这可能很傻,但它已经在我的大脑后面困扰了一段时间。
Python为我们提供了两种从对象中删除属性的内置方法,del命令字和delattr内置函数。我更喜欢delattr,因为我认为它更明确:
del foo.bar
delattr(foo, "bar")
但我想知道它们之间是否有本质上的区别。
这可能很傻,但它已经在我的大脑后面困扰了一段时间。
Python为我们提供了两种从对象中删除属性的内置方法,del命令字和delattr内置函数。我更喜欢delattr,因为我认为它更明确:
del foo.bar
delattr(foo, "bar")
但我想知道它们之间是否有本质上的区别。
当前回答
第一种方法比第二种方法更有效。德尔foo。Bar编译为两个字节码指令:
2 0 LOAD_FAST 0 (foo)
3 DELETE_ATTR 0 (bar)
而delattr(foo, "bar")需要5个:
2 0 LOAD_GLOBAL 0 (delattr)
3 LOAD_FAST 0 (foo)
6 LOAD_CONST 1 ('bar')
9 CALL_FUNCTION 2
12 POP_TOP
这意味着第一个运行得稍微快一些(但差别并不大——在我的机器上是.15 μs)。
正如其他人所说,当您要删除的属性是动态确定的时,您应该只使用第二种形式。
[编辑以显示在函数内部生成的字节码指令,其中编译器可以使用LOAD_FAST和LOAD_GLOBAL]
其他回答
就像getattr和setattr一样,delattr只应该在属性名未知时使用。
从这个意义上说,它大致相当于一些python特性,这些特性用于访问比通常可用的更低级别的内置功能,例如__import__而不是import和operator。用加法代替+
这确实是一个偏好问题,但第一个可能更可取。如果您不知道要提前删除的属性的名称,我只使用第二个。
毫无疑问是前者。在我看来,这就像问foo。bar比getattr(foo, "bar")更好,我不认为有人会问这个问题:)
不确定内部工作原理,但从代码可重用性和不要成为一个混蛋同事的角度来看,使用del。来自其他语言的人也能更清楚地理解它。
第一种方法比第二种方法更有效。德尔foo。Bar编译为两个字节码指令:
2 0 LOAD_FAST 0 (foo)
3 DELETE_ATTR 0 (bar)
而delattr(foo, "bar")需要5个:
2 0 LOAD_GLOBAL 0 (delattr)
3 LOAD_FAST 0 (foo)
6 LOAD_CONST 1 ('bar')
9 CALL_FUNCTION 2
12 POP_TOP
这意味着第一个运行得稍微快一些(但差别并不大——在我的机器上是.15 μs)。
正如其他人所说,当您要删除的属性是动态确定的时,您应该只使用第二种形式。
[编辑以显示在函数内部生成的字节码指令,其中编译器可以使用LOAD_FAST和LOAD_GLOBAL]