15

weakref이 모든 것을 수행하는 것을 막을 수있는 장애물이 있습니까? 예 : finalize은 인터프리터가 종료되기 전에 전화가 걸려오고 통화 순서가 잘 정의되어 있는지 확인합니다.`weakref` 콜백이`__del__`을 대체 할 수 있습니까?

먼 과거에 it was thoughtweakref 결국 언어에서 __del__의 제거로 이어질 것으로 보인다.

왜 이런 일이 발생하지 않도록 했습니까?

few use cases for __del__이있는 것 같습니다. 내가 알고있는 모든 것은 weakref 콜백 또는 weakref.finalize으로 적어도 잘 작동하는 것으로 보입니다.

업데이트 : PEP 442 극적으로 __del__의 행동을 개선하고, @gz와 @의 user2357112 언급 weakref와 우려가 나는쪽으로 언어는 일반적으로 __del__보다 안정적 만드는쪽으로 이동 궁금하거나하고있어와

__del__ 대신 weakref 또는 둘 다를 사용하십시오.

+1

* "이런 일이 발생하지 않도록 방지 할 수있는 이유는 무엇입니까?"* 그 대답은 거의 없을 수도있는 질문입니다. 나는 또한 당신이'python-list'에이 글을 게시 해 일부 핵심 개발자들의 관심을 끌 것을 제안합니다. –

+2

파이썬의 weakref 지원은 꽤 나쁘다. 따라서 weakref를 약한 참조로 삼을만한 많은 유형의 오브젝트에 적용 할 수 없다. 이것은 대개 자신이 작성하는 유형에 대해서는 중요하지 않지만, 유형이'튜플 (tuple) '서브 클래스와 같은 것이면 약식으로 작성할 수 없습니다. – user2357112

+1

weakref 콜백은 참조 대상에 액세스 할 수 없기 때문에보다 신중한 디자인이 필요합니다. – user2357112

답변

3

다소 실용적인 이유로 __del__이 아직 있습니다. finalize을 포함하여 몇 가지 의미가있는 weakref 개선 사항은 new in Python 3.4입니다. 따라서 __del__을 weakrefs로 바꾸면 py3k로 언어 변경 사항을 알 수없는 창을 놓쳤습니다.

[Weakref 콜백] 낮은 : 내가 가장 생각

기본 weakref 기능에 의해 대체 될 수 있지만이 제안 곳 issue 15528에 리처드 Oudkerk에서이 관찰 삼진 finalize을 구현하고있어 사용 레벨을 사용하고 올바르게 사용하는 방법은 약간의 머리 긁기가 필요합니다. 지시 대상이 죽은 후에 그리고 지시 대상을 우발적으로 유지하지 않을 때까지 약한 장소를 보관할 어딘가를 찾아야합니다. 그런 다음 콜백이 약한 참조를 해제하는지 확인해야합니다 (나머지 참조 순환을 남기지 않음).

옵션 인 경우 __del__ 메서드를 사용하는 것이 번거롭지 않습니다.

어쨌든 파이썬 4를 고려할 때 질문을 다시 제기해야할까요? ;)

1

은 유스 케이스에 달려 있으며 파이썬 인터프리터의 구현에 따라 CPython과 동일한 GC 동작이없는 것으로 간주하는 것이 좋습니다. 특히

PyPy는 하지 전화를하지 __del__로-곧 같은 객체가 del -eleted을 또는 범위하지만 '나중에 약간의 시간'에서 간다. 따라서 CPython의 __del__ 동작에 의존하는 코드는 PyPy 및 다른 대체 해석기에서 작동하지 않습니다.

with 키워드와 함께 __enter____exit__을 사용하는 것이 좋습니다.예를 들어

from __future__ import print_function 

class MyClass(object): 

    def __enter__(self): 
     print("Entering") 

    def __exit__(self, exc_type, exc_val, exc_tb): 
     print("Exiting") 

# 'with MyClass()' can be used but want to show that 
# code in exit is executed regardless of object 
# life time 
obj = MyClass() 
with obj: 
    print("Stuff happening in between") 

결과는 다음과 같습니다

Entering 
Stuff happening in between 
Exiting 

문 위의 순서가 보장되고 GC 동작에 의존하지 않습니다.

with 블록의 코드가 완료 되 자마자 수행해야하는 작업은 파일 핸들을 지우거나 잠금을 해제하는 등 소멸자에 일반적으로 넣을 것과 같은 __exit__으로 갈 수 있습니다.

개체에 대해 del이 계속 실행되거나 범위를 벗어나면 결국 인터프리터 구현에 따라 개체 참조가 다시 지워지지만 즉시 수행해야하는 작업은 해당 동작에 의존하지 않아야합니다.

관련 문제