2012-11-03 56 views
0

這裏是一個示例代碼變化值的局部空間內通過一個函數:在局部空間

def foo(): 
    def bar(): 
     foobar = 'foobaz' 

    foobar = 'foobar' 
    print foobar 
    bar() 
    print foobar 

foo() 

我想通過功能bar改變可變foobarfoo。上面的代碼將不起作用,因爲bar中的foobar與中的foobar位於單獨的命名空間中。一個簡單的解決方法將使全球foobarfoobar都可以訪問它,但我希望會有更簡單的解決方法。

+0

又有什麼用呢?它可以在py3中用'nonlocal'完成,但是呃...仍然是 –

+0

@JonClements我需要這樣做。 –

+0

@JonClements一個例子:http://pastebin.com/2HjFSngE - 在給定值上分割一個迭代器。 –

回答

2

Python的3.x中,你可以使用nonlocal和蟒蛇2.x的嘗試使用功能屬性:

def foo(): 
    def bar(): 
     foo.foobar = 'foobaz' #change the function attribute 

    foo.foobar = 'foobar'  #declare as function attribute 
    print foo.foobar 
    bar() 
    print foo.foobar 
foo() 

輸出:

foobar 
foobaz 
+1

+1,函數屬性在2.x中是一個很好的方法 –

2

您正在查找關鍵字nonlocal,它存在於3.x.

def f(): 
    x = None 
    def g(): 
     nonlocal x 
     x = 1 

如果你是停留在2.x中,您可以通過具有列表或類似的可變數據容器和訪問,作爲一個變通做到這一點。

def f(): 
    x = [None] 
    def g(): 
     x[0] = 1 

這可以作爲變量落入範圍,但不會泄漏出範圍。使用可變對象時,我們可以在範圍內更改它們,並將這些更改傳播出去。

1

python 2.7中不可能。在Python 3:

def foo(): 
    def bar(): 
     nonlocal foobar 
     foobar = 'foobaz' 

    foobar = 'foobar' 
    print foobar 
    bar() 
    print foobar 

foo() 

在2.x中,你可以這樣做:

def foo(): 
    foobar = [] 
    def bar(): 
     foobar[0] = 'foobaz' 

    foobar[0] = 'foobar' 
    print foobar[0] 
    bar() 
    print foobar[0] 

foo() 
+0

@JonClements:Whoops – Eric

0
def foo(): 
    def bar(): 
     foobar = 'foobaz' 
     return foobar 

    foobar = 'foobar' 
    print foobar 
    foobar = bar() 
    print foobar 

foo() 
+0

你假設''bar()''將被該函數調用,但情況並非如此。 –

+0

但按照給定示例代碼 –

+0

在foo方法中調用它可以很容易地完成這個例子。有關反案例的示例,請參閱http://pastebin.com/2HjFSngE。 –

0

即使功能已經在Python一流的對象,你可以創建自己的「仿函數」或函數對象是這樣的:這個

class Foo(object): 
    def bar(self): 
     self.foobar = 'foobaz' 

    def __call__(self): 
     self.foobar = 'foobar' 
     print self.foobar 
     self.bar() 
     print self.foobar 

foo = Foo() 
foo()