如何制作一个继承正常 class 的单例,具有预定义的值,并且可以在不需要圆括号的情况下通过 is 进行比较?

How to make a singleton that inherits a normal class, with predefined values, and comparable by `is` without the need of rounded brackets?

我的尝试是从 metaclass 内部创建默认实例,但没有成功。至少报告的 class 是下面示例中的单例。

编辑:在此澄清要求:通过使用 is 关键字可比较的单例,而不必 instantiate/call 它。不幸的是,这个众所周知的 question-answer here 似乎没有解决这个问题。

class MyNormalClass:
    def __init__(self, values):
        self.values = values


class MySingleton(MyNormalClass, type):
    def __new__(mcs, *args, **kwargs):
        return MyNormalClass(["default"])


print(MySingleton)
# <class '__main__.MySingleton'>

print(MySingleton.values)
# AttributeError: type object 'MySingleton' has no attribute 'values'

Metaclass用于单例的 es 太过分了。 (搜索我的答案,这句话应该出现10次左右)。

在问题的示例代码中,class 和 metaclass 方法中的代码甚至不是 运行,一次也没有。 Python 中没有 black-magic - 程序只有 运行s,并且有一些用 __xx__ 标记的特殊方法将由语言 [=33] 本质上调用=]时间。在这种情况下,每当您创建一个新的 class 并使用它作为您的代码未显示的元 class 时,元 class __new__ 将被调用。而且,它会在每次使用时创建一个新的“单例”实例class。

在这种情况下,如果您只需要一个实例,只需创建那个实例,然后让那个实例成为public,而不是它的[=27] =].您甚至可以使用实例本身来隐藏模块命名空间中的 class,这样就不会有人意外地再次实例化它。如果你希望值是不可变的,那么,你不能 确保 以任何方式使用纯 Python 代码,但您可以使更改的值不会随便与 = 一起工作,以便人们知道他们不应该更改它:


class MySingleton:
    __slots__ = ("values",)
    def __init__(self, values):
        self.values = values
        def lock(self, name, value):
             raise TypeError("Singleton can't change value")
        self.__class__.__setitem__ = lock



MySingleton = MySingleton(["values"])