2013-01-10 16 views
1

這是我在pythion的導入中無法想象的東西。 假設我有一個模塊'a',用'import b'導入模塊'b' 然後,有一個模塊'c'導入模塊'a'。 從'c'中可以使用模塊'b'的名稱嗎?Python中的封閉式導入工作原理

我檢查過它實際上取決於你如何在模塊'c'中導入模塊'a'。 如果您輸入'','b'中的名字將不會在'c'中提供。 但是,如果您從'導入*'執行操作,那麼它們將可用。 有人可以澄清區別?

回答

4

如果您想通過這些命令實際執行的操作,它非常簡單。

a.py:

import b 
foo = 0 

b.py:

bar = 1 

c.py:

import a 

c,你不能只是說foo,你有說a.foo。對於a中的每個名稱(變量,函數,類,甚至模塊)都是如此。這包括b

所以,你不能說bara.bar,但你可以說a.b.bar。現在

,如果你改變這樣的:

a.py:

from b import * 
foo = 0 

b.py:

bar = 1 

c.py:

from a import * 

from b import *做的是拿e在b的名字空間中有一些東西,並把它放到a的名字空間中,所以你可以直接從a中說bar。然後,當你做from a import *時,它將a的名稱空間中的所有內容都放入c中,所以就像foo一樣,你也可以這樣做bar

這就是爲什麼你通常不想在除頂級腳本之外的任何地方執行from b import *的原因 - 因爲你的命名空間將所有的命名空間合併在一起。

這也是爲什麼你可以限制哪些內容與__all__拾起*

a.py:

from b import * 
__all__ = ['foo'] 
foo = 0 

灣潘岳:

bar = 1 

c.py:

from a import * 

現在,從c,你可以做c.foo,但不c.bar

因此,a可以做from b import *來實現自己的功能,而不會暴露所有的b的內部給它的用戶。

+0

+1,因爲我不知道'__all__'。 –

+0

「所以,你不能說酒吧或a.bar,但你可以說a.b.bar」我得到'對象a沒有屬性b'當試圖這樣做。 – spoonboy

+0

@spoonboy:是的,我可以說'a.b.bar',我不能說它快10倍。 (儘管我剛剛意識到它非常接近我自己的用戶名的開始......) – abarnert

3

import語句會導致執行一個模塊,並且所有變量在執行模塊的模塊的命名空間中保持爲。也就是說,如果你import a,那麼所有的a的變量將在a.[variable]之下。關鍵字from的行爲稍有不同:它將變量放入當前名稱空間。例如,from a import foo將變量foo放入當前名稱空間中。 from a import *將所有變量從a導入當前名稱空間。關鍵字as允許您在導入變量時重命名變量;因此from a import foo as bar允許您訪問a.foo,但您必須將其稱爲bar; import a.foo as foo相當於from a import foo

1

更具體的例子比上面:

a.py

import b 
bar = 'bar' 

b.py

foo = 'foo' 

c.py

import a 


try: 
    print(b.foo) 
except: 
    print('No `b` in current namespace') 

try: 
    print(a.bar) 
except: 
    print('No `a` in current namespace') 

try: 
    print(a.b.foo) 
except: 
    print('No `a` or `a.b` in current namespace') 

本應打印(按順序):

No `b` in current namespace 
bar 
foo 

換句話說,B可通過而僅通過訪問a的命名空間