【发布时间】:2022-01-18 07:49:01
【问题描述】:
我有一个简单的元类,它将以“get_”开头的类的方法转换为属性:
class PropertyConvertMetaclass(type):
def __new__(mcs, future_class_name, future_class_parents, future_class_attr):
new_attr = {}
for name, val in future_class_attr.items():
if not name.startswith('__'):
if name.startswith('get_'):
new_attr[name[4:]] = property(val)
else:
new_attr[name] = val
return type.__new__(mcs, future_class_name, future_class_parents, new_attr)
假设我有 TestClass:
class TestClass():
def __init__(self, x: int):
self._x = x
def get_x(self):
print("this is property")
return self._x
我希望它像这样工作:我创建了一些从它们都继承的新类
class NewTestClass(TestClass, PropertyConvertMetaclass):
pass
我可以像这样重用他们的两种方法:
obj = NewTestClass(8)
obj.get_x() # 8
obj.x # 8
按照我的理解,我应该创建一个新类,将其命名为 PropertyConvert 并使 NewTestClass 继承自 It:
class PropertyConvert(metaclass=PropertyConvertMetaclass):
pass
class NewTestClass(TestClass, PropertyConvert):
pass
但这并没有帮助,我仍然无法将新属性方法与 NewClassTest 一起使用。如何让 PropertyConvert 继承其兄弟的所有方法,而不在 NewClassTest 中做任何事情,只更改 PropertyConverterMetaclass 或 PropertyConverter?我是元类新手,很抱歉,如果这个问题看起来很愚蠢。
【问题讨论】:
-
您是否希望元类在某个时候成为一个元类?因为从它继承只会使它成为一个奇怪的对象。您有时需要
metaclass=...才能实际使用它来代替type。 -
new_attr在您的元类中最终会丢弃所有非get_*属性,包括 dunders。你的意思是在某个地方放一个else吗?此外,您不需要多余的ifs:任何以get_开头的东西显然都不是以__开头的。 -
是的,我看到这很奇怪,但不幸的是,这是我的编程课程中的一项任务。
-
你至少需要在循环结束时调用
future_class_attr.update(new_attr)... -
即使你做了
class NewTestClass(TestClass, metaclass=PropertyConvertMetaclass):也无济于事。由于NewTestClass没有在其主体中定义任何方法,因此元类没有可操作的内容。TestClass对象是在元类发挥作用之前创建的
标签: python inheritance metaclass