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

9 投票
2 回答
10722 浏览
提问于 2025-04-15 23:04

我在尝试用 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 个回答

15

这里的限制是,del是一个语句,而不是表达式。它不会“返回一个值”,因为在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 当作一个值使用了(也就是说,它变成了一个未定义的变量)。

第二个问题是 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) 会失败。这个语句的语法是无效的。它不是一个可以调用的函数。

撰写回答