в python есть ли способ найти модуль, содержащий переменную или другой объект, из самого объекта?

#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'>