a= something iterable object in python
del a[1]
del a[1]
是否总是与a.__delitem__(1)
相同?
Python del
语句是否定义为对__delitem__
方法的调用?
答案 0 :(得分:2)
The del
statement适用于任何target list,其中包括订阅(del spam[1]
)和切片(del spam[:3]
),还包括署名(del spam.eggs
)和标识符( del spam
)。而且在每种情况下它都会做不同的事情。
该语句的文档可能无法很好地解释每种情况的工作原理,但是Data Model这一章填补了某些空白。
被称为实施
self[key]
的删除。
这当然包括切片;如果您del spam[:3]
,它将调用spam.__delitem__(slice(None, 3))
。
类似于
__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
声明为global
或nonlocal
(或代码位于顶层),否则del spam
将使spam
成为本地。
2。再说一次,如果您对字节码,快速的本地语言等一无所知,那可能不会有太大帮助...