后,出于测试目的,我创造,我想删除(其它测试方法运行之前)临时类。麻烦的是,[superclass].__subclasses__()
仍然列出了删除的类,即使在运行垃圾收集之后。垃圾收集不承认德尔类的实例分配
这里是我的测试方法是什么样子:
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__()
输出如下:
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__()
,虽然Fruit
确实使用__metaclass__ = abc.ABCMeta
和@abc.abstractmethod
装修工Fruit.mass()
。
残存类引用有事情做与Fruit
实例变量的赋值:如果我删除包含a1
,最终Fruit.__subclasses__()
返回[]
的所有行 - 即使裸构造Apple()
仍然运行。
这对我来说是一个问题,因为另一个测试是关于水果的相互作用(调用相关的方法将要测试blends()
),并使用一个Fruit.__subclasses__()
调用查看不同类型的Fruit
的组合。我没有打算定义与这些测试类别的交互,这令人困惑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(苹果)'垃圾回收后打印? –
对子类的引用是弱引用,所以*其他*仍然指向这些类。 ABC体系结构也包含引用,同样使用弱引用。 –
使用'gc.gen_referrers(Fruit .__子类__()[0])''。 –