繁体   English   中英

Python指针歧义

[英]Python Pointer Ambiguity

假设我有一个带列表baz的函数foo,在foo中,我想像这样清除baz:

baz = []
foo(baz)

foo(baz):
    baz = []

现在,此代码无法执行我想要的操作,因为它创建了一个称为baz的新本地列表。 我知道还有其他方法可以执行此操作,但是我想知道Python解决了此类歧义,其中语句

 baz = []

可以解释为告诉Python将外部作用域baz变量指向一个新的空内存块,或创建一个指向空内存块的新指针。

编辑

请注意,我不是在问如何清除列表。 我在问Python解释器的行为。 拒绝投票之前,请先清楚阅读问题。

如果您使用globalnonlocal关键字明确地将变量赋值给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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM