Reputation: 548
I'm using init_subclass in a project, and I sort of balked when I ran into the built in method kicking off when the code first runs in the interpreter -- without being directly referenced via instantiation of the containing class or the sub-classes it enumerates.
Can someone tell me what's going on, and point me to any examples of its safe use?
class Timer():
def __init__(self):
pass
def __init_subclass__(cls):
print('Runner.', cls)
print('Timer Dictionary :', Timer.__dict__.keys())
# print(Timer.__init_subclass__()) # Forbidden fruit...
pass
class Event(Timer):
print("I'll take my own bathroom selfies...thanks anyway.")
def __init__(self):
print('This is nice, meeting on a real date.')
if __name__ == '__main__': # a good place for a breakpoint
date = Event()
date
Edit --------------------------------------------------
Based on the explanations received, original code was retooled into something useful.
class Timer():
subclasses = {}
def __init__(self):
pass
def __init_subclass__(cls, **kwargs):
print('Runner.', cls)
print('Timer Dictionary :', Timer.__dict__.keys())
# print(Timer.__init_subclass__()) # Forbidden fruit...
super().__init_subclass__(**kwargs)
cls.subclasses[cls] = []
class Event(Timer):
print("I'll take my own bathroom selfies...thanks anyway.")
def __init__(self):
print('This is nice, meeting on a real date.')
if self.__class__ in super().subclasses:
# get the index and link the two
super().subclasses[self.__class__].append(self)
if __name__ == '__main__': # a good place for a breakpoint
date = Event()
date
duty = Event()
duty
print(Timer.subclasses)
Upvotes: 1
Views: 2475
Reputation: 4710
Here's a minimal example:
class Super():
def __init_subclass__(cls):
print(cls)
class Sub(Super):
pass
Running this:
$ python test.py
<class '__main__.Sub'>
Why is that? According to Python's data model docs:
Whenever a class inherits from another class, init_subclass is called on that class.
Sub
inherits from Super
, so Super.__init_subclass__()
gets called.
Specifically, type_new()
invokes init_subclass in the cpython
implementation.
The rationale is detailed in PEP 487.
Upvotes: 6