Python 清除元类单例
我已经使用元类创建了一个单例,如中所述 我希望能够在Python 清除元类单例,python,singleton,metaclass,Python,Singleton,Metaclass,我已经使用元类创建了一个单例,如中所述 我希望能够在unittest.TestCase的setUp()方法中清除单例,以便每个测试都从一个干净的单例开始 我想我不太明白这个元类在做什么,因为我无法获得clear()方法的正确咒语: def clear(self): try: del(Singleton._instances[type(self)] except KeyError: pass #Sometimes w
unittest.TestCase
的setUp()
方法中清除单例,以便每个测试都从一个干净的单例开始
我想我不太明白这个元类在做什么,因为我无法获得clear()
方法的正确咒语:
def clear(self):
try:
del(Singleton._instances[type(self)]
except KeyError:
pass #Sometimes we clear before creating
你觉得我做错了什么吗?我的单身汉没有被清除
sing=MySing()
sing.clear()
上面的
type
调用返回Singleton
notMySing
我第一眼就看到了这个元类的三个有用的测试用例
- 测试单个类创建是否正常工作
- 测试初始类之后是否没有创建新类
- 测试多个类是否可以结合使用这个元类李>
只需创建几个使用这个元类的不同TestClass,并检查它们的Id和类型 我第一眼看到这个元类有三个有用的测试用例
- 测试单个类创建是否正常工作
- 测试初始类之后是否没有创建新类
- 测试多个类是否可以结合使用这个元类李>
Singleton
的(更正的)定义和使用它定义的类。我正在将cls
的用法替换为Singleton
,在这里查找是通过的
class Singleton(type):
_instances = {}
# Each of the following functions use cls instead of self
# to emphasize that although they are instance methods of
# Singleton, they are also *class* methods of a class defined
# with Singleton
def __call__(cls, *args, **kwargs):
if cls not in Singleton._instances:
Singleton._instances[cls] = super().__call__(*args, **kwargs)
return Singleton._instances[cls]
def clear(cls):
try:
del Singleton._instances[cls]
except KeyError:
continue
class MySing(metaclass=Singleton):
pass
s1 = MySing() # First call: actually creates a new instance
s2 = MySing() # Second call: returns the cached instance
assert s1 is s2 # Yup, they are the same
MySing.clear() # Throw away the cached instance
s3 = MySing() # Third call: no cached instance, so create one
assert s1 is not s3 # Yup, s3 is a distinct new instance
首先,\u instances
是元类的class属性,用于将类映射到该类的唯一实例
\uuuu call\uuuu
是元类的一个实例方法;它的目的是使元类(即类)的实例可调用cls
这里是定义的类,而不是元类。因此,每次调用MyClass()
,都会转换为单例
clear
也是元类的实例方法,这意味着它还将元类的实例(也就是一个类)作为参数(不是用元类定义的类的实例)。这意味着MyClass.clear()
与Singleton.clear(MyClass)
相同。(这也意味着您可以(但可能不应该)编写s1.clear()
。)
元类实例方法与“常规”类方法的标识还解释了为什么需要在元类中使用\uuuuu call\uuuuu
,而在常规类中使用\uuuu new\uuuuu
:\uuuu new\uuuuuuu
是一种特殊的类方法,无需对其进行修饰。元类为其实例定义实例方法有点棘手,所以我们只使用\uuuu调用\uuuu
(因为类型.\uuu调用\uuuu
除了调用正确的\uu新的\uuu
方法之外,没有什么作用) 让我们浏览一下Singleton
的(更正的)定义和使用它定义的类。我正在将cls
的用法替换为Singleton
,在这里查找是通过的
class Singleton(type):
_instances = {}
# Each of the following functions use cls instead of self
# to emphasize that although they are instance methods of
# Singleton, they are also *class* methods of a class defined
# with Singleton
def __call__(cls, *args, **kwargs):
if cls not in Singleton._instances:
Singleton._instances[cls] = super().__call__(*args, **kwargs)
return Singleton._instances[cls]
def clear(cls):
try:
del Singleton._instances[cls]
except KeyError:
continue
class MySing(metaclass=Singleton):
pass
s1 = MySing() # First call: actually creates a new instance
s2 = MySing() # Second call: returns the cached instance
assert s1 is s2 # Yup, they are the same
MySing.clear() # Throw away the cached instance
s3 = MySing() # Third call: no cached instance, so create one
assert s1 is not s3 # Yup, s3 is a distinct new instance
首先,\u instances
是元类的class属性,用于将类映射到该类的唯一实例
\uuuu call\uuuu
是元类的一个实例方法;它的目的是使元类(即类)的实例可调用cls
这里是定义的类,而不是元类。因此,每次调用MyClass()
,都会转换为单例
clear
也是元类的实例方法,这意味着它还将元类的实例(也就是一个类)作为参数(不是用元类定义的类的实例)。这意味着MyClass.clear()
与Singleton.clear(MyClass)
相同。(这也意味着您可以(但可能不应该)编写s1.clear()
。)
元类实例方法与“常规”类方法的标识还解释了为什么需要在元类中使用\uuuuu call\uuuuu
,而在常规类中使用\uuuu new\uuuuu
:\uuuu new\uuuuuuu
是一种特殊的类方法,无需对其进行修饰。元类为其实例定义实例方法有点棘手,所以我们只使用\uuuu调用\uuuu
(因为类型.\uuu调用\uuuu
除了调用正确的\uu新的\uuu
方法之外,没有什么作用) 除了del(Singleton
处的语法错误外,此代码工作正常。如果尝试print(sing is MySing())
您将得到False
作为输出。clear
作为类方法比作为实例方法更有意义。我发现了我的错误。我这里的示例不是我代码中真正的示例。我的代码实际上有MySing.clear()
这是一个类方法,它解释了为什么self
与我想象的不同。你是想\u instances
成为一个空字典,还是只想删除一个特定的项。?删除特定的实例。除了del(Singleton
处的语法错误外,这段代码工作正常。如果你尝试打印(sing is MySing())
您将得到False
作为输出。clear
作为类方法比作为实例方法更有意义。我发现了我的错误。我这里的示例不是我代码中真正的示例。我的代码实际上有MySing.clear()
,这是一个类