python, del 또는 delattr 중 어느 것이 더 낫습니까?


181

이것은 어리석은 일이지만 내 두뇌의 뒷부분을 잠시 동안 잔소리하고 있습니다.

파이썬은 우리에게주는이 내장 된 객체에서 삭제 속성에 방법의 명령 단어와 delattr 내장 기능. 나는 좀 더 명시 적으로 생각하기 때문에 delattr을 선호합니다 .

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

그러나 그들 사이에 차이가 있는지 궁금합니다.

답변:


266

첫 번째는 두 번째보다 더 효율적입니다. 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_FASTLOAD_GLOBAL]


6
이것을 생성하기 위해 어떤 도구를 사용 했습니까?
Triptych

33
dis모듈. python -m dis일부 코드를 사용 하고 입력 하여 명령 행에서 실행 하거나을 사용하여 기능을 분해 할 수 있습니다 dis.dis().
Miles

15
조기 최적화는 모든 악의 근원입니다. ;-) 그러나 네, 물론입니다.
Lennart Regebro

26
.. 따라서 돈에 대한 사랑이 조기 최적화라는 결론을 내립니까?
John Fouhy

5
조기 최적화는 돈에 대한 사랑의 하위 집합입니다. 즉, 처리 능력에 더 적은 비용을 소비하려고 함을 의미합니다.
Rob Grant

41
  • 은보다 명확하고 효율적입니다.
  • 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로는 할 수 없습니다 .


2
del을 사용하여 두 번째 작업을 수행 할 수 있습니다. del self.__dict__[name]물론 메타 클래스와 관련하여 재미있는 비즈니스가 없다고 가정 할 경우
smac89

17

의심의 여지없이 전자. 내 관점에서 이것은 foo.bar보다 나은지 묻는 것과 같 으며 getattr(foo, "bar")아무도 그 질문을하고 있다고 생각하지 않습니다. :)


3
foo.bar보다 getattr (foo, "bar")를 선호하는 사람이 적어도 명 있다고 확신합니다. 물론, 나는 그들에 동의하지 않을 것입니다. 그러나 그 사람은 여전히 ​​의심 할 여지없이 전자가되기에 충분합니다.
Jason Baker

3
@Jason 그렇다면이 구절을 해석하면 다른 어떤 것보다 "더 나은 것은 없습니다". 나는 이것이 "의심없이"를 완벽하게 합리적으로 사용한다고 생각합니다.
Phob

26
getattr은 특성이 존재하지 않을 수 있고 try / except 블록을 쓰지 않고 기본값을 설정하려는 경우에 바람직합니다. 즉. gettattr (foo, "bar", None)
Marc Gibbons

2
@MarcGibbons : 잠깐만 요? 나는 항상 패턴을 사용했습니다 if hasattr(obj, 'var') and obj.var == ...... if getattr(obj, 'var', None) == ...대부분의 경우에 이것을 줄일 수 있습니다 ! 조금 더 짧고 읽기 쉽다고 생각합니다.
ArtOfWarfare

@ArtOfWarfare는 hasattr실제로 전화getattr
cheniel

14

그것은 실제로 선호의 문제이지만 첫 번째가 바람직 할 것입니다. 미리 삭제하는 속성의 이름을 모르는 경우에만 두 번째 것을 사용합니다.


5

getattr 및 setattr과 마찬가지로 delattr은 속성 이름을 알 수없는 경우에만 사용해야합니다.

그런 의미에서, 그것은 다음과 같은 가능한 내장 낮은 수준에서 기능하는 것이 일반적이보다 액세스에 사용되는 여러 파이썬 기능이 거의 비슷의 __import__대신 importoperator.add대신+


3

내부 작업에 대해서는 확실하지 않지만 코드 재사용 성으로 인해 동료의 관점에서 보면 델을 사용하십시오. 다른 언어를 사용하는 사람들이 더 명확하고 이해합니다.


1

당신 delattr이 더 명백 하다고 생각한다면 , 왜 getattr항상 사용하지 object.attr않는가?

후드 아래에서 ... 당신의 추측은 내만큼 좋습니다. 크게 개선되지 않은 경우.


1

그것은 오래된 질문이지만 내 2 센트를 넣고 싶습니다.

del foo.bar더 우아 하지만 때로는 필요할 것 delattr(foo, "bar")입니다. 예를 들어, name입력하여 사용자가 오브젝트의 멤버를 동적으로 삭제할 수있는 대화식 명령 행 인터페이스가 있는 경우 후자를 사용할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.