如何制作一个继承正常 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"])
我的尝试是从 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"])