如何在 class 中定义方法和成员变量 defined with custom metaclass in python
How to define methods and member variables in class defined with custom metaclass in python
我正在定义一个单例 class,并使用那个 class 作为元 class 来创建新的 classes.
class Singleton(type):
_lock: Lock = Lock()
_instance = {}
def __call__(cls, *args, **kwargs):
with cls._lock:
if cls not in cls._instance:
_instance = super().__call__(*args, **kwargs)
cls._instance[cls] = cls
return cls._instance.get(cls)
新的class定义如下
class SomeClass(metaclass=Singleton):
def __init__(self, some_list = []):
self.some_list = some_list
def add_to_list(self, a):
self.some_list.append(a)
some_class = SomeClass()
我无法访问 some_class 对象的 some_list 变量。它抛出无效属性错误。
some_class.some_list
a_list = [1,2,4,5]
for l in a_list:
some_class.add_to_list(l)
此外,我无法拨打 add_to_list fn。它在参数中抛出缺少参数“a”。
有人可以帮助我理解元class 概念。
你的错误在这里:
cls._instance[cls] = cls
应该是:
cls._instance[cls] = _instance
您正在将 class 本身存储在您的 class 注册表中,而不是它的单个实例。
在我们继续之前,我会指出另一个问题你的代码:
def __init__(self, some_list = []):
永远不要将可变对象(空列表)作为函数或方法的默认参数:每次调用该函数时,相同的对象是re-used。在这种情况下,由于该方法在单例 class 中,这将得到缓解,因此此 __init__
应该 运行 一次,但这是错误的。正确的模式是:
def __init__(self, some_list = None):
if some_list is None:
some_list = []
这确保每次执行该方法时都会创建一个新的、不同的列表。
还有一件事,我不知道为什么这个创建单例的 metaclass 方法如此受欢迎,但这绝对是矫枉过正——我在其他一些答案中谈到了它,包括 , and .
我正在定义一个单例 class,并使用那个 class 作为元 class 来创建新的 classes.
class Singleton(type):
_lock: Lock = Lock()
_instance = {}
def __call__(cls, *args, **kwargs):
with cls._lock:
if cls not in cls._instance:
_instance = super().__call__(*args, **kwargs)
cls._instance[cls] = cls
return cls._instance.get(cls)
新的class定义如下
class SomeClass(metaclass=Singleton):
def __init__(self, some_list = []):
self.some_list = some_list
def add_to_list(self, a):
self.some_list.append(a)
some_class = SomeClass()
我无法访问 some_class 对象的 some_list 变量。它抛出无效属性错误。
some_class.some_list
a_list = [1,2,4,5]
for l in a_list:
some_class.add_to_list(l)
此外,我无法拨打 add_to_list fn。它在参数中抛出缺少参数“a”。
有人可以帮助我理解元class 概念。
你的错误在这里:
cls._instance[cls] = cls
应该是:
cls._instance[cls] = _instance
您正在将 class 本身存储在您的 class 注册表中,而不是它的单个实例。
在我们继续之前,我会指出另一个问题你的代码:
def __init__(self, some_list = []):
永远不要将可变对象(空列表)作为函数或方法的默认参数:每次调用该函数时,相同的对象是re-used。在这种情况下,由于该方法在单例 class 中,这将得到缓解,因此此 __init__
应该 运行 一次,但这是错误的。正确的模式是:
def __init__(self, some_list = None):
if some_list is None:
some_list = []
这确保每次执行该方法时都会创建一个新的、不同的列表。
还有一件事,我不知道为什么这个创建单例的 metaclass 方法如此受欢迎,但这绝对是矫枉过正——我在其他一些答案中谈到了它,包括