【问题标题】:python - How to update __subclasses__ list after deleting an extending object [duplicate]python - 删除扩展对象后如何更新__subclasses__列表[重复]
【发布时间】:2018-01-23 17:47:45
【问题描述】:

首先我应该说这可能不是最好的做法,所以我愿意接受建议。 我正在转发对象的__subclasses__ 列表以运行多个操作。问题是我希望动态添加和删除对象,我希望__subclasses__ 列表能够反映这些更改。但是我没有成功更新它。 这是一个例子:

>>> class a(object):
>>>     pass
>>> class b(a):
>>>     pass
>>> del b
>>> a.__subclasses__()
[<class 'b'>]

我期待得到一个空列表。 现在因为我在我的代码中使用了 a.__subclasses__(),所以我希望在删除对象时更新它。

我尝试使用垃圾收集器并在删除对象后立即调用collect(),就像建议的here 一样,但这也没有帮助。

如果您认为这不是最佳做法并且有更好的方法去做,我会很高兴听到 :)

【问题讨论】:

  • 您愿意接受建议,您能否提供一些您想要实现的目标的背景信息?
  • 运行 gc.collect() 确实为我删除了子类,只要从 _ 无法访问子类。
  • @GerardvanHelden 我有一个服务器 api,它使客户端能够在 mongo 中定义一个集合,而不是为其生成 CRUD。现在客户端完成后,它可以请求处理该集合。我正在创建这个集合,继承一个预定义的对象以获得特定的行为。现在我为我的对象的所有子类启用了不同的功能。我在我的实现中转发了子类列表。现在上下文更清楚了吗?
  • @user2357112 我正在使用 python 2.7.10
  • 这绝对是重复的。我可以在 2.7.10 下重现您的问题,因为 _ 引用了 a.__subclasses__() 返回的列表。正如我在回答中显示的那样,清除 _ 会清除对子类的引用,gc.collect() 可以获取它,此时 a.__subclasses__() 返回一个空列表。如果您仍然看到列出的b,那么您在某处有更多引用,它们仍然保持活跃。

标签: python inheritance subclass


【解决方案1】:

Python 使用弱引用来填充 __subclasses__()。只需运行gc.collect() 即可清除它。

如果您仍然看到其中引用了b,那只是意味着还有更多对该对象的引用。这可以像 _ last-result 参考一样简单:

>>> import sys
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=14, releaselevel='final', serial=0)
>>> class a(object): pass
...
>>> class b(a): pass
...
>>> del b
>>> a.__subclasses__()  # result will be referenced by _
[<class '__main__.b'>]
>>> import gc
>>> gc.collect()
0
>>> a.__subclasses__()  # result will be referenced by _
[<class '__main__.b'>]
>>> 'Clear the _ reference by running a different expression'
'Clear the _ reference by running a different expression'
>>> gc.collect()
3
>>> a.__subclasses__()
[]

所以一旦我们让_ 指向不同的对象,就不会留下对b 的引用,并且子类的弱引用也会被清除。

【讨论】:

  • 感谢您的帮助,我只使用交互式 shell 来运行辅助测试。您的建议在清除 _ 的小场景中确实有效。然而,在我的代码上下文中,在调用 gc.collect() 之后,我仍然有一个对子类列表中已删除对象的引用......
  • @DoronNadav:您有其他地方的参考资料,让课程保持活力。这些可能是来自其他对象的传递引用,这些对象调用了__subclasses__ 并存储了结果,或者因为已删除类的其他子类使其保持活动状态,等等。但是我们无法告诉您哪些代码保存了这些引用。
  • @DoronNadav:您可能需要搜索gc.get_referrers() 堆以查看其他可能引用您的课程的内容。你可能不得不递归直到找到你认可的东西。
猜你喜欢
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 2011-03-15
  • 2023-03-06
  • 1970-01-01
相关资源
最近更新 更多