답변:
첫 번째는 두 번째보다 더 효율적입니다. 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
이것은 첫 실행 속도 가 약간 빨라지는 것을 의미합니다 (그러나 머신에서 .15 μs와 큰 차이는 없습니다).
다른 사람들이 말했듯이 삭제하는 속성이 동적으로 결정될 때 두 번째 양식 만 사용해야합니다.
[컴파일러가 사용할 수있는 기능, 내부에서 발생하는 바이트 코드 명령어 보여 편집 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