簡體   English   中英

Python導入模塊:文件和目錄之間有什么區別?

[英]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沒有alicebob 而且,除了

from foo import alice, bob

如果我想使用foo模塊的alicebob ,因為該文件夾中可能有很多文件?

編輯

我的問題不是關於內置函數dir給出的奇怪結果。 如果我在main.py中這樣做

import foo
foo.alice

將會發生異常: AttributeError:'模塊'對象沒有屬性'alice'

foo似乎沒有alice 我想我在理解如何將目錄作為模塊導入時遇到一些問題。

您在dir(bar)中看到的alicebob是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文件的目的是使其成為一個包。 該文件提供了一個位置,用於指定程序包的面向公眾的界面。 有兩種方法可以使alicebob進入foo

1.使用__all__

__init__.py文件中,您可以顯式聲明要使用__all__公開的模塊。 以下內容將揭露alicebob

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

2.直接導入alicebob

另外,在__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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM