Singleton is not working in Cython

2019-07-03 23:00发布

问题:

This is how i define Singleton.

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]

Then I have my classes defined as:

class MyClass(object):
    __metaclass__ = Singleton

    def __init__(self):
        pass


a = MyClass()
b = MyClass()

"a is b" will return True

However,

cdef class MyCythonClass(object):
    __metaclass__ = Singleton

    def __cinit__(self):
        pass

c = MyCythonClass()
d = MyCythonClass()

"c is d" will return False

I thought it is the c code (cinit) running before init and so I tried to put the cinit back to init, it doesnt work either. The problem is solved if i removed the "cdef" before "class"

I am wondering why, probably I am missing something important here. Your help would be much appreciated.

Win 10 / Python 2.7

回答1:

Cython does not appear to support meta classes out of the box. But this module may provide a workaround.

Implementing the singleton as follows may be another (safer) alternative:

cdef class Singleton:
    _instances = {}

    @classmethod
    def instance(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = cls(*args, **kwargs)
        return cls._instances[cls]

cdef class MyCythonClass(Singleton):
    pass

c = MyCythonClass.instance()
d = MyCythonClass.instance()
c is d  # True