Which is better in python, del or delattr?
Question:
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.
Answers:
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.
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 🙂
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
]
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.
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 +
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.
- 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.
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.
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.
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.
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 🙂
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
]
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.
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 +
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.
- 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.
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.