【问题标题】:Mutable global variables don't get hide in python functions, right?可变全局变量不会隐藏在 python 函数中,对吧?
【发布时间】:2010-05-06 14:11:05
【问题描述】:

请看以下代码:

def good():
  foo[0] = 9         # why this foo isn't local variable who hides the global one

def bad():
  foo    = [9, 2, 3] # foo is local, who hides the global one

for func in [good, bad]:
  foo = [1,2,3]

  print('Before "{}": {}'.format(func.__name__, foo))
  func()
  print('After  "{}": {}'.format(func.__name__, foo))

结果如下:

# python3 foo.py
Before "good": [1, 2, 3]
After  "good": [9, 2, 3]
Before "bad" : [1, 2, 3]
After  "bad" : [1, 2, 3]

【问题讨论】:

    标签: python scope


    【解决方案1】:

    因为您没有设置 foo,所以您在 in foo(确切地说是 foo[0])中得到了一些东西。

    在bad 中创建一个新变量foo。在good 中,您执行foo.set(0, 9) 之类的操作(将项目0 设置为值9)。这是使用一个变量,而不是定义一个新名称。

    【讨论】:

    • 我猜是这样,但是为什么设置和使用之间的逻辑不同呢?好的话还得声明全局 foo,是不是更加一致,防止用户自己开枪?
    【解决方案2】:

    变量将首先查看它们的内部作用域,然后再查看 Python 中的外部作用域。例如:

    FOO = 'global'
    
    def printfoo():
        print FOO
    # prints 'global'
    
    def printfoolocal():
        FOO = 'local'
        print FOO
    # prints 'local'
    

    如果你想修改一个全局范围的变量,你需要使用global关键字

    def modifyfoo():
        global FOO
        FOO = 'modified'
    print FOO
    # prints 'modified'
    

    【讨论】:

    • 我知道这种行为,只是好奇这两种情况的差异。我认为@extraneon 回答了我的问题。无论如何,谢谢。
    【解决方案3】:

    为简单起见,python 先查找局部变量,然后查找全局变量。 (用于读取或创建变量)

    所以,最好使用 foo 变量:没有局部 foo 变量和一个全局 foo 变量 => 使用全局变量并对其进行修改。

    糟糕的是,您创建了一个新的(局部)变量,因此不会修改全局变量。

    你可以用 global 关键字指定一个变量是全局的:

    def good2():
        global foo
        foo    = [9, 2, 3]
    

    【讨论】:

    • > “所以,最好使用 foo 变量:没有局部 foo 变量和全局 foo 变量 => 使用全局变量并对其进行修改。”我的问题正是为什么这种行为不会发生在“坏”中。这里有什么规则?
    【解决方案4】:

    如果您想替换列表 foo 的内容,那么您可以分配给整个列表的一部分,例如:

    def good2():
        foo[:] = [9, 2, 3]
    

    就像good 分配给列表的一个元素一样,这会替换整个内容。

    在 bad 中,您将 new 列表绑定到名称 foo。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      相关资源
      最近更新 更多