테스트 목적으로 다른 테스트 메소드를 실행하기 전에 삭제할 임시 클래스를 만듭니다. 문제는 [superclass].__subclasses__()
가 가비지 수집을 실행 한 후에도 삭제 된 클래스를 계속 나열한다는 것입니다.가비지 수집은 인스턴스 할당 후 클래스의 del을 인식하지 못합니다.
class Apple(Fruit):
@staticmethod
def mass(size):
return size
class Orange(Fruit):
@staticmethod
def mass(size):
return size
try:
Apple()
Orange()
a1 = Apple(type='fuji')
finally:
if 'a1' in locals():
print 'del a1'
del a1
print gc.get_referrers(Apple)
print gc.get_referrers(Orange)
del Apple
del Orange
print Fruit.__subclasses__()
gc.collect()
print Fruit.__subclasses__()
출력은 다음과 같다 :
여기처럼 내 시험 방법은 어떻게 표시되는지를 보여줍니다 Fruit
가 __metaclass__ = abc.ABCMeta
를 사용 않지만, 관련된 클래스의
del a1
[<frame object at 0xabcdef0>, (<class 'Apple'>, <class 'Fruit'>, <type 'object'>), <Apple object at 0x4443331>, {'a1': <Apple object at 0x4443331, 'self': <FruitTests testMethod=test_pass_Fruit_core>, 'Orange': <class 'Orange'>, 'Apple': <class 'Apple'>}]
[<frame object at 0xabcdef0>, (<class 'Orange'>, <class 'Fruit'>, <type 'object'>), {'a1': <Apple object at 0x4443331, 'self': <FruitTests testMethod=test_pass_Fruit_core>, 'Orange': <class 'Orange'>, 'Apple': <class 'Apple'>}]
[<class 'Apple'>, <class 'Orange'>]
[<class 'Apple'>, <class 'Orange'>]
없음이 __del__()
을 명시 적으로 정의가 없으며, a @abc.abstractmethod
데코레이터 사용시 Fruit.mass()
.
나머지 클래스 참조는 변수에 Fruit
인스턴스의 할당을 함께 할 수있는 뭔가가 : 나는 a1
, 최종 Fruit.__subclasses__()
반환 []
을 포함하는 모든 행을 제거하는 경우 - 베어 생성자 Apple()
은 여전히 실행되는 경우에도. 또 다른 시험 (관련 메소드 실험용 blends()
전화) 과일의 상호 작용에 관심을, 그리고 그 Fruit
의 다른 유형의 조합을 확인하는 Fruit.__subclasses__()
전화를 사용하기 때문에
이 나를 위해 문제입니다. 나는이 테스트 클래스들과의 상호 작용을 정의하는데 신경 쓰지 않았고, 그것은 혼란 스럽다. blends()
.
이러한 참조가 왜 고수하고 있는지에 대한 힌트를 주시면 감사하겠습니다.
편집 : gc.collect() 후에 gc.get_referrers (Apple)을 호출하면 할당 전에 "UnboundLocalError : 로컬 변수 'Apple'이 참조됩니다."Fruit이 "@classmethod"및 "@property"장식, 참고 문헌 또 "블렌드()"처리 클래스 ... 쓰레기 수거 후
, gc.get_referrers(Fruit.__subclasses__()[0])
반환
[{'a1': <Apple object at 0x4443331>, 'self': <FruitTests testMethod=test_pass_Fruit_core>, 'Orange': <class 'Orange'>, 'Apple': <class 'Apple'>}, <Apple object at 0x4443331>, (<class 'Apple'>, <class 'Fruit'>, <type 'object'>)]
편집 : 난 그냥이 하나 개의 시험 방법 실행할 때 문제가 발생합니다 . (여러 테스트를 큐에 넣을 때도 발생합니다.) IDE (PyCharm)를 재부팅하고 명령 줄에서 "./manage.py test FruitTests.test_pass_Fruit_core"를 실행 해 보았습니다. 특정 메모리 주소는 다양하지만 모든 경우에 동일한 결과가 산출됩니다. 지역 주민()이 직접 전화를 받고 있습니다. 아무데도 별명을 지정하지 않았습니다.
편집 : 과일 정의 전체 모듈 : 시험 방법
from abc import abstractmethod, ABCMeta
class Fruit(object):
__metaclass__ = ABCMeta
def __init__(self, **kwargs):
super(Fruit, self).__init__()
@abstractmethod
def mass(self, size):
raise NotImplementedError
는 test_pass_Fruit_core()는 'A1 = 애플()'및 'A1 = 애플 (타입 ='후지 ') "를 생산 같은 결과. "a1"에 할당을 취소해도 아무런 효과가 없지만 "locals()"에 대한 호출을 중단하면 가비지 수집이 예상대로 작동합니다. Apple은 메소드의 끝에서 더 이상 Fruit의 하위 클래스로 사용할 수 없습니다.
그리고'gc.get_referrers는 (애플)'쓰레기 수거 후 무엇을 인쇄 않습니다 클래스 애플 (과일) : @staticmethod 데프 질량 (크기) 위의 첫 번째 코드 블록과 비교? –
하위 클래스에 대한 참조는 약한 참조이므로 다른 *는 여전히이 클래스를 참조합니다. ABC 아키텍처에도 참조가 있고 약한 참조가 사용됩니다. –
'gc.gen_referrers (과일 .__ 하위 클래스 __() [0])'을 사용하십시오. –