问题:在python,del或delattr中哪个更好?
这可能很愚蠢,但已经困扰了我一段时间。
Python提供了两种从对象中删除属性的内置方法,即del命令字和delattr内置函数。我更喜欢delattr,因为我认为它更加明确:
del foo.bar
delattr(foo, "bar")
但是我想知道它们之间是否存在内在差异。
This may be silly, but it’s been nagging the back of my brain for a while.
Python gives us two built-in ways to delete attributes from objects, the del command word and the delattr built-in function. I prefer delattr because it I think its a bit more explicit:
del foo.bar
delattr(foo, "bar")
But I’m wondering if there might be under-the-hood differences between them.
回答 0
第一个比第二个更有效。 del foo.bar
编译为两个字节码指令:
2 0 LOAD_FAST 0 (foo)
3 DELETE_ATTR 0 (bar)
而delattr(foo, "bar")
需要五个:
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
。
The first is more efficient than the second. del foo.bar
compiles to two bytecode instructions:
2 0 LOAD_FAST 0 (foo)
3 DELETE_ATTR 0 (bar)
whereas delattr(foo, "bar")
takes five:
2 0 LOAD_GLOBAL 0 (delattr)
3 LOAD_FAST 0 (foo)
6 LOAD_CONST 1 ('bar')
9 CALL_FUNCTION 2
12 POP_TOP
This translates into the first running slightly faster (but it’s not a huge difference – .15 μs on my machine).
Like the others have said, you should really only use the second form when the attribute that you’re deleting is determined dynamically.
[Edited to show the bytecode instructions generated inside a function, where the compiler can use LOAD_FAST
and LOAD_GLOBAL
]
回答 1
- del更明确,更有效;
- delattr允许删除动态属性。
请考虑以下示例:
for name in ATTRIBUTES:
delattr(obj, name)
要么:
def _cleanup(self, name):
"""Do cleanup for an attribute"""
value = getattr(self, name)
self._pre_cleanup(name, value)
delattr(self, name)
self._post_cleanup(name, value)
您不能使用del做到这一点。
- del is more explicit and efficient;
- delattr allows dynamic attribute deleting.
Consider the following examples:
for name in ATTRIBUTES:
delattr(obj, name)
or:
def _cleanup(self, name):
"""Do cleanup for an attribute"""
value = getattr(self, name)
self._pre_cleanup(name, value)
delattr(self, name)
self._post_cleanup(name, value)
You can’t do it with del.
回答 2
无疑是前者。在我看来,这就像在询问是否foo.bar
比更好getattr(foo, "bar")
,而且我认为没有人在问这个问题:)
Unquestionably the former. In my view this is like asking whether foo.bar
is better than getattr(foo, "bar")
, and I don’t think anyone is asking that question :)
回答 3
这实际上是一个优先事项,但第一个可能更可取。如果您不知道要提前删除的属性的名称,我只会使用第二个。
It’s really a matter of preference, but the first is probably preferable. I’d only use the second one if you don’t know the name of the attribute that you’re deleting ahead of time.
回答 4
就像getattr和setattr一样,仅当属性名称未知时才应使用delattr。
从这个意义上讲,它大致等同于几个python功能,这些功能用于以比通常可用的级别低的级别访问内置功能,例如,__import__
代替import
和operator.add
代替+
Just like getattr and setattr, delattr should only be used when the attribute name is unknown.
In that sense, it’s roughly equivalent to several python features that are used to access built-in functionality at a lower level than you normally have available, such as __import__
instead of import
and operator.add
instead of +
回答 5
不确定内部工作原理,但是从代码的可重用性出发,并且不要太讨厌同事,请使用del。来自其他语言的人也更加清楚和理解。
Not sure about the inner workings, but from a code reusability and don’t be a jerk coworker perspective, use del. It’s more clear and understood by people coming from other languages as well.
回答 6
如果您认为delattr
更明确,那为什么不一直使用getattr
而不是object.attr
?
至于幕后…你的猜测和我的一样好。如果没有明显好转。
If you think delattr
is more explicit, then why not used getattr
all the time rather than object.attr
?
As for under the hood… your guess is as good as mine. If not significantly better.
回答 7
这是一个古老的问题,但是我想投入2美分。
虽然del foo.bar
更优雅,但有时您会需要delattr(foo, "bar")
。假设,如果您有一个交互式命令行界面,该界面允许用户通过键入name动态删除对象中的任何成员,那么您别无选择,只能使用后者的形式。
It is an old question, but I would like to put my 2 cents in.
Though, del foo.bar
is more elegant, at times you will need delattr(foo, "bar")
. Say, if you have an interactive command line interface that allows a user to dynamically delete any member in the object by typing the name, then you have no choice but to use the latter form.