【问题标题】:Python: Modify Global list inside a functionPython:修改函数内的全局列表
【发布时间】:2015-10-04 19:13:03
【问题描述】:

首先,我明白我可以使用global 语句来访问全局变量。但不知何故,我能够在没有global 的情况下修改全局列表,如下所示:

def func1(nums):
    nums = [4,5,6]

nums = [1,2,3]
func1(nums)
print nums # print [1,2,3]

def func2(nums):
    nums[0] = 4
    nums[1] = 5
    nums[2] = 6

nums = [1,2,3]
func2(nums)
print nums # print [4,5,6]

在尝试了func2之后,我意识到如果我指定索引,我总是可以在函数中访问全局列表:

def func3(nums):
    nums[:] = [4,5,6]

nums = [1,2,3]
func3(nums)
print nums # print [4,5,6]

如果在定义之前使用了函数变量,是否因为Python会自动尝试匹配全局变量?

【问题讨论】:

标签: python function global-variables


【解决方案1】:

我明白我可以使用 global 语句来访问全局变量

你的理解是错误的。只要您没有同名的局部变量,您始终可以访问全局变量。当您要更改变量名称所指的对象时,您只需要global 语句。在您的func2 中,您没有这样做;您只是在更改对象的内容。 nums 仍然指向同一个列表。

【讨论】:

    【解决方案2】:

    它是基于 Python 中的 mutableimmutable 对象的概念。在你的情况下,例如:

    a=[1,2]
    def myfn():
        a=[3,4]
        print id(a)
    
    >>>id(a)
    3065250924L
    >>>myfn()
    3055359596
    

    很明显,两者都是不同的对象。现在:

    a=[1,2]
    def myfn():
        a[:] =[3,4]
        print id(a)
    
    >>>id(a)
    3055358572
    >>>myfn()
    3055358572
    

    这意味着它是在本地和全局范围内使用的相同变量。

    【讨论】:

    • 这与可变性无关。这是一个改变值与重新绑定变量值的问题。
    【解决方案3】:

    在这种特定情况下,这是因为lists 是可变的

    因此,将它们放在 全局命名空间 中,甚至通过 函数 传递,意味着它们将在 Python 持有对可变对象的引用时被更改,不是它的副本。

    如果你用tuples 尝试同样的事情,它不会起作用,因为它们是不可变的

    避免这种情况的方法是向函数提供列表的副本,而不是列表本身:

    func2(list[:])
    

    同时,您可以使用默认参数执行此操作,您可以在其中指定默认参数为[],如果您随后向其添加.append(),则该默认参数将永远在其中保存该项目所有未来的调用(除非您以某种方式将其删除)。

    【讨论】:

      【解决方案4】:
      • 2 个变量 nums 不同,它们指向同一个对象或 2 个不同的对象,尽管它们具有相同的名称。
      • 当您调用func1(nums) 时,意味着您传递了一个引用。现在 2 变量 nums 指向同一个对象。 (2 个变量,1 个对象
      • func1中赋值时,内部变量nums会指向一个新对象,外部不变(2个变量,2个对象
      • 当您调用print nums 时,这个nums 是外部变量,

      【讨论】:

        【解决方案5】:

        这个结果有两个原因:

        1. 变量只是引用对象的名称
        2. 列表是可变的

        func1,nums 中引用一个新对象,因为创建了一个新列表。因此global nums 不受影响。

        func2 中,修改应用于传入的对象。因此global nums 被更改。未创建新对象,因为 list 是可变的。

        参考:https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

        【讨论】:

          猜你喜欢
          • 2014-06-19
          • 1970-01-01
          • 2015-01-31
          • 2014-03-30
          • 2015-10-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多