Я только что прочитал статью, которая предположительно познакомила меня с новой концепцией: до сих пор я был уверен, что пакеты python (то есть каталоги с файлом __init__.py
) ведут себя точно так же, как пакеты java, то есть - небольшие пространства имен, помогающие упорядочить код (минус область видимости "пакета" java). Но, согласно этой ссылке: A Краткий экскурс в многофайловые модули, если я помещу все свои файлы в один «пакет»:
вся коллекция файлов представлена другому коду Python как единый модуль - как если бы все функции и классы находились в одном .py
Итак, теперь я подумал, что все мое понимание «пакета» Python было неправильным. Более того - это совсем не пакет, а «многофайловый модуль», как его называет автор.
Итак, насколько я понял, независимо от того, на сколько файлов я делю свои функции и классы внутри пакета, снаружи этот пакет должен выглядеть так, как если бы я взял весь код из всех файлов внутри пакета и поместил его в один большой файл с тем же именем, что и пакет, то есть как один модуль.
например, если у меня следующая файловая структура:
/base
/animals
/__init__.py
/dog.py
и в dog.py:
def bark():
print "woof"
он должен быть таким же, как и наличие:
/base
/animals.py
и в animals.py:
def bark():
print 'woof'
таким образом, следующий фрагмент кода должен нормально работать в обоих случаях:
from base import animals
animals.bark()
Это, конечно, дает в первом случае:
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'module' object has no attribute 'bark'
Что мне здесь не хватает? Я вижу за исключением того, что «животные» действительно рассматриваются как модуль, но, похоже, мне все еще нужно явно указывать animals.dog.bark
, т.е. внутренняя файловая структура пакета не абстрагируется извне.
Я упускаю точку зрения автора или просто неправильно ее реализую?
=== РЕДАКТИРОВАТЬ ===
Просто чтобы убедиться, что никто не пропустил эту строчку в цитате:
как если бы все функции и классы находились в одном .py
независимо от того, как на самом деле получить доступ к этим функциям и классам, в приведенной выше цитате явно указано, что если у вас есть func1 в файле a и func2 в файле b, независимо от того, по какому пути они будут доступны, если мы обозначим этот путь как X, тогда, согласно вышеупомянутой цитате должны работать и X.func1
, и X.func2
.