【问题标题】:Singleton is not working in CythonSingleton 不在 Cython 中工作
【发布时间】:2018-12-17 02:36:33
【问题描述】:

这就是我定义单例的方式。

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 MyClass(object):
    __metaclass__ = Singleton

    def __init__(self):
        pass


a = MyClass()
b = MyClass()

"a is b" 将返回 True

然而,

cdef class MyCythonClass(object):
    __metaclass__ = Singleton

    def __cinit__(self):
        pass

c = MyCythonClass()
d = MyCythonClass()

"c is d" 将返回 False

我认为这是在 init 之前运行的 c 代码(cinit),所以我试图将 cinit 放回 init,它也不起作用。 如果我在“class”之前删除“cdef”,问题就解决了

我想知道为什么,可能我在这里遗漏了一些重要的东西。非常感谢您的帮助。

Win 10 / Python 2.7

【问题讨论】:

  • 不确定,但您尝试过用cdef 声明Singleton 吗?
  • 不,我没有,这是我知道如何定义单例的唯一方法,而 C 不允许定义关键字 args ...即 *args , **kwargs。我很高兴有一个解决方法,但同时我也很想了解背后的原因
  • 为什么使用cdef 类很重要?部分原因在于它们是直接用 C 实现的,这让一些事情工作得更快,但失去了 Python 的一些可定制性。想要cdef 的东西似乎并不总是很现实,但希望它支持 Python 所做的一切。 (当然,如果你想在单例中存储像指针这样的 C 数据类型,那可能是合理的......)

标签: python python-2.7 cython cythonize


【解决方案1】:

Cython 似乎不支持开箱即用的元类。但是this module 可能会提供一种解决方法。

如下实现单例可能是另一种(更安全)的选择:

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

【讨论】:

  • 非常感谢,直到!这正是我正在寻找的答案!
  • 嗨,直到,我刚刚发现您建议的解决方案带来了另一个问题,实际上它正在我的实施中发生......我提出了一个新问题并将其放在这里stackoverflow.com/questions/51263233/…
猜你喜欢
  • 1970-01-01
  • 2011-11-09
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-06
相关资源
最近更新 更多