В чем разница?
Разница заключается в файле __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
.Убедитесь, что вы не загрязняете пространство имен на уровне модуля.