Imagine a parent class which has a mangled attribute, and a child class:
class Foo:
def __init__(self):
self.__is_init = False
async def init(self):
# Some custom logic here, not important
self.__is_init = True
class Bar(Foo):
...
# Create class instance.
bar = Bar()
# How access `__is_init` of the parent class from the child instance?
How can I get a __is_init
value from a parent (Foo
) class?
Obviously, I can bar._Foo__is_init
in this example, but the problem is that class name is dynamic and I need a general purpose solution that will work with any passed class name.
CodePudding user response:
The solution I see now is iterating over parent classes, and building a mangled attribute name dynamically:
from contextlib import suppress
class MangledAttributeError(Exception):
...
def getattr_mangled(object_: object, name: str) -> str:
for cls_ in getattr(object_, "__mro__", None) or object_.__class__.__mro__:
with suppress(AttributeError):
return getattr(object_, f"_{cls_.__name__}{name}")
raise MangledAttributeError(f"{type(object_).__name__} object has no attribute '{name}'")
Checking that this works:
class Foo:
def __init__(self):
self.__is_init = False
async def init(self):
self.__is_init = True
class Bar(Foo):
def __init__(self):
super().__init__()
bar = Bar()
is_init = getattr_mangled(bar, "__is_init")
print(f"is_init: {is_init}") # Will print `False` which is a correct value in this example
CodePudding user response:
class Foo:
def __init__(self):
self.__is_init = False
async def init(self):
self.__is_init = True
class Bar(Foo):
def getattr_mangled(self, attr:str):
for i in self.__dict__.keys():
if attr in i:
return getattr(self,i)
# return self.__dict__[i] #or like this
bar = Bar()
print(bar.getattr_mangled('__is_init')) #False
if there is a need in __init__
in Bar we should of course initiate Foo
's init too by: super().__init__()
When Foo
's init is run, self namespace already has attribute name we need in the form we need it (like_PARENT_CLASS_NAME__attrname
).
And we can just get it from self namespace without even knowing what parent class name is.