首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python:修改函数内的全局列表

Python:修改函数内的全局列表
EN

Stack Overflow用户
提问于 2015-07-16 00:07:09
回答 5查看 14K关注 0票数 8

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

代码语言:javascript
复制
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之后,我意识到如果我指定索引,我总是可以在函数中访问全局列表:

代码语言:javascript
复制
def func3(nums):
    nums[:] = [4,5,6]

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

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

EN

回答 5

Stack Overflow用户

发布于 2015-07-16 01:42:27

我知道我可以使用global语句来访问全局变量

你的理解是错误的。只要没有同名的局部变量,就可以随时访问全局变量。只有当您要更改变量名所引用的对象时,才需要global语句。在您的func2中,您不会这样做;您只需要更改对象的内容。nums仍然引用相同的列表。

票数 11
EN

Stack Overflow用户

发布于 2015-07-16 00:35:00

它是基于Python中可变和不可变对象的概念。在您的示例中,例如:

代码语言:javascript
复制
a=[1,2]
def myfn():
    a=[3,4]
    print id(a)

>>>id(a)
3065250924L
>>>myfn()
3055359596

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

代码语言:javascript
复制
a=[1,2]
def myfn():
    a[:] =[3,4]
    print id(a)

>>>id(a)
3055358572
>>>myfn()
3055358572

这意味着它是在局部和全局作用域中使用的相同变量。

票数 3
EN

Stack Overflow用户

发布于 2015-07-16 00:22:10

在这种情况下,这是因为list是可变的。

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

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

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

代码语言:javascript
复制
func2(list[:])

同时,您可以使用默认参数来执行此操作,您可以将一个默认参数指定为[],如果您随后对其执行.append()操作,则该默认参数将在以后的所有调用中始终保留该项目(除非您以某种方式删除它)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31435603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档