Python的del()内置函数不能用于赋值吗?
我在尝试用 lambda 表达式来筛选出正在运行的线程时,发现了一个问题:
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 版本。
2 个回答
这里的限制是,del
是一个语句,而不是表达式。它不会“返回一个值”,因为在Python中,语句是不会返回值的。
lambda
形式只允许你提到表达式(因为在表达式之前有一个隐含的return
),而def
形式允许你在一行中定义一个单语句的函数(就像你对rmThis
所做的那样)。
通常情况下,del
是直接使用的,不需要括号,如下所示:
del x
不过,把参数放在括号里,比如del(x)
也是可以的,但这并不意味着它是一个函数调用。
有两个问题。第一个问题比较复杂,所以我先解释这个。
问题在于,使用 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
当作一个值使用了(也就是说,它变成了一个未定义的变量)。
第二个问题是 SyntaxError
,这个问题比较简单。Python 的 lambda
函数里面只能有表达式,而不能有语句。del
不是一个表达式(也就是说,它不是一个函数调用),而是一个语句(del_stmt
),所以它不能出现在 lambda
的主体里面。如果你试着在 lambda
的主体里放一个 print
,也会遇到同样的问题。
>>> lambda x: print x
File "<stdin>", line 1
lambda x: print x
^
SyntaxError: invalid syntax
这也解释了为什么 x=del(a)
会失败。这个语句的语法是无效的。它不是一个可以调用的函数。