web-dev-qa-db-ja.com

python、del、delattrのどちらが良いですか?

これはばかげているかもしれませんが、しばらくの間私の頭の後ろをしつこくしていました。

Pythonには、オブジェクトから属性を削除する2つの組み込み方法、delコマンドWordとdelattr組み込み関数があります。 delattrの方が好きです。

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

しかし、私はそれらの内部の違いがあるかもしれないのだろうかと思っています。

165
pydanny

前者は後者よりも効率的です。 del foo.barは、2つのバイトコード命令にコンパイルします。

  2           0 LOAD_FAST                0 (foo)
              3 DELETE_ATTR              0 (bar)

一方、delattr(foo, "bar")は5つかかります。

  2           0 LOAD_GLOBAL              0 (delattr)
              3 LOAD_FAST                0 (foo)
              6 LOAD_CONST               1 ('bar')
              9 CALL_FUNCTION            2
             12 POP_TOP             

これは、最初の実行わずかにより高速に変換されます(ただし、大きな違いではありません-私のマシンでは.15μs)。

他の人が言ったように、実際に削除する属性が動的に決定される場合にのみ、2番目のフォームを使用する必要があります。

[コンパイラーがLOAD_FASTおよびLOAD_GLOBAL]を使用できる関数内で生成されたバイトコード命令を表示するように編集されました

248
Miles
  • 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ではできません。

37

間違いなく前者。私の見解では、これはfoo.bargetattr(foo, "bar")より優れているかどうかを尋ねるようなもので、誰もその質問をしているとは思わない:)

17
Alex Gaynor

本当に好みの問題ですが、おそらく最初の方が望ましいでしょう。事前に削除する属性の名前がわからない場合にのみ、2番目のものを使用します。

14
Jason Baker

Getattrおよびsetattrと同様に、delattrは属性名が不明な場合にのみ使用してください。

その意味では、importの代わりに__import__など、通常よりも低いレベルで組み込み機能にアクセスするために使用されるいくつかのpython機能とほぼ同等です。およびoperator.addの代わりに+

5
Algorias

内部の動作についてはわかりませんが、コードの再利用性と、同僚の不愉快な観点からは、delを使用してください。他の言語から来た人にもわかりやすく理解されています。

3
eleddy

これは古い質問ですが、2セントを入れたいと思います。

ただし、del foo.barはよりエレガントですが、場合によってはdelattr(foo, "bar")が必要になります。たとえば、ユーザーが名前の入力によってオブジェクト内のメンバーを動的に削除できるインタラクティブなコマンドラインインターフェイスがある場合、後者の形式を使用する以外に選択肢はありません。

1
kaosad

delattrがより明示的であると思う場合、object.attrではなくgetattrを常に使用しないのはなぜですか?

フードの下では...あなたの推測は私のものと同じくらい良いです。大幅に改善されていない場合。

1
Dougal Matthews