In Python, why is list[] automatically global?

前端 未结 5 1371
你的背包
你的背包 2020-11-28 12:56

This is a weird behavior.

Try this :

rep_i=0
print \"rep_i is\" , rep_i
def test():
  global rep_i #without Global this gives error but list , dict ,         


        
相关标签:
5条回答
  • 2020-11-28 13:29

    If you had assigned a new value to rep_lst inside of test2 (not just to one of its elements, as you did) it would not work without the global flag. In Python, if you do not assign to a variable inside a function it will look for that variable in in more global scopes until it finds it.

    For example, in this code segment I define the list both globally and inside of example(). Since the variable in example() is closer in scope to example2() than the global one is, it is what will be used.

    x = ["out"]
    
    def example():
        x = ["in"]
        def example2():
            print x # will print ["in"]
    

    This has nothing to do with lists, but is the behaviour of any variable in Python.

    0 讨论(0)
  • 2020-11-28 13:29

    Here's an example that demonstrates that a non list/dict variable is available in a subroutine, and the problem is, as everyone says, the act of rebinding in your original code sample:

    x = 1
    def test():
        y = x + 1
        print y
    test()
    

    You'll see this prints out 2, despite x not being declared global.

    0 讨论(0)
  • 2020-11-28 13:44

    You only need to use global if you are assigning to the global name. Without global, an assignment creates a new local.

    There's nothing special about how global applies to a list—global simply influences scope and name resolution.

    0 讨论(0)
  • 2020-11-28 13:44

    There is an error in python called UnboundLocalError which often confuses newcomers. The confusing thing is: future assignment does change the way a variable is looked up.

    When the interpreter sees a variable name for the first time, it looks ahead to the end of current code block, and if you don't have an assignment to it anywhere within the same block of code, the interpreter considers it global. If you do, however, then it is considered local, and any reference to it before assignment generates an UnboundLocalError. That's the error you got. That's why you need to declare global rep_i. If you did not assign rep_i, you wouldn't need this line.

    Also, this has nothing to do with variable type. Also, assigning or appending an item to the list (which you probably meant to do, but did not) is not assignment of the list itself, it is essentially calling a method on a list object, which is different from assignment: assignment creates a new object (possibly under a name that already exists), while manipulating a list just changes an existing list. You can try:

    In [1]: # It won't work with small integers, as they are cached singletons in CPython
    
    In [2]: a = 123123
    
    In [3]: id (a)
    Out[3]: 9116848
    
    In [4]: a = 123123
    
    In [5]: id(a)
    Out[5]: 9116740
    
    In [6]: # See, it changed
    
    In [7]: # Now with lists
    
    In [8]: l = [1,2,3]
    
    In [9]: id(l)
    Out[9]: 19885792
    
    In [10]: l[1] = 2
    
    In [11]: id(l)
    Out[11]: 19885792
    
    In [12]: # See, it is the same
    
    In [13]: # But if i reassign the list, even to the same value
    
    In [14]: l = [2,2,3]
    
    In [15]: id(l)
    Out[15]: 19884272
    
    0 讨论(0)
  • 2020-11-28 13:49

    It isn't automatically global.

    However, there's a difference between rep_i=1 and rep_lst[0]=1 - the former rebinds the name rep_i, so global is needed to prevent creation of a local slot of the same name. In the latter case, you're just modifying an existing, global object, which is found by regular name lookup (changing a list entry is like calling a member function on the list, it's not a name rebinding).

    To test it out, try assigning rep_lst=[] in test2 (i.e. set it to a fresh list). Unless you declare rep_lst global, the effects won't be visible outside test2 because a local slot of the same name is created and shadows the global slot.

    0 讨论(0)
提交回复
热议问题