是否可以在python中修改外部但不是全局范围的变量?

gri*_*yvp 95 python python-2.7

给出以下代码:

def A() :
    b = 1

    def B() :
        # I can access 'b' from here.
        print( b )
        # But can i modify 'b' here? 'global' and assignment will not work.

    B()
A()
Run Code Online (Sandbox Code Playgroud)

对于B()函数变量中的代码,b在外部作用域中,但不在全局作用域中.是否可以bB()函数内修改变量?当然我可以从这里读取它print(),但是如何修改呢?

Ada*_*ner 83

Python 3.x有nonlocal关键字.我认为这样做你想要的,但我不确定你是否正在运行python 2或3.

非本地语句使列出的标识符引用最近的封闭范围中的先前绑定的变量.这很重要,因为绑定的默认行为是首先搜索本地名称空间.除了全局(模块)范围之外,该语句还允许封装代码重新绑定局部范围之外的变量.

对于python 2,我通常只使用一个可变对象(如列表或dict),并改变值而不是重新分配.

例:

def foo():
    a = []
    def bar():
        a.append(1)
    bar()
    bar()
    print a

foo()
Run Code Online (Sandbox Code Playgroud)

输出:

[1, 1]
Run Code Online (Sandbox Code Playgroud)

  • 一个很好的方法是在外部作用域中使用`class nonlocal:pass`.然后可以在内部范围中指定`nonlocal.x`. (15认同)
  • @kindall非常整洁谢谢堆:)可能需要一个不同的名称,因为它打破了兼容性.在python 3中,它是一个关键字冲突,会导致`SyntaxError`.也许是"非本地人"? (2认同)

chr*_*isk 17

您可以使用空类来保存临时范围.它就像可变但有点漂亮.

def outer_fn():
   class FnScope:
     b = 5
     c = 6
   def inner_fn():
      FnScope.b += 1
      FnScope.c += FnScope.b
   inner_fn()
   inner_fn()
   inner_fn()
Run Code Online (Sandbox Code Playgroud)

这会产生以下交互式输出:

>>> outer_fn()
8 27
>>> fs = FnScope()
NameError: name 'FnScope' is not defined
Run Code Online (Sandbox Code Playgroud)


Mik*_*rds 11

我对Python有点新意,但我已经对此有所了解.我相信你得到的最好的东西类似于Java解决方法,即将你的外部变量包装在一个列表中.

def A():
   b = [1]
   def B():
      b[0] = 2
   B()
   print(b[0])

# The output is '2'
Run Code Online (Sandbox Code Playgroud)

编辑:我想在Python 3之前这可能是真的.看起来'nonlocal'是你的答案.