これはばかげているかもしれませんが、それはしばらくの間私の脳の後ろをしつこくしています。
Pythonには、オブジェクトから属性を削除するための2つの組み込みの方法、delコマンドワードとdelattr組み込み関数があります。私はdelattrを好みます。それは、もう少し明確だと思うからです。
del foo.bar
delattr(foo, "bar")
しかし、私はそれらの間に内部的な違いがあるのではないかと思います。
1つ目は2つ目よりも効率的です。 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
]
次の例を検討してください。
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")
であり、誰もその質問をしているとは思わない:)
それは本当に好みの問題ですが、おそらく最初のものが望ましいでしょう。事前に削除する属性の名前がわからない場合にのみ、2番目の属性を使用します。
getattrやsetattrと同様に、delattrは、属性名が不明な場合にのみ使用する必要があります。
__import__
その意味で、これは、代わりに、import
またはoperator.add
代わりになど、通常利用できるよりも低いレベルで組み込み機能にアクセスするために使用されるいくつかのPython機能とほぼ同等です。+
内部の仕組みについてはよくわかりませんが、コードの再利用性の観点から、同僚の観点からは、delを使用してください。それは他の言語から来た人々によってもより明確で理解されています。
もっと明確だと思うならdelattr
、なぜではなくgetattr
常に使用しないのobject.attr
ですか?
ボンネットの下に関しては...あなたの推測は私のものと同じくらい良いです。大幅に良くない場合。
古い質問ですが、2セント入れたいと思います。
よりエレガントですdel foo.bar
が、時には必要になりますdelattr(foo, "bar")
。たとえば、ユーザーが名前を入力してオブジェクト内の任意のメンバーを動的に削除できるインタラクティブなコマンドラインインターフェイスがある場合は、後者の形式を使用する以外に選択肢はありません。