Модули импорта Python: что отличается между файлом и каталогом? - PullRequest
2 голосов
/ 10 февраля 2012

У меня есть следующие файлы и каталоги в корневом каталоге моего проекта

main.py
bar.py
foo \
    __init__.py
    alice.py
    bob.py

файлы в каталоге foo являются пустыми файлами, а содержимое bar.py равно

alice = None
bob = None

и main.py is

import foo
import bar
print 'foo:', dir(foo)
print 'bar:', dir(bar)

При выполнении python main.py вывод

foo: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
bar: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'alice', 'bob']

Почему в foo нет alice или bob? И что я должен делать, кроме

from foo import alice, bob

если я хочу использовать alice и bob модуля foo, так как в этой папке может быть много файлов?

EDIT

Мой вопрос не о встроенной функции dir, которая дает странный результат. Если я сделаю это в main.py

import foo
foo.alice

Произойдет исключение: AttributeError: у объекта 'module' нет атрибута 'alice'

Кажется, нет alice в foo? Мне кажется, у меня возникли проблемы с пониманием того, как импортировать каталог как модуль.

Ответы [ 4 ]

3 голосов
/ 10 февраля 2012

alice и bob, которые вы видите в dir(bar), являются переменными из bar.py

dir(foo) doesn't mean directory.

dir : If called without an argument, return the names in the current scope.
Else, return an alphabetized list of names comprising (some of) the attributes
of the given object, and of attributes reachable from it.
If the object supplies a method named __dir__, it will be used; otherwise
the default dir() logic is used and returns
. for a module object: the module's attributes.
. for a class object:  its attributes, and recursively the attributes
    of its bases.
. for any other object: its attributes, its class's attributes, and
    recursively the attributes of its class's base classes.

В main.py напишите:

import foo.alice
import foo.bob

это должно дать тебе Алису и Боба

1 голос
/ 10 февраля 2012

В основном все сводится к разнице между модулем и пакетом.Начиная с документы :

Пакеты являются способом структурирования пространства имен модуля Python с помощью «точечных имен модулей».Например, имя модуля AB обозначает подмодуль с именем B в пакете с именем A. Точно так же, как использование модулей избавляет авторов различных модулей от необходимости беспокоиться о именах глобальных переменных друг друга, использование названий модулей с точками сохраняет авторовмультимодульных пакетов, таких как NumPy или Python Imaging Library от необходимости беспокоиться об именах модулей друг друга.

Цель файла __init__.py в каталоге - сделать его пакетом.Этот файл предоставляет место, указывающее открытый интерфейс для пакета.Есть два способа получить alice и bob в foo:

1.Используйте __all__

В своем файле __init__.py вы можете явно объявить, какие модули вы хотите выставить с помощью __all__.Следующее выставит alice и bob.

`__all__` = ['alice', bob']

2.импорт alice и bob напрямую

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

Он также будет импортировать эти модули во время инициализации, поэтому при каждомвы импортируете что-нибудь в foo, они также будут импортированы.

0 голосов
/ 10 февраля 2012

Python не импортирует автоматически модули пакетов. Он хочет, чтобы вы явно указали имя где-либо, либо с помощью from foo import alice в main.py, либо с помощью foo/__init__.py import alice, либо с помощью foo/__init__.py включив список __all__.

Мой ответ на другой вопрос SO более подробно расскажет, почему это так.

0 голосов
/ 10 февраля 2012
# in foo/__init__.py:
__all__ = ['alice', 'bob']

позволит вам сделать это:

# in main.py
from foo import *

и импортировать только те модули, которые были явно указаны в all

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...