2016-09-23 59 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()