регистрация Python __name__ и упаковка - PullRequest
0 голосов
/ 11 мая 2018

Официальная документация по регистрации Python гласит:

Имя может быть иерархическим значением, разделенным точкой, как foo.bar.baz (хотя это также может быть простопросто фу, например).Регистраторы, которые находятся ниже в иерархическом списке, являются потомками регистраторов, которые находятся выше в списке.Например, при наличии логгера с именем foo, логгеры с именами foo.bar, foo.bar.baz и foo.bam являются потомками foo.Иерархия имен регистраторов аналогична иерархии пакетов Python и идентична ей, если вы организуете свои регистраторы для каждого модуля с использованием рекомендуемой конструкции logging.getLogger (__name__).Это потому, что в модуле __name__ - это имя модуля в пространстве имен пакета Python.

Но я обнаружил, что последнее предложение не совсем верно.Значение __name__ зависит от того, как импортируется модуль.Это демонстрирует следующее:

Имеется два модуля foo и bar в пакете pkg:

Это foo :

def showFoosName():
    print __name__

и этоis bar :

from pkg import foo
if __name__ == '__main__':
    foo.showFoosName()

при запуске bar выдает

pkg.foo

Однако, если мы введем baz в пакет pkg, который просто импортирует fooкак foo, что допустимо, поскольку оба находятся в одном пакете:

import foo
if __name__ == '__main__':
    foo.showFoosName() 

при запуске baz выдается

foo

Теперь, возвращаясь к обсуждению и настройке ведения журнала, кажется, чтоРекомендация по регистрации в Python для именующих регистраторов с __name__ остается в силе, только если импорт в пакете кодируется с синтаксисом from pkg import bar.Это не то, что я ожидал.Я бы подумал, что значение __name__ не будет зависеть от того, как оно было импортировано.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Суть пакетов и модулей Python в том, что, как и все остальное в Python, они являются динамическими. __name__ каждого модуля зависит от того, где он находится относительно корневых путей Python (на sys.path). Таким образом, если у вас есть папка с именем pkg, даже если она содержит __init__.py, она на самом деле не является «пакетом», если она находится на sys.path напрямую. Если папка pkg находится в sys.path напрямую (например, потому что вы запустили там интерпретатор Python), то это не пакет, и любые файлы .py внутри нее являются модулями верхнего уровня, а не модулями внутри каких-либо пакет. Таким образом, если у вас есть foo.py внутри папки pkg, при запуске интерпретатора Python изнутри pkg, настоящее * официальное имя foo.py равно foo, а не pkg.foo .

Если папка, которая содержит pkg, не включена в sys.path, там равно без пакета pkg - from pkg import foo не будет работать с ImportError. И если оба pkg и папка, содержащая pkg, находятся на sys.path, то ваш путь Python искажен, и у вас есть два отдельных импортируемых модуля, pkg.foo и foo (с независимыми копиями всех их глобальных переменных). !).

Чтобы решить эту проблему, рекомендуется отделять исполняемые скрипты и импортируемые модули и пакеты друг от друга. Это позволяет вам поместить все ваши импортируемые модули и пакеты в общее место (как правило, под site-packages для вашей установки Python), и ваши исполняемые скрипты могут импортировать их, используя полное имя, независимо от того, где расположены скрипты (как правило, где-то вроде /usr/bin или /usr/local/bin).

0 голосов
/ 11 мая 2018

Это признак нарушения вашего пути импорта. На вашем пути есть и pkg, и содержащий его каталог, в результате чего foo.py соответствует двум отдельным модулям , foo и pkg.foo.

Вероятно, каталог, содержащий pkg, находится на вашем пути импорта, но вы запускаете bar.py и baz.py непосредственно по имени файла, в результате чего сам pkg также находится на пути. Запуск

python -m pkg.bar

или

python -m pkg.baz

должен препятствовать добавлению pkg к пути.

Это только один возможный способ, которым ваш путь импорта мог быть испорчен. Мы не можем действительно сказать. Чтение в системе импорта Python должно помочь; вот один хороший ресурс .

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