2016-05-19 7 views
3

Я пытаюсь понять правила теневого копирования пакетов и модулей в python и наткнулся на случай, когда я не понимаю, почему результаты, которые я вижу, имеют какой-то смысл. Это происходит из-за случаи питона 2 (с from future import absolute_imports) и питоном 3.python: from x import y changes previous result result

Предполагая, что у меня есть следующая структура папок:

├── mypackage 
│   ├── argparse.py 
│   └── __init__.py 
└── script.py 

mypackage мой пользовательский верхний уровень пакет, в котором у меня есть модуль затенения стандарта argparse модуль. Внутри моего сценария я выполнить следующий код:

import argparse 
print(argparse) 
from mypackage.argparse import foo 
print(argparse) 

Результаты являются те, которые я планирующим:

<module 'argparse' from '/usr/lib/python3.5/argparse.py'> 
<module 'argparse' from '/usr/lib/python3.5/argparse.py'> 

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

сценарий:

from mypackage import main 
main() 

__init__.py:

import argparse 
print(argparse) 
from mypackage.argparse import foo 
print(argparse) 

def main(): 
    pass 

В результате я вижу:

<module 'argparse' from '/usr/lib/python3.5/argparse.py'> 
<module 'mypackage.argparse' from '/tmp/test/src/mypackage/argparse.py'> 

Почему в данном случае (а не в другой) from X import Y оператор переопределения предыдущего глобального импорта argparse к локальному модуль?

ответ

1

Рассмотрите, как вы получаете доступ к подмодулям, вы должны написать mypackage.argparse для доступа к подмодулю mypackage.

Теперь рассмотрим, как работает поиск атрибутов для модулей, он ищет атрибут в глобальном пространстве имен модулей.

Объединяя эти два элемента, единственный способ получить доступ к подмодулям - это добавить их в глобальное пространство имен пакетов, это намеченное поведение.

+0

Это как-то документировано где-то? У меня такое чувство, что 50% преимуществ, получаемых при абсолютном импорте, бесполезны. – languitar

+0

[документация по пакетам] (https://docs.python.org/3/tutorial/modules.html#packages) серьезно отсутствует в объяснении того, как во многих отношениях «__init __. :/ –

+0

Хорошо, спасибо. Таким образом, у меня нет никаких шансов справиться с этим, кроме как организовать мой импорт необычным способом, чтобы гарантировать, что argparse импортируется после утверждения X ..... – languitar