【发布时间】:2020-10-24 00:46:42
【问题描述】:
我正在尝试更深入地了解元类在 python 中是如何工作的。我的问题如下,我想使用元类来为每个类定义一个方法,该方法将使用在元类中定义的类属性。例如,这有注册申请。
这是一个工作示例:
import functools
def dec_register(func):
@functools.wraps(func)
def wrapper_register(*args, **kwargs):
(args[0].__class__.list_register_instances).append(args[0])
return func(*args, **kwargs)
return wrapper_register
dict_register_classes = {}
class register(type):
def __new__(meta, name, bases, attrs):
dict_register_classes[name] = cls = type.__new__(meta, name, bases, attrs) # assigniation from right to left
cls.list_register_instances = []
cls.print_register = meta.print_register
return cls
def print_register(self):
for element in self.list_register_instances:
print(element)
def print_register_class(cls):
for element in cls.list_register_instances:
print(element)
#
class Foo(metaclass=register):
@dec_register
def __init__(self):
pass
def print_register(self):
pass
class Boo(metaclass=register):
@dec_register
def __init__(self):
pass
def print_register(self):
pass
f = Foo()
f_ = Foo()
b = Boo()
print(f.list_register_instances)
print(b.list_register_instances)
print(dict_register_classes)
print("1")
f.print_register()
print("2")
Foo.print_register_class()
print("3")
f.print_register_class()
print("4")
Foo.print_register()
我最后做的测试没有像我预期的那样工作。如果我所说的没有使用正确的语法,我提前道歉,我试图尽可能清楚:
我在想cls.print_register = meta.print_register 行正在使用元类中定义的方法在类中定义一个方法。因此,它是我可以在对象上使用的一种方法。我也可以将它用作类方法,因为它是在元类中定义的。但是,尽管以下方法有效:
print("1")
f.print_register()
这不能正常工作:
print("4")
Foo.print_register()
有错误:
Foo.print_register()
TypeError: print_register() missing 1 required positional argument: 'self'
对于测试 2 和 3,我期望如果在类级别定义方法,它也应该在对象级别定义。但是,测试 3 引发了错误。
print("2")
Foo.print_register_class()
print("3")
f.print_register_class()
因此,你能解释一下我对类方法的理解是错误的吗?我希望能够在类或对象上调用方法print_register。
也许知道实际上我试图重现以下非常简单的示例可能会有所帮助:
# example without anything fancy:
class Foo:
list_register_instances = []
def __init__(self):
self.__class__.list_register_instances.append(self)
@classmethod
def print_register(cls):
for element in cls.list_register_instances:
print(element)
我不是对元类做同样的事情吗?类方法可以用于类或对象。
另外,如果您对代码结构有任何提示,我将不胜感激。我一定很不擅长元类的语法。
【问题讨论】:
标签: python python-3.x class metaclass class-method