Python, как «освободить» объект после использования обратного вызова с «self» - PullRequest
0 голосов
/ 29 ноября 2018

пожалуйста, просмотрите следующий код…

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. object = self.ConfigSetBgError(self.BgError)

оба случая работают, потому что код обратного вызова может справиться с этим

проблема заключается в refCount из self object… case (2) увеличивает refCount на ONE …, поэтому следующий код показывает код разницы…

cl = Client()
print("refCount=" + str(sys.getrefcount(cl)))
cl = None
  1. .tp_dealloc называется ... потому что refCount=2
  2. .tp_dealloc это НЕ вызывается потому что refCount=3

→ так что ... вопрос ... как решить эту проблему refCount проблема очистки?

1 Ответ

0 голосов
/ 29 ноября 2018

Если вас беспокоит обратный вызов, поддерживающий работу экземпляра, не передает связанный метод .self.BgError создает объект метода (через протокол дескриптора ), который ссылается на объект экземпляра, потому что он должен иметь доступ к этому экземпляру при его вызове;вот как параметр self передается в первую очередь.

Если вам не нужно ссылаться на состояние экземпляра, а API обратного вызова может обрабатывать несвязанные методы или метод класса или статические методы, тогда передайте одинвместо этого.

Например, вы можете сделать BgError метод класса или статический метод:

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

Теперь и Client.BgError, и self.BgError (instance_of_Client.BgError)создайте объект метода, привязанный к классу, а не к экземпляру, что даст вам согласованное поведение.Никаких дополнительных ссылок на экземпляр не делается.

Если вам нужно состояние экземпляра, передайте функцию-обертку со слабой ссылкой вашему экземпляру.При вызове проверьте, доступна ли слабая ссылка, прежде чем использовать экземпляр.Также см. с использованием Python WeakSet для включения функции обратного вызова для более подробного сообщения о обратных вызовах и слабых ссылках.Там реестр обратных вызовов заботится о создании и хранении слабых ссылок, но применяются те же принципы.

...