简单理解 Python __init_subclass__ 的使用

官方文档 object.__init_subclass__
python - Understanding __init_subclass__ - Stack Overflow

三个简单示例

class Origin():
    _register=[]
    
    def __init_subclass__(cls):
        print("hello from Origin")
        cls._register.append(cls.__name__)

class Sub(Origin):
    pass

class Subsub(Sub):
    pass

class Subsub(Subsub):
    pass

print(Origin._register)
"""
hello from Origin
hello from Origin
hello from Origin
['Sub', 'Subsub', 'Subsub']
"""

__init_subclass__ 在被子类继承并定义后执行,这里可以通过 _register 记录所有 Origin 的子类。

class Origin():
    _register=[]
    
    def __init_subclass__(cls):
        print("hello hello from Origin")
        cls._register.append(cls.__name__)

class Sub(Origin):
    def __init_subclass__(cls):
        print("hello from Sub")
        cls._register.append(cls.__name__)

class Subsub(Sub):
    def __init_subclass__(cls):
        print("hello from Subsub")
        cls._register.append(cls.__name__+" :) ")

class Subsubsub(Subsub):
    def __init_subclass__(cls):
        print("hello from Subsubsub")
        cls._register.append(cls.__name__+" :| ")

print(Origin._register)
"""
hello hello from Origin
hello from Sub
hello from Subsub
['Sub', 'Subsub', 'Subsubsub :) ']
"""

当子类定义 __init_subclass__ 时,父类的方法被屏蔽。

class Origin():
    _register=[]
    
    def __init_subclass__(cls):
        print("hello hello from Origin")
        cls._register.append(cls.__name__+"from origin")
        print("==========")
        

class Sub(Origin):
    def __init_subclass__(cls):
        print("hello from Sub")
        super().__init_subclass__()
        print("==========")

class Subsub(Sub):
    def __init_subclass__(cls):
        print("hello from Subsub")
        super().__init_subclass__()
        print("==========")

class Subsubsub(Subsub):
    def __init_subclass__(cls):
        print("hello from Subsubsub")
        super().__init_subclass__()
        print("==========")

print(Origin._register)
"""
hello hello from Origin
==========
hello from Sub
hello hello from Origin
==========
==========
hello from Subsub
hello from Sub
hello hello from Origin
==========
==========
==========
['Subfrom origin', 'Subsubfrom origin', 'Subsubsubfrom origin']
"""

使用 super().__init_subclass__() 调用父类的方法。

参考 pyTelegramBotAPI 中的例子

class State:
    """
    Class representing a state.

    .. code-block:: python3

        class MyStates(StatesGroup):
            my_state = State() # returns my_state:State string.
    """
    def __init__(self) -> None:
        self.name = None
    def __str__(self) -> str:
        return self.name

class StatesGroup:
    """
    Class representing common states.

    .. code-block:: python3

        class MyStates(StatesGroup):
            my_state = State() # returns my_state:State string.
    """
    def __init_subclass__(cls) -> None:
        state_list = []
        for name, value in cls.__dict__.items():
            if not name.startswith('__') and not callable(value) and isinstance(value, State):
                # change value of that variable
                value.name = ':'.join((cls.__name__, name))
                value.group = cls
                state_list.append(value)
        cls._state_list = state_list

    @property
    def state_list(self):
        return self._state_list
posted @ 2023-08-10 10:35  BuckyI  阅读(55)  评论(0编辑  收藏  举报