回答:
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
これは、最初の実行がわずかに速くなることを意味します(ただし、大きな違いはありません。私のマシンでは0.15μs)。
他の人が言ったように、削除する属性が動的に決定される場合にのみ、実際には2番目の形式を使用する必要があります。
[コンパイラが使用できる機能、内部で発生したバイトコード命令を表示する編集LOAD_FAST
とをLOAD_GLOBAL
】
dis
モジュール。コマンドラインを使用python -m dis
してコードを入力したり、関数を逆アセンブルしたりできますdis.dis()
。
次の例を検討してください。
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ではできません。
del self.__dict__[name]
、もちろん、メタクラスで面白いビジネスが行われていないと仮定
間違いなく前者。私の意見では、これはfoo.bar
がより良いかどうかを尋ねるようなものgetattr(foo, "bar")
であり、誰もその質問をしているとは思わない:)
if hasattr(obj, 'var') and obj.var == ...
... if getattr(obj, 'var', None) == ...
ほとんどの場合、これを単に減らすことができます!少し短くて読みやすいと思います。
hasattr
実際に電話をかけるgetattr