Pro*_*e85 5 python inheritance metaclass python-3.x
我正在fields使用元类设置类属性:
class MyMeta(type):
def __new__(mcs, name, bases, clsdict):
clsdict['fields'] = {k: v
for k, v in clsdict.items()
if <my_condition>}
return super(MyMeta, mcs).__new__(mcs, name, bases, clsdict)
class MyBaseClass(metaclass=MyMeta):
fields = {}
Run Code Online (Sandbox Code Playgroud)
以下实例化导致预期结果:
class SubClass(MyBaseClass):
param1 = 1 # meets <my_condition>
>>> SubClass.fields
{param1: 1}
Run Code Online (Sandbox Code Playgroud)
但如果我现在子类SubClass,fields是空的:
class SubSubClass(SubClass):
pass
>>> SubSubClass.fields
{}
Run Code Online (Sandbox Code Playgroud)
我如何能够更新继承层次结构中所有类的 classdict 以便fields从基类更新变量?
您需要以某种方式保留fields超类,例如通过迭代“基础”并使用它们fields作为起点:
class MyMeta(type):
def __new__(mcs, name, bases, clsdict):
if 'fields' not in clsdict:
clsdict['fields'] = {}
# Initialize "fields" from base classes
for base in bases:
try:
clsdict['fields'].update(base.fields)
except AttributeError:
pass
# Fill in new fields (I included a "trivial" condition here, just use yours instead.)
clsdict['fields'].update({k: v for k, v in clsdict.items() if k.startswith('param')})
return super(MyMeta, mcs).__new__(mcs, name, bases, clsdict)
Run Code Online (Sandbox Code Playgroud)
它适用于SubClass和SubSubClass:
>>> SubClass.fields
{'param1': 1}
>>> SubSubClass.fields
{'param1': 1}
Run Code Online (Sandbox Code Playgroud)