del语句是否始终与调用__delitem__相同?

时间:2018-06-21 17:25:06

标签: python python-3.x

a= something iterable object in python
del a[1]

del a[1]是否总是与a.__delitem__(1)相同?

Python del语句是否定义为对__delitem__方法的调用?

1 个答案:

答案 0 :(得分:2)

The del statement适用于任何target list,其中包括订阅(del spam[1])和切片(del spam[:3]),还包括署名(del spam.eggs)和标识符( del spam)。而且在每种情况下它都会做不同的事情。

该语句的文档可能无法很好地解释每种情况的工作原理,但是Data Model这一章填补了某些空白。


__delitem__(self, key)

  

被称为实施self[key]的删除。

这当然包括切片;如果您del spam[:3],它将调用spam.__delitem__(slice(None, 3))


__delattr__(self, name)

  

类似于__setattr__(),但用于属性删除而不是分配。仅当del obj.name对对象有意义时,才应实现此目的。


理论上,类或元类上的__getattribute__可以重新路由这些调用。但是由于这两个调用都是通过special method lookup完成的,因此Python可以直接查找方法,至少在CPython 3.7和2.7中可以。因此,将始终调用__delitem____delattr__


对于标识符,发生什么情况取决于编译器将变量标识为本地变量,非本地变量还是全局变量。它使用与任何其他变量引用相同的规则。 1

对于全局变量,这实际上意味着del globals()['spam']。对于本地人来说,它有点像del locals()['spam'],除了它实际上会影响本地环境。对于非本地人,它实际上会在闭包单元格上调用delete_contents()函数。


使用dis模块来查看CPython如何编译del语句的不同形式,然后查找每个字节码的作用,可能会有所帮助。 2 当然,这是特定于CPython的,但是它演示了任何Python实现都需要执行的操作,但是它选择执行此操作。


1。但是请注意,就像分配一样,删除也算作绑定操作。因此,除非将spam声明为globalnonlocal(或代码位于顶层),否则del spam将使spam成为本地。

2。再说一次,如果您对字节码,快速的本地语言等一无所知,那可能不会有太大帮助...