Пакеты Python (многофайловые модули) ведут себя точно как один большой модуль?

Я только что прочитал статью, которая, предположительно, представила меня новому понятию: До сих пор я был уверен что пакеты 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 должен работать.

10
задан mplungjan 20 October 2011 в 20:08
поделиться

3 ответа

Автор слишком упрощает вещи. Он говорит, что все в разделе animal можно рассматривать как находящееся в одном модуле, хотя на самом деле имена в animal.dog будут находиться в своем собственном пространстве имен.

4
ответ дан 4 December 2019 в 01:56
поделиться

Возможно, дело просто в том, что пакет - это просто конкретный тип модуля.

/base
    /animals
        /__init__.py
        /dog.py

Это просто означает, что все, что вы определяете или импортируете в __ init __. Py , будет видно внутри модуля animals .

Итак, animals - это модуль (то есть пакет), а animals.dog - это подмодуль animals , но не пакет .

Это также означает, что если у вас есть простой модуль animals , вы можете заменить его пакетом с тем же именем в следующей версии и расположить так, чтобы ваши пользователи не заметили разницы.

Если вы хотите, чтобы все классы из подмодулей пакета составляли один видимый для пользователя модуль (пространство имен), вы должны определить такую ​​строку для каждого подмодуля в __ init __. Py :

from animals.dog import *
]
4
ответ дан 4 December 2019 в 01:56
поделиться

Я не могу объяснить это хорошо, но, возможно, следующий код поможет. Если я оставлю вашу первую структуру файлов как есть, а вторую изменю так, чтобы в файле animals.py было следующее:

class Dog:
    def bark(self): pass
dog=Dog()

Тогда в обоих случаях

from base import animals
animals.dog.bark()

будет работать.

0
ответ дан 4 December 2019 в 01:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: