Порядок деструктора при использовании метакласса, импортированного из другого модуля - PullRequest
0 голосов
/ 22 апреля 2020

Я хочу использовать шаблон синглтона в python. Это код для него:

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

Я хочу использовать его как метакласс, например:

class Foo(metaclass=Singleton):
  def __init__(self):
      self._test_list = {}

  def __del__(self):
      self._test_list = {}

def main():
   test = Foo()

У меня проблема с порядком наведения деструктора. Я добавляю отпечатки к del класса Foo и для Singleton. Когда у меня есть метакласс Singleton и класс Foo в одном и том же скрипте .py, порядок отпечатков следующий:

del singleton
del Foo

Но когда я импортирую Singleton из другого модуля с простой строкой from module_path import Singleton, порядок меняется на:

del Foo
del singleton

В моем коде это ключевое отличие, потому что для второго варианта код не работает (спецификация внешней библиотеки c), но организация файлов не интуитивно понятна.

  1. Почему это происходит?
  2. Как я могу обеспечить один правильный порядок деструкторов?

Весь код:

#I use these line with exactly the same Singleton metaclass implementation in module_path
from module_path import Singleton
#Or this Singleton implementation inside the same file as Foo class
class Singleton(type):
   _instances = {}

   def __call__(cls, *args, **kwargs):
      if cls not in cls._instances:
          cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
      return cls._instances[cls]

  def __del__(cls):
      print('del singleton')

class Foo(metaclass=Singleton):
    def __init__(self):
        self._test_list = {}

    def __del__(self):
        print('del Foo')
        self._test_list = {}


def main():
    test = Foo()
...