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

del a[1]总是一样吗a.__delitem__(1)

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

4

1 回答 1

2

del语句适用于任何目标列表,其中包括订阅 ( del spam[1]) 和切片 ( del spam[:3]),还包括属性 ( del spam.eggs) 和标识符 ( del spam)。它在每种情况下都会做不同的事情。

该声明的文档可能无法很好地解释每种情况的工作原理,但数据模型一章填补了一些空白。


__delitem__(self, key)

调用以实现删除self[key].

这当然包括切片;如果你del spam[:3],它会打电话spam.__delitem__(slice(None, 3))


__delattr__(self, name)

__setattr__()但对于属性删除而不是分配。del obj.name仅当对对象有意义时才应执行此操作。


理论上,__getattribute__类或元类上的 a 可以重新路由这些调用。但是由于这两个调用都是通过特殊的方法查找完成的,因此允许 Python 直接查找方法,并且至少在 CPython 3.7 和 2.7 中是这样。所以,__delitem____delattr__将永远被调用。


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

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


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


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

2. 话又说回来,如果你对字节码、fast locals 等一无所知,那可能也帮不上什么忙……</sub>

于 2018-06-21T17:42:57.580 回答