【问题标题】:Are lists implicitly 'global' inside of functions? [duplicate]列表是否在函数内部隐含“全局”? [复制]
【发布时间】:2016-08-18 16:36:32
【问题描述】:

我正在试验这段代码:

def a():
    #global p
    p.append(4);
    d=9

p=[2,3];
d=8
a();
print p  # ----> [2, 3, 4]
print d  # ----> 8

变量d 的值没有改变,因为我没有使用global 关键字。但是列表p在功能上被修改了,即使我没有使用global。函数中是否默认所有列表global

【问题讨论】:

    标签: python python-2.7 global-variables


    【解决方案1】:

    关键的区别是这里的分配。您可以在现有全局对象上调用方法,但如果不调用它们global,就无法分配给它们。在您的代码中,名称 d 被重新分配以引用另一个值。如果您将 p 更改为 assignment,您会得到类似的结果

    def a():
        p = [5, 7]  # new local variable, doesn't change global
        p.append(9)  # doesn't change global p
    

    如果您考虑一下 python 第一次遇到该名称时会发生什么,这是有道理的。在您提供的函数中,python 将看到 p.append 并说“嗯,我没有名为 p 的本地人,让我看看封闭范围。”它看到全局 p 并使用它。

    在我展示的示例中,python 会说“没有明确的global,所以我认为这应该是一个新的局部变量。”并创建一个。

    python 中的名称只是参考。如果 python 遵循您所期望的行为,您需要为您调用的每个函数提供global,让我解释一下:

    def a():
        p.append(1)  # I should need 'global p' to do this
    

    这意味着如果你有

    def g():
        ...
    
    def f():
        g()  # this would also need 'global g', otherwise how does it see g?
    
    def f2():
        global g
        def g():  # changes the global g function
            return 0
    

    【讨论】:

    • 澄清一下,p 对函数 a 可见,即使 p 不是全局的?这与有多少其他语言可以正常工作不同?
    • @rbierman 我认为你把事情搞反了。 在模块顶层定义的所有名称都是全局的。然而,整个函数声明在 python 中是一个单一的范围,所以名称 x 可以引用局部变量 全局变量。如果你在函数中对x 赋值,那么python 会确定该函数体内对名称x所有 引用都指向该局部变量。如果没有找到赋值,则 python 查找封闭范围并找到全局名称x
    • @rbierman 你在哪个例子中说p 不是全局的?
    • 感谢 Ryan,但在我的代码中,我没有使用全局 KW。那么当子程序看到 p.append() 时,它如何修改全局 p 数组呢?同样在这种追加情况下,那么在函数中使用全局 p 和不使用全局 p 有什么区别,因为两者都给出了修改 p 数组的相同结果?
    • @syam 因为在a 的任何地方都没有分配p 局部变量,它会在封闭范围内查找名为p 的东西。如果在你的函数中你有 assignedp 这将引入一个局部变量
    猜你喜欢
    • 1970-01-01
    • 2012-12-12
    • 2022-08-04
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    相关资源
    最近更新 更多