2016-02-26 66 views
3

下面是代碼:這個函數如何找到另一個變量的值?

def caller(callee): 
    callee() 

def wrapper(): 

    def a(): 
     print v0 

    for i in range(5): 
     v0 = i*i 
     caller(a) 

wrapper() 

上面的代碼輸出:

0 
1 
4 
9 
16 

但我不知道如何解決a變量v0。我無法找到有關此語言功能的相關python文檔。

+0

下面是一些閱讀材料:https:// realpython。com/blog/python/inner-functions-what-are-they-good-for/ – idjaw

+0

[在創建它們的函數中使用全局變量]的可能副本(// stackoverflow.com/questions/423379/ using-global-variables-in-a-function-other-that-one-that-c​​reated-them) – Zizouz212

+2

@ Zizouz212此代碼中沒有全局變量(除函數'wrapper'和'caller'外) 。具體而言,'v0'不是全局的。 –

回答

2

函數中定義的變量範圍包括其中的所有嵌套函數。因此,在內可以訪問wrapper()中定義的變量,因爲此函數嵌套在其中。這被稱爲詞法範圍,它通常用於創建閉包。

這Python的Resolution of Names文檔中進行了說明:

範圍限定了塊內的名稱的可見性。如果在塊中定義了局部變量,則其作用域包含該塊。如果定義發生在功能塊中,則範圍擴展到定義塊中包含的任何塊,除非包含的塊爲該名稱引入了不同的綁定。

0

請記住,函數中的所有代碼都不會運行,直到函數被調用。在調用a()時,v0已在外部範圍內定義,因此它可以識別變量並對其進行評估。

1

函數a根據調用wrapper定義。當調用給定實例a時,它會在其定義的上下文內查找v0,這是對wrapper進行定義的具體調用。在調用a時,v0已被定義在wrapper內,並且a使用v0的定義。

在此示例中,調用wrapper(定義a)在調用a時仍處於活動狀態,但不一定如此。換句話說,wrapper可能會返回,並從該上下文中引用a仍然可以調用。在這種情況下,這將是一個封閉。但是在這個例子中不會發生這種情況。

下面是不使用閉包的例子:

def foo(x): 
    def bar(): 
     return x 
    return bar 

f1 = foo(123) 
f2 = foo(456) 

print(f1()) 
print(f2()) 

輸出是:

123 
456 

foo被調用,它返回它在上下文評估xbar的實例中foo被稱爲。在第一個調用x是123,第二個調用456。即使對foo的調用返回後,這些綁定仍然存在。

相關問題