我想知道是否有任何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函数中执行的动作来改变,这真的很奇怪!这种纠缠是否正常?它有名字吗?
这两个函数甚至不使用相同的名称来引用列表。这非常奇特。我有点喜欢它。
答案 0 :(得分:1)
行为与Ruby完全相同:
def foo()
nums = [1,2,3]
bar(nums)
p(nums)
end
def bar(numbers)
numbers.pop
end
foo()
# prints [1, 2]
您无法更改局部变量的引用以引用其他变量。但是您可以调用原位更改状态的方法。 list.pop
就是这种方法之一。 (与Ruby中的Array#pop
相同)
答案 1 :(得分:1)
列表是一个对象,调用对象上的方法(如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
那么当你调用numbrs.pop()时会发生什么?据推测,在列表的定义中,您将找到方法定义:
def pop(self):
通过删除其中一个成员来修改自身对象的状态,并返回已删除的成员。
那种情况下的自我是什么?它是对列表的引用。具体来说,当你执行pop()操作时,它就是被称为numbrs的引用,这与你在创建它时存储为nums的引用相同。
我希望这会有所帮助 - 它有很多间接性,但是如果你按照参考文献进行操作,你会看到它的全部内容。
答案 2 :(得分:0)
这有点奇怪,我不确定这是否是问题的答案,但如果你运行这个:
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]