Вопрос

Возможно, это глупо, но это уже какое-то время гложет мой мозг.

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").Скажем, если у вас есть интерактивный интерфейс командной строки, который позволяет пользователю динамически удалять любой член объекта, набирая имя, то у вас нет другого выбора, кроме как использовать последнюю форму.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top