Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 清除元类单例_Python_Singleton_Metaclass - Fatal编程技术网

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
not
MySing

我第一眼就看到了这个元类的三个有用的测试用例

  • 测试单个类创建是否正常工作
  • 测试初始类之后是否没有创建新类
  • 测试多个类是否可以结合使用这个元类
无需“重置”按钮即可完成所有这些测试。之后,你将完成你的大部分基础。(我可能忘了一个)


只需创建几个使用这个元类的不同TestClass,并检查它们的Id和类型

我第一眼看到这个元类有三个有用的测试用例

  • 测试单个类创建是否正常工作
  • 测试初始类之后是否没有创建新类
  • 测试多个类是否可以结合使用这个元类
无需“重置”按钮即可完成所有这些测试。之后,你将完成你的大部分基础。(我可能忘了一个)

只需创建几个使用这个元类的不同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()
,这是一个类