什么是__init_subclass__
class Hook:
def __init_subclass__(cls, **kwargs):
print("__init_subclass__", cls, kwargs)
class A(Hook, name="satori", age=16):
pass
"""
__init_subclass__ <class '__main__.A'> {'name': 'satori', 'age': 16}
"""
首先我們定義了一個Hook類,然后讓A這個類繼承它。發現我們還沒有沒有實例化,而是在創建類的時候就有輸出結果了。
對於一個類,如果這個類被作為父類繼承,那么會觸發其內部的__init_subclass__方法,這里的Hook被A繼承,那么Hook中的__init_subclass__就會被觸發。而且看到,里面的cls,就是我們的A,也就是繼承它的類,**kwargs,就是我們額外傳遞的參數。
但是我們發現,第一個參數不是self,而是cls,而且這個cls還不是我們的Hook,而是繼承它的類。其實這個方法是隱式的被classmethod裝飾了
用法
有時候我們想控制類的生成過程,怎么辦呢?顯然可以通過元類的的方式,但是如果場景比較簡單,也沒必要使用元類。直接使用__init_subclass__即可
class Hook:
def __init_subclass__(cls, **kwargs):
for k, v in kwargs.items():
type.__setattr__(cls, k, v)
class A(Hook, name="satori", age=16):
pass
print(A.name) # satori
print(A.age) # 16
可以看到,我們在不使用元類的情況下,通過__init_subclass__實現了類的自定義過程。當然這比較簡單,也可以實現更復雜的邏輯,在某些場景下,可以替代元類。