Python中的del()内置函数不能用于赋值?

9
当我尝试使用lambda表达式中的del来精简线程列表时,我注意到了一个问题。
map(lambda x: del(x) if not x.isAlive() else x, self.threads)

先不考虑这段代码没有实际作用,我只是在玩弄map、reduce和lambda。

这个代码在del(x)处出现语法错误。经过一些尝试,我认为问题在于del()不会返回值。例如,下面的代码也会出现相同的错误:

b = 5
x = del(b)

然而,这并不包括:

def rmThis(x): del(x)

这意味着我正在使用这个解决方法:
map(lambda x: rmThis(x) if not x.isAlive() else x, self.threads)

那么这个限制只是因为del()不返回值吗?为什么不呢?
我正在使用Python 2.6.2。

需要显式调用del删除线程对象吗?如果可以交给引用计数器或垃圾回收器处理,那么可以这样写:[thread for thread in self.threads if thread.isAlive()] - Tamás
3
即使这个方法可行,它也行不通 :) 在遍历集合时,不能删除其中的元素。 - user97370
2个回答

15
限制在于del是一个语句(statement)而不是表达式(expression)。它不会“返回一个值”,因为在Python中语句不会返回值。 lambda形式只允许提及表达式(因为表达式前有隐含的return),而def形式允许在一行上指定单个语句函数(就像你用rmThis做的那样)。
通常,del不使用括号,如下所示:
del x

然而,将参数放在括号中,如del(x)是允许的,但并不意味着这是一个函数调用。


13

有两个问题。第一个问题比较微妙,所以我会先解释一下。

问题在于del会移除变量的绑定关系。传递值并不能达到你的目的。

这里有一个示例:

>>> a = 5
>>> del(a)
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> def mydel(x): del(x)
... 
>>> a = 5
>>> mydel(a)
>>> a
5
>>> 

如你所见,在第一种情况下,变量a已经从当前命名空间中被删除。除非还有其他指向同一对象的指针,否则不再能引用它所指向的对象。

在第二种情况下,您并没有从命名空间中删除a。您只是删除了函数命名空间中x的绑定,这会导致您无法将x用作函数中的rvalue(即未定义的变量)。

第二个问题是SyntaxError,这更简单。Python lambda函数只能包含表达式而不能包含语句。而del不是表达式(即不是函数调用),而是语句(del_stmt),因此它不能出现在lambda函数体中。如果您尝试将print放在lambda函数体中,您也会遇到同样的问题。

>>> lambda x: print x
  File "<stdin>", line 1
    lambda x: print x
                  ^
SyntaxError: invalid syntax

这也解释了为什么x=del(a)会失败。该语句的语法无效。它不是可调用的函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接