Is it possible to access the parent class name within a static class? For example, how to I print the parent class name in the bar
method below?
class Static:
def bar(self):
parent_name = ???
print(parent_name)
class A:
object = Static()
def foo(self):
A.object.bar()
class B:
object = Static()
def foo(self):
B.object.bar()
A().foo()
B().foo()
You're looking for the __set_name__
method.
It is called on every static attribute of a class when the class is finished constructing. One of the parameters is the "owner" class (A or B), so all you need is to store that reference. Note that this requires a separate Static instance for each parent class, but you're doing that already.
class Static:
def bar(self):
print(self.parent_name)
def __set_name__(self, owner, name):
self.parent_name = owner.__name__
class A:
object = Static()
def foo(self):
A.object.bar()
class B:
object = Static()
def foo(self):
B.object.bar()
A().foo()
B().foo()
I personally avoid these magic methods when possible, so you might also consider taking @JonSG's advice and put the owner class in the Static
constructor instead. This way the relationship is much clearer, at the cost of adding them after-the-fact.
class Static:
def __init__(self, owner):
self.parent_name = owner.__name__
def bar(self):
print(self.parent_name)
class A:
def foo(self):
A.object.bar()
A.object = Static(A)
class B:
def foo(self):
B.object.bar()
B.object = Static(B)
A().foo()
B().foo()
Alternatively, one might leverage a metaclass
to do some of the work. This has the potential to also simplify the implementations of A()
and B()
class Static:
def __init__(self, parent_name) -> None:
self.parent_name = parent_name
def bar(self):
print(self.parent_name)
class AB_Meta(type):
def __init__(cls, name, bases, dct):
cls.object = Static(name)
class A(metaclass=AB_Meta):
def foo(self):
A.object.bar()
class B(metaclass=AB_Meta):
def foo(self):
B.object.bar()
A().foo()
B().foo()
Should give you:
A
B