I am setting a class property fields
using a metaclass:
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 = {}
The following instantiation leads to expected results:
class SubClass(MyBaseClass):
param1 = 1 # meets <my_condition>
>>> SubClass.fields
{param1: 1}
But if I now subclass SubClass
, fields
is empty:
class SubSubClass(SubClass):
pass
>>> SubSubClass.fields
{}
How would I be able to update the classdict of all classes in inheritance hierarchy so that the fields
variable would be updated from base classes?
You need to somehow keep the fields
of the superclasses, for example by iterating over the "bases" and using their fields
as starting point:
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)
And it works for SubClass
and SubSubClass
:
>>> SubClass.fields
{'param1': 1}
>>> SubSubClass.fields
{'param1': 1}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With