Python指针模糊

时间:2016-06-30 21:57:51

标签: python list pointers

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

baz = []
foo(baz)

foo(baz):
    baz = []

现在,这段代码没有按照我的意愿去做,因为它创建了一个名为baz的新本地列表。我知道还有其他方法可以做到这一点,但我想知道Python解决了这样的含糊不清的声明

 baz = []

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

修改

请注意,我不是在询问如何清除列表。我问的是Python解释器的行为。请在downvoting之前清楚地阅读这个问题。

5 个答案:

答案 0 :(得分:2)

如果您使用globalnonlocal关键字明确告知变量,则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

否则,它总是将赋值解释为赋值给局部变量。

答案 1 :(得分:1)

如果您打算清除列表中的项目,则无需将当前名称重新分配给新列表,只需通过切片清除旧名称:

foo(baz):
    baz[:] = [] # clears out list baz

baz[:]是一种索引列表中所有项目并为其指定新值的方法

更新

如果在新列表的赋值中使用相同的内容,解释器只需将该名称重新分配给新的list对象:

>>> baz = []
>>> id(baz)
14832064
>>> baz = []
>>> id(baz)
14834304

除非您使用切片重构列表,否则名称baz将不再是old列表的引用。< / p>

答案 2 :(得分:1)

看一下这篇文章,了解passing parameters by assignment的python方式。

发生的事情是您正在将变量baz重新定义为另一个列表,因此它不再具有对外部baz的引用。您需要直接操作列表中的元素。

例如,如果您要向baz添加元素,外部列表将获得更改:

def foo(baz):
    baz.append('baz')

但这样做:

def foo(baz):
    baz = []

您为baz分配了一个新列表,现在已经破坏了对外部baz的引用。

在您的情况下,您有2个选项可以清除列表:

del baz[:]
baz[:] = []

答案 3 :(得分:0)

使用切片:

>>> def foo(baz):
...     baz[:] = []
...
>>> baz = [1, 2]
>>> foo(baz)
>>> baz
[]

my_list[:]告诉Python将my_list中的所有元素替换为赋值语句右侧的内容,引用相同的my_list对象。

答案 4 :(得分:-1)

如果要清除列表,请使用.clear()而不是创建新列表:

def foo(baz):
    baz.clear()

附注:要访问baz中的外部foo(),您可以使用global关键字。但是在这种情况下不存在歧义,因为python会强制你通过抛出SyntaxError来重命名参数。

def foo(baz2):
    global baz
    baz = []

请注意,不鼓励使用global