#python #namespaces #definition
#python #пространства имен #определение
Вопрос:
В качестве примера, скажем, у меня определена переменная, где может быть несколько
from __ import *
from ____ import *
и т.д.
Есть ли способ выяснить, где определена одна из переменных в пространстве имен?
Редактировать
Спасибо, но я уже понимаю, что import * часто считается плохой формой. Хотя это был не вопрос, и в любом случае я его не писал. Было бы просто неплохо иметь способ найти, откуда взялась переменная.
Комментарии:
1. Именно поэтому вам не следует использовать импорт подстановочных знаков.
Ответ №1:
Вот почему использование from __ import *
в python в большинстве случаев считается дурным тоном. Либо используйте from __ import myFunc
, либо import __ as myLib
нет . Тогда, когда вам что-то нужно myLib
, это не перекрывает что-то еще.
Для получения помощи в поиске объектов в текущем пространстве имен ознакомьтесь с библиотекой pprint, встроенным каталогом, встроенными локальными и встроенными глобальными.
Ответ №2:
Нет, имена, определенные с помощью from blah import *
, не сохраняют никакой информации о том, откуда они пришли. Значения могут иметь ключ, например, у классов есть __module__
атрибут, но они могли быть определены в одном модуле, а затем импортированы из другого, поэтому вы не можете рассчитывать на то, что они будут ожидаемыми значениями.
Ответ №3:
Например, сортировка:
>>> from zope.interface.common.idatetime import *
>>> print IDate.__module__
'zope.interface.common.idatetime'
>>> print Attribute.__module__
'zope.interface.interface'
Модуль the Attribute
может показаться удивительным, поскольку вы импортировали его не оттуда, но именно там Attribute
был определен тип. Глядя на zope/interface/common/idatetype.py
, мы видим:
from zope.interface import Interface, Attribute
что объясняет значение __module__
. Вы также столкнетесь с проблемами с экземплярами типов, импортированных из других модулей. Предположим, что вы создаете Attribute
экземпляр с именем att
:
>>> att = Attribute('foo')
>>> print att.__module__
'zope.interface.interface'
Опять же, вы узнаете, откуда взялся тип, но не где была определена переменная.
Вполне возможно, что самая большая причина не использовать импорт подстановочных знаков заключается в том, что вы не знаете, что получаете, и они загрязняют ваше пространство имен и, возможно, загромождают другие типы / переменные.
>>> class Attribute(object):
... foo = 9
...
>>> print Attribute.foo
9
>>> from zope.interface.common.idatetime import *
>>> print Attribute.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'Attribute' has no attribute 'foo'
Даже если сегодня import *
работает без столкновений, нет гарантии, что этого не произойдет при будущих обновлениях импортируемого пакета.
Ответ №4:
Если вы вызовете сам метод в интерпретаторе, он сообщит вам, что это за родительские модули.
Например:
>>> from collections import *
>>> deque
<type 'collections.deque'>