【问题标题】:why is python function capable of mutating non-global list? [duplicate]为什么python函数能够改变非全局列表? [复制]
【发布时间】:2017-01-08 18:08:42
【问题描述】:
myList = [5, 2]
def foo():
    myList[0] = 6

在上面的例子中,myList 仍然是变异的,尽管它是非全局的并且不是通过参数传入的。但是,如果变量不是列表,这将不起作用。

【问题讨论】:

  • 我认为如果你想改变函数中的某些东西,你必须调用:global myList?
  • 仅当您将新值重新分配给给定名称时。你不在这种情况下。
  • list[0] = 4 可以改变列表的元素而list = [4, 5] 不会。
  • 这个问题不是链接问题的重复,因为另一个问题是关于 Python 中的参数传递,这里没有传递任何参数。

标签: python


【解决方案1】:

范围规则大致是这样的:

  • 局部作用域:在函数内部定义变量
  • 封闭范围:您的函数在另一个函数(或多层函数)内,并且其中一个更高(封闭)函数声明了变量
  • 全局范围:全局范围(模块或文件)
  • 内置:Python 原生的任何内置值

这被称为 LEGB 规则。

在您的情况下,这是因为您没有为 foo() 内部的名称 myList 赋值。您只是为现有列表的0 索引分配一个值。因此,myList 的全局值就是您使用的范围。

【讨论】:

    【解决方案2】:

    myList 是一个全局变量。它存在于foo 的上下文中,您可以在其中访问和修改其中一个元素。

    myList = [0, 5]
    
    def foo():
        myList[0] = 6
    
    print('Before foo: {}'.format(myList))
    foo()
    print('After foo: {}'.format(myList))
    

    输出

    Before foo: [0, 5]
    After foo: [6, 5]
    

    但是,如果变量不是列表,这不起作用。

    我假设您尝试过类似以下的操作:

    a = 0
    
    def bar():
        a = 6
    
    print('Before bar: {}'.format(a))
    bar()
    print('After bar: {}'.format(a))
    

    输出

    Before bar: 0
    After bar: 0
    

    在这种情况下,您不会观察到 global 变量 a 的任何变化,因为在 bar 内,您正在分配一个 新的局部变量 @ 987654330@ 其中shadows 是同名的全局变量。您将 局部变量 a 设置为 6,这没有任何作用,因为该变量会在函数结束后立即被丢弃。

    您可以通过运行以下代码来证明,即使是在全局范围内声明的简单整数也可以在函数范围内访问。在这种情况下,我们指定函数应该修改现有的全局变量b,而不是分配给新的本地变量。

    b = 0
    
    def baz():
        global b
        b = 6
    
    print('Before baz: {}'.format(b))
    baz()
    print('After baz: {}'.format(b))
    

    输出

    Before baz: 0
    After baz: 6
    

    【讨论】:

    • global 关键字的示例在这里可能会有所帮助,因为它显示了一个 可以 如何从本地范围分配给全局变量。 Python 只是假设您通常不是这个意思(并且没有显式声明变量的语法)
    • @pvg 走在你前面。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    相关资源
    最近更新 更多