2016-09-23 36 views
1

我有一個函數,它將遞歸地執行另一個函數,我想共享該函數的所有執行變量。Python共享全局變量僅適用於函數內部的功能

類似的東西:

def testglobal(): 
    x = 0 
    def incx(): 
    global x 
    x += 2 
    incx() 
    return x 
testglobal() # should return 2 

不過,我收到提示NameError: name 'x' is not defined

有哈克解決方案,使列表,並使用該列表的第一個值作爲x。但是這太難看了。

那麼如何分享xincx函數?或者我應該使用完全不同的方法?

+1

在Python 3有一個新的關鍵字,[非局部](https://docs.python.org/3/ reference/simple_stmts.html#the-nonlocal-statement),這正是你想要的。請記住,這是一個閉包,所以你可以在不改變的情況下訪問'x',但是在'incx'內部賦值(例如'x = 1')會使'x'局部爲'incx',因此不會引用相同的變量。 'nonlocal'實現了這一點。 – alexpeits

回答

1

你想使用nonlocal聲明訪問x,這不是全局的,而是本地的testglobal

def testglobal(): 
    x = 0 
    def incx(): 
    nonlocal x 
    x += 2 
    incx() 
    return x 
assert 2 == testglobal() 

你可以來在Python 2這樣做的最接近的是一個可變值,類似的說法砍你在你的問題中提到更換x

def testglobal(): 
    x = [0] 
    def incx(): 
    x[0] += 2 
    incx() 
    return x[0] 
assert 2 == testglobal() 

下面是一個使用函數屬性而不是列表的例子,您可能會發現更具吸引力的替代方法。

def testglobal(): 
    def incx(): 
    incx.x += 2 
    incx.x = 0 
    incx() 
    return inc.x 
assert 2 == testglobal() 
+0

但是這只是在python 3中引入的,對吧?但是這個概念看起來很常見,如何在python 2中做同樣的事情? –

+0

你不能,缺乏你的可變參數破解。閉包僅捕獲一個變量的值以供閱讀;你不能非價值地修改這個值(這就是爲什麼Python 3添加了'nonlocal'關鍵字)。 – chepner

3

這將除非你還在使用Python 2.x的工作:

def testglobal(): 
    x = 0 
    def incx(): 
    nonlocal x 
    x += 2 
    incx() 
    return x 

testglobal() # should return 2 

可能一個清潔的解決方案,雖然是定義一個類來存儲方法調用之間的狀態。

2

使用nonlocal語句,所以incx將使用x變量從testglobal

def testglobal(): 
    x = 0 
    def incx(): 
     nonlocal x 
     x += 2 
    incx() 
    return x 

testglobal() 
相關問題