Я только что прочитал статью, которая, предположительно, представила меня новому понятию: До сих пор я был уверен что пакеты Python (т.е. каталоги с __init__.py
файл), ведут себя точно то же как пакеты Java, которое является - небольшие пространства имен, чтобы помочь расположить код (минус обзор "пакета" Java). Но, согласно этой ссылке: Короткое Отклонение В Многофайловые Модули, если я поместил все свои файлы в тот же "пакет":
весь набор файлов представлен другому коду Python как единственный модуль — как будто все функции и классы были в единственном .py
Таким образом, теперь я думал, что мое целое понимание вещи "пакета" Python было неправильным. Кроме того - это - полностью не пакет, скорее "многофайловый модуль", поскольку автор обращается к нему.
Так, от того, что я понял, неважно, к тому, сколько файлов я делю свой funcs и классы в пакете с внешней стороны, что пакет должен появиться, как будто я взял весь код из всех файлов в пакете и поместил его в один большой файл с тем же именем как пакет вместо этого, т.е. как один модуль.
например, если у меня есть следующая файловая структура:
/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 "", line 1, in
AttributeError: 'module' object has no attribute 'bark'
Что я пропускаю здесь? Я вижу исключением, что "животных" действительно рассматривают как модуль, но кажется, что я все еще должен явно заявить animals.dog.bark
, т.е. внутренняя файловая структура пакета не абстрагирована с внешней стороны.
Я упускаю суть автора или просто не реализую ее правильно?
=== РЕДАКТИРОВАНИЕ ===
Только для проверки никто не пропускает эту строку в кавычке:
как будто все функции и классы были в единственном .py
независимо от того, как к на самом деле получают доступ к этому funcs и классам, вышеупомянутая кавычка явно указывает что, если у Вас есть func1 в файле a и func2 в файле b, независимо от которого путь будет они быть доступным от, если мы обозначим этот путь как X затем, согласно вышеупомянутой кавычке, обоим X.func1
и X.func2
должен работать.
Автор слишком упрощает вещи. Он говорит, что все в разделе animal
можно рассматривать как находящееся в одном модуле, хотя на самом деле имена в animal.dog
будут находиться в своем собственном пространстве имен.
Возможно, дело просто в том, что пакет - это просто конкретный тип модуля.
/base
/animals
/__init__.py
/dog.py
Это просто означает, что все, что вы определяете или импортируете в __ init __. Py
, будет видно внутри модуля animals
.
Итак, animals
- это модуль (то есть пакет), а animals.dog
- это подмодуль animals
, но не пакет .
Это также означает, что если у вас есть простой модуль animals
, вы можете заменить его пакетом с тем же именем в следующей версии и расположить так, чтобы ваши пользователи не заметили разницы.
Если вы хотите, чтобы все классы из подмодулей пакета составляли один видимый для пользователя модуль (пространство имен), вы должны определить такую строку для каждого подмодуля в __ init __. Py
:
from animals.dog import *
] Я не могу объяснить это хорошо, но, возможно, следующий код поможет. Если я оставлю вашу первую структуру файлов как есть, а вторую изменю так, чтобы в файле animals.py было следующее:
class Dog:
def bark(self): pass
dog=Dog()
Тогда в обоих случаях
from base import animals
animals.dog.bark()
будет работать.