Что лучше в Python, del или delattr?
Вопрос
Возможно, это глупо, но это уже какое-то время гложет мой мозг.
Python предоставляет нам два встроенных способа удаления атрибутов из объектов: дель командное слово и делатр встроенная функция.я предпочитаю делатр потому что я думаю, что это немного более явно:
del foo.bar
delattr(foo, "bar")
Но мне интересно, могут ли между ними быть скрытые различия.
Решение
Первое более эффективно, чем второе. 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
Это означает первый запуск немного быстрее (но это не такая уж большая разница — 0,15 мкс на моей машине).
Как говорили другие, вам действительно следует использовать вторую форму только тогда, когда удаляемый атрибут определяется динамически.
[Отредактировано, чтобы показать инструкции байт-кода, сгенерированные внутри функции, где компилятор может использовать LOAD_FAST
и LOAD_GLOBAL
]
Другие советы
- дель является более явным и эффективным;
- делатр позволяет динамическое удаление атрибута.
Рассмотрим следующие примеры:
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)
Вы не можете сделать это с дель.
Бесспорно первое.На мой взгляд, это все равно, что спросить: foo.bar
Это лучше чем getattr(foo, "bar")
, и я не думаю, что кто-то задается этим вопросом :)
Это действительно вопрос предпочтений, но первое, вероятно, предпочтительнее.Я бы использовал второй только в том случае, если вы заранее не знаете имя удаляемого атрибута.
Как и getattr и setattr, delattr следует использовать только в том случае, если имя атрибута неизвестно.
В этом смысле это примерно эквивалентно нескольким функциям Python, которые используются для доступа к встроенным функциям на более низком уровне, чем обычно имеется, например: __import__
вместо import
и operator.add
вместо +
Не уверен насчет внутренней работы, но из соображений возможности повторного использования кода и не будьте придурком с точки зрения коллеги, используйте del.Это более ясно и понятно людям, говорящим на других языках.
Если вы думаете delattr
более явно, то почему бы не использовать getattr
все время, а не object.attr
?
Что касается под капотом...твоя догадка так же хороша как и моя.Если не сказать, значительно лучше.
Это старый вопрос, но я хотел бы внести свои 2 цента.
Хотя, del foo.bar
более элегантно, иногда вам понадобится delattr(foo, "bar")
.Скажем, если у вас есть интерактивный интерфейс командной строки, который позволяет пользователю динамически удалять любой член объекта, набирая имя, то у вас нет другого выбора, кроме как использовать последнюю форму.