How to write a function that prints out all attributes of a class with types?
class Parent:
parent_param: str
parent_default: str | None = None
def find_params_meta(self):
...
# enter magic code, filter out methods and attributes starting with `"_"`
class Child(Parent):
child_param: str
_params_meta: dict[str, Any] | None = None
def __init__(self, parent_param: str, child_param: str):
self._params_meta = self.find_params_meta()
self.child_param = child_param
self.parent_param = parent_param
assert Child("parent param", "child param")._params_meta == {
"parent_param": {"types": [str]},
"parent_default": {"types": [str, None], "default": None},
"child_param": {"types": [str]},
}
The parent_param
and child_param
attributes are not instantiated.
getattr(self, "parent_param")
raises the AttributeError: 'Child' object has no attribute 'parent_param'
. type(self).__dict__
, dir(self)
or inspect.getmembers(self)
are not printing them. inspect.get_annotations(type(self))
is closer as it prints {'child_param': <class 'str'>, ...}
, but it does not return Parent
's attributes.
Building on the code you posted:
class Parent:
...
@classmethod
def find_params_meta(cls):
return {
k: v
for c in reversed(cls.__mro__)
for k, v in inspect.get_annotations(c).items()
}
Edit: added reversed
since you probably want to give preference to types set on child classes... though it is probably not valid to override the type for a child class (Liskov Substitution Principle)