[英]Python Pointer Ambiguity
假设我有一个带列表baz的函数foo,在foo中,我想像这样清除baz:
baz = []
foo(baz)
foo(baz):
baz = []
现在,此代码无法执行我想要的操作,因为它创建了一个称为baz的新本地列表。 我知道还有其他方法可以执行此操作,但是我想知道Python解决了此类歧义,其中语句
baz = []
可以解释为告诉Python将外部作用域baz变量指向一个新的空内存块,或创建一个指向空内存块的新指针。
编辑
请注意,我不是在问如何清除列表。 我在问Python解释器的行为。 拒绝投票之前,请先清楚阅读问题。
如果您使用global
或nonlocal
关键字明确地将变量赋值给Python,Python只会将其视为从外部作用域分配给变量。 global
表示全局变量, nonlocal
表示闭包变量的Python 3专有关键字:
x = 1
def change_x():
global x
x = 2
def dont_change_x():
# no global
x = 3
change_x()
print(x) # prints 2
dont_change_x()
print(x) # still prints 2
否则,它将始终将分配解释为分配给局部变量。
如果您打算清除列表中的项目,则无需将当前名称重新分配给新列表,只需通过切片将旧名称清除:
foo(baz):
baz[:] = [] # clears out list baz
baz[:]
是索引列表中所有项目并为其分配新值的一种方法
更新 :
如果在分配给新列表的操作中使用了相同的名称,则解释器会将该名称重新分配给新的list
对象:
>>> baz = []
>>> id(baz)
14832064
>>> baz = []
>>> id(baz)
14834304
除了使用切片来重构旧列表以外,名称baz
将不再是对old
列表的引用。
看一下这篇文章,了解python 通过赋值传递参数的方式。
发生的事情是您将变量baz重新定义为另一个列表,因此它不再具有对外部baz的引用。 您需要直接操作列表中的元素。
例如,如果您要向baz添加元素,则外部列表将获得更改:
def foo(baz):
baz.append('baz')
但是通过这样做:
def foo(baz):
baz = []
您为baz分配了一个新列表,对外部baz的引用现在已断开。
对于您的情况,您有2个选项可以清除列表:
del baz[:]
baz[:] = []
使用切片:
>>> def foo(baz):
... baz[:] = []
...
>>> baz = [1, 2]
>>> foo(baz)
>>> baz
[]
该my_list[:]
告诉Python来代替所有的元素my_list
与赋值语句的右侧的内容,指的是同一my_list
对象。
如果要清除列表,请使用.clear()
而不是创建新列表:
def foo(baz):
baz.clear()
旁注:要访问foo()
的外部baz
,可以使用global
关键字。 但是在那种情况下,不会有任何歧义,因为python会通过抛出SyntaxError迫使您重命名该参数。
def foo(baz2):
global baz
baz = []
请注意,不建议使用global
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.