The del陈述 https://docs.python.org/3/reference/simple_stmts.html#the-del-statement适用于任何目标清单 https://docs.python.org/3/reference/simple_stmts.html#grammar-token-target_list,其中包括订阅(del spam[1]
) 和切片 (del spam[:3]
),还有归因(del spam.eggs
)和标识符(del spam
)。它在每种情况下都会做不同的事情。
该声明的文档可能并不能很好地解释每个案例的工作原理,但是数据模型 https://docs.python.org/3/reference/datamodel.html#object.__delitem__本章填补了一些空白。
__delitem__(self, key) https://docs.python.org/3/reference/datamodel.html#object.__delitem__:
调用执行删除self[key]
.
当然,这包括切片;如果你del spam[:3]
,它会调用spam.__delitem__(slice(None, 3))
.
__delattr__(self, name) https://docs.python.org/3/reference/datamodel.html#object.__delattr__:
Like __setattr__()
但用于属性删除而不是赋值。仅应在以下情况下实施:del obj.name
对于对象来说是有意义的。
理论上,一个__getattribute__ https://docs.python.org/3/reference/datamodel.html#object.__getattribute__在类或元类上可以重新路由这些调用。但是由于这两个调用都是通过特殊方法查找 https://docs.python.org/3/reference/datamodel.html#special-lookup,Python 可以直接查找方法,并且至少在 CPython 3.7 和 2.7 中是这样。所以,__delitem__
or __delattr__
总会被调用。
For identifiers, what happens depends on whether the compiler identifies the variable as a local, nonlocal, or global. This uses the same rules as any other variable reference.1
对于全局变量来说,这实际上意味着del globals()['spam']
。对于当地人来说,这有点像del locals()['spam']
,除了它实际上影响当地环境。对于非本地人来说,它本质上称为delete_contents()
作用于闭合单元。
It may help to use the dis https://docs.python.org/3/library/dis.html module to see how CPython compiles the different forms of the del
statement, and then look up what each of the bytecodes does.2 Of course that's specific to CPython, but it demonstrates what any Python implementation needs to do, however it chooses to do it.
1. But notice that deletion counts as a binding operation, just like assignment does. So, unless spam
is declared global
or nonlocal
(or the code is at the top level), del spam
is going to make spam
local.
2. Then again, if you don't know anything about bytecode, fast locals, etc., it probably won't help very much…