Что лучше в python, del или delattr? - PullRequest
164 голосов
/ 13 июля 2009

Это может быть глупо, но какое-то время мучило мою спину.

Python предоставляет нам два встроенных способа удаления атрибутов из объектов, командное слово del и встроенную функцию delattr . Я предпочитаю delattr , потому что я думаю, что это немного более явно:

del foo.bar
delattr(foo, "bar")

Но мне интересно, могут ли быть различия между ними.

Ответы [ 8 ]

243 голосов
/ 13 июля 2009

Первый более эффективен, чем второй. 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]

36 голосов
/ 15 октября 2013
  • 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 .

17 голосов
/ 13 июля 2009

Несомненно прежний. На мой взгляд, это все равно, что спросить, лучше ли foo.bar, чем getattr(foo, "bar"), и я не думаю, что кто-то задает этот вопрос:)

14 голосов
/ 13 июля 2009

Это действительно вопрос предпочтений, но первый, вероятно, предпочтительнее. Я бы использовал второй, только если вы не знаете название атрибута, который вы удаляете заранее.

5 голосов
/ 13 июля 2009

Так же, как getattr и setattr, delattr следует использовать только тогда, когда имя атрибута неизвестно.

В этом смысле это примерно эквивалентно нескольким функциям Python, которые используются для доступа к встроенным функциям на более низком уровне, чем у вас обычно есть, например __import__ вместо import и operator.add вместо +

3 голосов
/ 13 июля 2009

Не уверен насчет внутренней работы, но с точки зрения повторного использования кода и не будь мудрым коллегой, используйте del.Это понятнее и понятнее людям с других языков.

1 голос
/ 08 июля 2014

Это старый вопрос, но я бы хотел поставить свои 2 цента.

Хотя del foo.bar более элегантно, иногда вам понадобится delattr(foo, "bar"). Скажем, если у вас есть интерактивный интерфейс командной строки, который позволяет пользователю динамически удалять любого члена в объекте, набрав , набрав имя , то у вас нет выбора, кроме как использовать последнюю форму.

1 голос
/ 13 июля 2009

Если вы думаете, delattr является более явным, то почему бы не использовать getattr все время, а не object.attr?

Что касается под капотом ... Ваше предположение так же хорошо, как и мое. Если не значительно лучше.

...