Python импортирует разницу - PullRequest
0 голосов
/ 30 мая 2018

В Python это выглядит как пользовательские классы, которые должны быть полностью классифицированы при импорте

Например,

from analytics.npv_differences import NpvDifferences

analytics
----npv_differences.py (содержиткласс NpvDifferences)

, когда следующее не будет работать:

from analytics import NpvDifferences

Однако для панд обе следующие работы

from pandas import DataFrame
from pandas.core.frame import DataFrame

почему разница?

1 Ответ

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

В чем разница?

Разница заключается в файле __init__.py.

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

__init__.py содержит код, который запускается при импорте пакета.
Включает:

  • import module
  • import module.submodule
  • from module import something
  • from module.submodule import something

Во всех этих случаях выполняется module/__init__.py.Вы можете проверить это, добавив в файл вызов print() и наблюдая вывод во время импорта.

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

Как сделать то же самое?

Если вы создаете файл __init__.py в своем каталоге analyticsи импортируйте класс туда, вы сможете использовать короткий импорт, как в pandas.

Ваш analytics/__init__.py файл должен содержать что-то вроде этого:

from analytics.npv_differences import NpvDifferences

The analytics часть импорта может быть опущена, превращая ее в относительный импорт .Если вы поместите это в ваш __init__.py, вы получите тот же результат:

from .npv_differences import NpvDifferences

Относительный импорт лучше в том смысле, что если вам случится переименовать ваш пакет во что-то другое, ваш импорт выиграет 't break.

Почему это работает?

Причина, по которой импорт внутри __init__.py допускает короткий импорт, заключается в том, что любая переменная, определенная в __init__.py, доступна на уровне модуля .

Например, если module/__init__.py содержит следующий код:

from .submodule import SomeClass  # this defines a `SomeClass` variable
__doc__ = '''This behaviour is commonly used to define 
             module-level documentation, available with 
             a call `help(module)`.'''
config_var = 1337

, то становится возможным следующее:

import module
help(module)  # will output the content of the __doc__ variable
module.SomeClass()  # create an instance of module.submodule.SomeClass
print(module.config_var)  # prints 1337

Именно поэтому в pandas __init__.py любые ненужные переменные тщательно удаляются с помощью del.Убедитесь, что вы не загрязняете пространство имен на уровне модуля.

...