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