2015-03-31 66 views
1

我有以下文件app.pyPython導入語句是否也自動導入相關性?

class Baz(): 
    def __init__(self, num): 
     self.a = num 
     print self.a 

def foo(num): 
    obj = Baz(num) 

第二個文件main.py

from app import foo 
foo(10) 

運行文件python main.py給出正確的輸出。

現在在第二個文件中,我只是導入函數而不是類,儘管成功執行我的函數也需要類。

導入函數時,Python會自動導入運行該函數所需的所有內容,還是會自動搜索當前目錄中的類?

回答

2

正如@DavidZ已經提到的那樣,當我們導入整個Python文件時就會被編譯。但是另一件特別的事情發生在函數體被解析時,函數知道它應該在本地作用域中查找哪些變量以及它應該在全局作用域中尋找哪些變量(以及有自由變量)。

>>> import dis 
>>> dis.dis(foo) 
    7   0 LOAD_GLOBAL    0 (Baz) 
       3 LOAD_FAST    0 (num) 
       6 CALL_FUNCTION   1 
       9 STORE_FAST    1 (obj) 
      12 LOAD_CONST    0 (None) 
      15 RETURN_VALUE 

所以,這裏的Baz必須從全局範圍提取。

但是當我們在另一個 文件中導入app.py時,如何識別這個全局範圍?

那麼,每個函數都有一個特殊的屬性__globals__附加到它包含其實際的全局命名空間。因此,這就是Baz來源:

>>> foo.__globals__['Baz'] 
<class __main__.Baz at 0x10f6e1c80> 

因此,應用程序的模塊字典和foo.__globals__指向同一個對象:

>>>sys.modules['app'].__dict__ is foo.__globals__ 
True 

由於此,即使你定義導入後在main.py命名Baz另一個變量foo它仍然會訪問實際的Baz

data-model page

__globals__ func_globals

的引用保存功能的全球 變量字典 - 其中功能 定義的模塊的全局命名空間。

+0

這是整潔。所以我不應該把不相關的代碼放在一個文件中,如果我的意圖是隻加載一個函數,因爲Python會一直編譯整個文件,對嗎? – 2015-03-31 11:25:22

+0

@KartikAnand Python只會將它編譯成一個'.pyc'文件,稍後導入只需從同一個'.pyc'文件中獲取字節碼,直到您再次更新'.py'文件。 – 2015-03-31 11:27:05

+0

因此,如果我沒有明確導入'Baz',我可以通過從函數附加的'__globals__'來實例化它嗎? – 2015-03-31 11:30:40

1

Python不會自動執行任何這些操作。

當您從模塊(在本例中爲app模塊)導入某些內容時,Python首先運行相應文件(app.py)中的所有代碼。您已寫入的文件app.py中的代碼做了兩兩件事:

  1. 定義類Baz
  2. 定義函數foo

當函數foo運行,巨蟒在尋找Bazfoo是其中的一部分,並且僅限於此。 (好吧,它也檢查函數foo中定義的局部變量,但是除了obj之外,您沒有任何其他變量。)具體而言,它會查找app.Baz。如果你改變你的main.py做同樣的搜索:

from app import foo 
foo(10) 
import app # same app that was already imported 
print app.Baz 

你會看到app.Baz是您在app.py定義的類。

如果您將Baz類的定義放在另一個文件中,並且您不導入該文件,Python將不會運行它。這表明Python確實不是自動導入依賴關係。具體而言,假設app.py包含

def foo(num): 
    obj = Baz(num) 

baz.py包含

class Baz(): 
    def __init__(self, num): 
     self.a = num 
     print self.a 

main.py不變。你會得到一個錯誤,因爲Python沒有運行代碼來定義類Baz

+0

我知道關於定義部分。當它運行文件時,它是否以某種形式在當前文件中存儲Class的定義部分? – 2015-03-31 11:19:22

+0

看我的編輯是否有助於澄清任何事 – 2015-03-31 11:25:33