[英]Python import modules: what is different between a file and a directory?
我的項目根目錄中有以下文件和目錄
main.py
bar.py
foo \
__init__.py
alice.py
bob.py
foo目錄中的文件都是空文件,而bar.py的內容為
alice = None
bob = None
並且main.py是
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
如果我想使用foo
模塊的alice
和bob
,因為該文件夾中可能有很多文件?
編輯
我的問題不是關於內置函數dir
給出的奇怪結果。 如果我在main.py中這樣做
import foo
foo.alice
將會發生異常: AttributeError:'模塊'對象沒有屬性'alice'
在foo
似乎沒有alice
? 我想我在理解如何將目錄作為模塊導入時遇到一些問題。
您在dir(bar)
中看到的alice
和bob
是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
這應該給你愛麗絲和鮑勃
基本上可以歸結為模塊和包之間的區別。 從文檔 :
包是一種通過使用“點分模塊名稱”來構造Python模塊名稱空間的方法。 例如,模塊名稱AB在名為A的包中指定了一個名為B的子模塊。就像使用模塊可以節省不同模塊的作者不必擔心彼此的全局變量名稱一樣,使用帶點划線的模塊名稱也可以節省作者諸如NumPy或Python Imaging Library之類的多模塊軟件包,而不必擔心彼此的模塊名稱。
目錄中__init__.py
文件的目的是使其成為一個包。 該文件提供了一個位置,用於指定程序包的面向公眾的界面。 有兩種方法可以使alice
和bob
進入foo
:
__all__
在__init__.py
文件中,您可以顯式聲明要使用__all__
公開的模塊。 以下內容將揭露alice
和bob
。
`__all__` = ['alice', bob']
alice
和bob
另外,在__init__.py
文件中導入模塊也將公開這些模塊。
它還將在初始化時導入這些模塊,因此,每當您在foo中導入任何內容時,它們也會被導入。
# in foo/__init__.py:
__all__ = ['alice', 'bob']
將允許您執行以下操作:
# in main.py
from foo import *
並僅導入所有顯式調用的模塊
Python不會自動導入軟件包模塊。 它希望您通過在main.py
使用from foo import alice
或通過foo/__init__.py
import alice
或通過foo/__init__.py
包括__all__
列表來明確指定名稱。
我對另一個SO問題的回答將進一步詳細說明原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.