【问题标题】:python how to "free" an object after callback with "self" is usedpython如何在使用“self”回调后“释放”一个对象
【发布时间】:2018-11-29 11:20:43
【问题描述】:

请查看以下代码...

class Client(MqC):                                                                                                 

  def __init__(self, tmpl=None):                                                                                   
    self.ConfigSetBgError(self.BgError)                                                                          
    MqC.__init__(self)                                                                                             

  def BgError(self):                                                                                               
    ... do some stuff……

我可以将回调 BgError 添加为类或对象回调...

  1. class= self.ConfigSetBgError(Client.BgError)
  2. 对象 = self.ConfigSetBgError(self.BgError)

这两种情况都有效,因为回调代码可以处理此问题

问题是 self 对象的 refCount ......情况(2)将 refCount 增加 ONE…所以下面的代码显示了差异代码…

cl = Client()
print("refCount=" + str(sys.getrefcount(cl)))
cl = None
  1. .tp_dealloc 被称为...因为refCount=2
  2. .tp_dealloc 调用,因为 refCount=3

→ 所以……问题……如何解决这个 refCount 清理问题?

【问题讨论】:

  • 请不要用C标记有关python的问题。谢谢。

标签: python automatic-ref-counting


【解决方案1】:

如果您担心回调使实例保持活动状态,那么不要传入绑定方法self.BgError 创建一个方法对象(通过descriptor protocol),它引用实例对象,因为它需要在调用时访问该实例;这就是首先传入self 参数的方式。

如果您不需要引用实例状态并且回调 API 可以处理未绑定的方法或类方法或静态方法,则改为传递其中之一。

例如,您可以将BgError 设为类方法或静态方法:

@classmethod
def BgError(cls):
    # ...

现在Client.BgErrorself.BgError (instance_of_Client.BgError) 都会生成一个绑定到类而不是实例的方法对象,从而为您提供一致的行为。没有额外引用该实例。

如果您确实需要实例状态,请将带有 weak reference 的包装函数传递给您的实例。调用时,在使用实例之前检查弱引用是否仍然可用。另请参阅 using python WeakSet to enable a callback functionality 以获取有关回调和弱引用的更深入的帖子。回调注册表负责生成和存储弱引用,但原理相同。

【讨论】:

    猜你喜欢
    • 2011-09-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多