Как извлечь и затем обратиться к переменным, определенным в модуле Python? - PullRequest
2 голосов
/ 14 сентября 2009

Я пытаюсь создать простой скрипт проверки среды для среды тестирования моей фирмы. Моя цель - иметь возможность пропинговать каждый из хостов, определенных для данного экземпляра тестовой среды. Хосты определены в файле следующим образом:

#!/usr/bin/env python
host_ip = '192.168.100.10'
router_ip = '192.168.100.254'
fs_ip = '192.168.200.10'

Как я могу получить все эти значения итеративным способом (т. Е. Мне нужно просмотреть и пропинговать каждый IP-адрес)?

Я посмотрел на local () и vars (), но пытаюсь сделать что-то вроде этого:

for key, value in vars():
    print key, value

генерирует эту ошибку:

ValueError: too many values to unpack

Мне удалось извлечь имена всех переменных, проверив dir(local_variables) для значений, которые не содержат строку '__', но затем у меня есть список строк, и я не могу понять, как получить из строки значение переменной с тем же именем.

Ответы [ 5 ]

8 голосов
/ 14 сентября 2009

Во-первых, я настоятельно рекомендую не делать это таким образом. Вместо этого выполните:

hosts = {
    "host_ip": '192.168.100.10',
    "router_ip": '192.168.100.254',
    "fs_ip": '192.168.200.10',
}

Затем вы можете просто импортировать модуль и ссылаться на него как обычно - это дает обычный, стандартный способ доступа к этим данным из любого кода Python:

import config
for host, ip in config.hosts.iteritems():
    ...

Если вы обращаетесь к переменным напрямую, вы получите кучу вещей, которые вам не нужны: встроенные (__builtins__, __package__ и т. Д.); все, что было импортировано при настройке других переменных и т. д.

Вы также захотите убедиться, что контекст, в котором вы работаете, отличается от того, в котором вы перебираете переменные, или вы будете создавать новые переменные в locals () (или vars () или globals ()), пока вы итерируете его, и вы получите "RuntimeError: dictionary changed size during iteration".

2 голосов
/ 14 сентября 2009

Вам нужно сделать vars (). Iteritems (). (или .items ())

Зацикливание словаря, например, vars (), извлечет только ключи в словаре.

Пример.

>>> for key in vars(): print key
...
__builtins__
__name__
__doc__
key
__package__


>>> for key, value in vars().items(): print key, value
...
__builtins__ <module '__builtin__' (built-in)>
value None
__package__ None
key __doc__
__name__ __main__
__doc__ None
1 голос
/ 14 сентября 2009

Гленн Мейнард делает хорошую мысль, используя словарь проще и более стандартно. Тем не менее, вот несколько приемов, которые я иногда использовал:

В файле hosts.py:

#!/usr/bin/env python
host_ip = '192.168.100.10'
router_ip = '192.168.100.254'
fs_ip = '192.168.200.10'

и в другом файле:

hosts_dict = {}
execfile('hosts.py', hosts_dict)

или

import hosts
hosts_dict = hosts.__dict__

Но, опять же, оба довольно хакерские.

0 голосов
/ 14 сентября 2009

Если это действительно все, что содержится в вашем импортированном файле, вы также можете прочитать его как просто текстовый файл, а затем проанализировать строки ввода, используя основные строковые методы.

iplistfile = open("iplist.py")

host_addr_map = {}
for line in iplistfile:
    if not line or line[0] == '#':
        continue

    host, ipaddr = map(str.strip, line.split('='))
    host_addr_map[host] = ipaddr

iplistfile.close()

Теперь у вас есть набор ваших IP-адресов, адресуемых по имени хоста. Чтобы получить их все, просто используйте базовые методы в стиле dict:

for hostname in host_addr_map:
    print hostname, host_addr_map[hostname]

print host_addr_map.keys()

Это также имеет то преимущество, что устраняет любой соблазн, который может понадобиться любому введенному в заблуждение человеку, чтобы добавить более сложную логику Python к тому, что вы считали просто файлом конфигурации.

0 голосов
/ 14 сентября 2009

Вот хак, которым я пользуюсь все время. Вы очень близко подошли к моменту, когда вы вернули список имен строк, но вы должны использовать функцию eval (), чтобы вернуть фактический объект с именем, представленным строкой:

hosts = [eval('modulename.' + x) for x in dir(local_variables) if '_ip' in x]

Если я не ошибаюсь, этот метод также не имеет тех же недостатков, что и localals () и vars (), которые объяснил Глен Мейнард.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...