Python仅为函数内部的函数共享全局变量

Python仅为函数内部的函数共享全局变量,python,scope,global-variables,python-3.5,Python,Scope,Global Variables,Python 3.5,我有一个递归执行另一个函数的函数,我想为该函数的所有执行共享变量 诸如此类: def testglobal(): x = 0 def incx(): global x x += 2 incx() return x testglobal() # should return 2 但是,我得到一个错误name错误:没有定义名称“x” 有一种骇人的解决方案,可以制作列表并使用列表的第一个值作为x。但这太难看了 那么,我如何与incx函数共享x?或者我应该使用完全不同的方

我有一个递归执行另一个函数的函数,我想为该函数的所有执行共享变量

诸如此类:

def testglobal():
  x = 0
  def incx():
    global x
    x += 2
  incx()
  return x
testglobal() # should return 2
但是,我得到一个错误
name错误:没有定义名称“x”

有一种骇人的解决方案,可以制作列表并使用列表的第一个值作为
x
。但这太难看了


那么,我如何与
incx
函数共享
x
?或者我应该使用完全不同的方法吗?

您想使用
非本地
语句访问
x
,它不是全局的,而是本地的
testglobal

def testglobal():
  x = 0
  def incx():
    nonlocal x
    x += 2
  incx()
  return x
assert 2 == testglobal() 
在Python2中,最接近这样做的方法是用可变值替换
x
,类似于您在问题中提到的参数hack

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() 

您想使用
非本地
语句访问
x
,它不是全局的,而是本地的
testglobal

def testglobal():
  x = 0
  def incx():
    nonlocal x
    x += 2
  incx()
  return x
assert 2 == testglobal() 
在Python2中,最接近这样做的方法是用可变值替换
x
,类似于您在问题中提到的参数hack

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() 

除非您仍在使用Python 2.x,否则这将起作用:

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

testglobal() # should return 2

不过,一个更简洁的解决方案可能是定义一个类来存储方法调用之间的状态。

除非您仍在使用Python 2.x:

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

testglobal() # should return 2
不过,一个更简洁的解决方案可能是定义一个类来存储方法调用之间的状态。

使用该语句,因此
incx
将使用
testglobal
中的
x
变量:

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

testglobal()
使用该语句,因此
incx
将使用
testglobal
中的
x
变量:

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

testglobal()

在Python3中有一个新的关键字,它正是您想要的。请记住,这是一个闭包,因此您可以访问
x
,而无需进行任何更改,但在
incx
内部赋值(例如
x=1
)将使
x
成为
incx
的局部变量,因此不会引用同一变量<代码>非本地实现了这一点。在Python3中有一个新的关键字,它正是您想要的。请记住,这是一个闭包,因此您可以访问
x
,而无需进行任何更改,但在
incx
内部赋值(例如
x=1
)将使
x
成为
incx
的局部变量,因此不会引用同一变量<代码>非本地实现了这一点。但这只是在Python3中引入的,对吗?但是这个概念看起来很普遍,在Python2中如何做到这一点?你不能,除非你的可变参数黑客。闭包只捕获用于读取的变量值;您不能非本地修改值(这就是为什么Python3添加了
nonlocal
关键字)?但是这个概念看起来很普遍,在Python2中如何做到这一点?你不能,除非你的可变参数黑客。闭包只捕获用于读取的变量值;不能非本地修改该值(这就是Python 3添加
nonlocal
关键字的原因)。