Is it possible to modify variable in python that is in outer, but not global, scope?

前端 未结 9 1957
温柔的废话
温柔的废话 2020-11-30 02:55

Given following code:

def A() :
    b = 1

    def B() :
        # I can access \'b\' from here.
        print( b )
        # But can i modify \'b\' here? \'         


        
相关标签:
9条回答
  • 2020-11-30 03:11

    I'm a little new to Python, but I've read a bit about this. I believe the best you're going to get is similar to the Java work-around, which is to wrap your outer variable in a list.

    def A():
       b = [1]
       def B():
          b[0] = 2
       B()
       print(b[0])
    
    # The output is '2'
    

    Edit: I guess this was probably true before Python 3. Looks like nonlocal is your answer.

    0 讨论(0)
  • 2020-11-30 03:12

    No you cannot, at least in this way.

    Because the "set operation" will create a new name in the current scope, which covers the outer one.

    0 讨论(0)
  • 2020-11-30 03:15

    You can use an empty class to hold a temporary scope. It's like the mutable but a bit prettier.

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

    This yields the following interactive output:

    >>> outer_fn()
    8 27
    >>> fs = FnScope()
    NameError: name 'FnScope' is not defined
    
    0 讨论(0)
  • 2020-11-30 03:16

    Python 3.x has the nonlocal keyword. I think this does what you want, but I'm not sure if you are running python 2 or 3.

    The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.

    For python 2, I usually just use a mutable object (like a list, or dict), and mutate the value instead of reassign.

    example:

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

    Outputs:

    [1, 1]
    
    0 讨论(0)
  • 2020-11-30 03:16

    You can, but you'll have to use the global statment (not a really good solution as always when using global variables, but it works):

    def A():
        global b
        b = 1
    
        def B():
          global b
          print( b )
          b = 2
    
        B()
    A()
    
    0 讨论(0)
  • 2020-11-30 03:23

    For anyone looking at this much later on a safer but heavier workaround is. Without a need to pass variables as parameters.

    def outer():
        a = [1]
        def inner(a=a):
            a[0] += 1
        inner()
        return a[0]
    
    0 讨论(0)
提交回复
热议问题