Python局部变量正在被另一个方法更改

2024-04-25 12:51:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我想知道是否有python的人可以告诉我以下情况是如何/为什么发生的:

# define a list and send it as an arg to another function
def foo():
    nums=[1,2,3]
    bar(nums)
    print(nums)

# Take the list as an arg and pop the last element off
def bar(numbrs):
    numbrs.pop()

# Call the first function
foo()

# The nums local variable has been modified
[1, 2]

作为一个rubyist,我发现foo函数中的一个局部定义变量(nums)可以通过bar函数中执行的一个操作进行更改,这真的很奇怪!这种纠缠正常吗?有名字吗?你知道吗

这两个函数甚至不使用相同的名称来引用列表。这很奇怪。不过我还是挺喜欢的。你知道吗


Tags: andthe函数anfoodefasarg
3条回答

与Ruby的行为完全相同:

def foo()
  nums = [1,2,3]
  bar(nums)
  p(nums)
end

def bar(numbers)
  numbers.pop
end

foo()
# prints [1, 2]

DEMO

不能将局部变量的引用更改为引用其他变量。但是您可以调用就地更改状态的方法。^{}就是这样的方法之一。(与Ruby中的^{}相同)

这有点奇怪,我不确定这是否是问题的答案,但如果你运行这个:

def foo():
    nums=[1,2,3]
    print "foo"
    print locals()
    print globals()
    bar(nums)
    print "foo-after"
    print locals()
    print globals()
    print(nums)


def bar(numbrs):
    print "bar"
    print locals()
    print globals()
    numbrs.pop()
    print "bar-after"
    print locals()
    print globals()

foo()

输出:

>>> foo()
foo
{'nums': [1, 2, 3]}
{'bar': <function bar at 0x024759B0>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x024593B0>, '__doc__': None}
bar
{'numbrs': [1, 2, 3]}
{'bar': <function bar at 0x024759B0>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x024593B0>, '__doc__': None}
bar-after
{'numbrs': [1, 2]}
{'bar': <function bar at 0x024759B0>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x024593B0>, '__doc__': None}
foo-after
{'nums': [1, 2]}
{'bar': <function bar at 0x024759B0>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x024593B0>, '__doc__': None}
[1, 2]

列表是一个对象,调用对象上的方法(如pop())会影响其状态。你知道吗

更准确地说,让我们浏览一下您的代码,看看发生了什么:

def foo():
    nums=[1,2,3]  # create a list and give it a name. nums contains a reference to the list
    bar(nums)     # call the method bar, passing it the reference to that list
    print(nums)   # print the list.

好吧,这很清楚。酒吧里发生的事和你有关:

# Take the list as an arg and pop the last element off
def bar(numbrs):  # method gets a value. In this case the value is a reference to a list
    numbrs.pop()  # call a method on that object

你打电话的时候会发生什么数字流行音乐()? 在list的定义中,您可能会发现一个方法定义:

def pop(self):

它通过移除自身对象的一个成员来修改自身对象的状态,并返回移除的成员。你知道吗

在这种情况下,自我是什么?它是一个列表的引用。具体来说,它是在执行pop()操作时被称为numbrs的引用,与创建它时存储为nums的引用相同。你知道吗

我希望这有帮助-这是很多间接的,但如果你遵循周围的参考,你会看到一切如何进行。你知道吗

相关问题 更多 >