1. 介绍
在Python 3.6及以上版本中,__init_subclass__方法被引入,它允许在创建子类时调用基类的__init_subclass__方法。这个方法允许您将定义在基类中的行为呈现出来,而无需在每个子类中人工添加它。
2. __init_subclass__方法的语法
class BaseClass:
def __init_subclass__(cls):
pass
2.1 参数说明
注意,__init_subclass__方法中有一个自动创建的cls参数。这个参数是子类的引用,它可以用来调用基类中的方法或属性。有时它会在__init_subclass__方法中使用,以利用特性注解或其他自定义元数据。
2.2 示例
这里有一个示例,演示了如何编写一个繁荣的__init_subclass__方法。在这里,我们使用一个修改__init__方法的装饰器来将一些自动行为添加到所有子类中:
class MyBaseClass:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.my_var = 42
cls.my_list = [1, 2, 3]
def test_mbc():
class MyChildClass(MyBaseClass):
pass
assert MyChildClass.my_var == 42
assert MyChildClass.my_list == [1, 2, 3]
在这个示例中,我们创建了一个名为MyBaseClass的基类,它包含一个定义良好的__init_subclass__方法。这个方法将添加两个新属性到我们最终的子类中。
在创建一个子类时,我们只需从MyBaseClass中继承即可。在继承的过程中,__init_subclass__方法会自动执行。这样,我们不必为每个新的子类手动添加任何新行为。返回的子类会自动获得定义在其基类中的特定属性。
3. __init_subclass__ 与元类
在Python 3中,元类被广泛使用,而__init_subclass__方法可以用作所有元类的替代品。在元类中添加行为时,我们也可以在子类上自动执行功能。
3. 1 示例:
在这里,我们定义一个元类,它为任何子类自动添加一些额外的方法。首先,我们定义了一个带有类装饰器的基类(MyBaseClass),并将元类设置为带有__init_subclass__方法的自定义元类Meta1:
class Meta1(type):
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.hello = lambda self: print('hello from', self)
class MyBaseClass(metaclass=Meta1):
pass
def test_m1():
class MyChildClass(MyBaseClass):
pass
try:
MyChildClass().hello()
except AttributeError as ex:
assert str(ex) == "'MyChildClass' object has no attribute 'hello'"
在这个示例中,我们首先定义了元类Meta1。它有一个定义良好的__init_subclass__方法,该方法将一个新方法 hello 添加到所有子类中。然后,我们定义了一个MyBaseClass基类,该基类使用刚刚定义的元类。如果我们现在创建一个MyChildClass子类,并将其归入MyBaseClass中,则此子类将自动具有hello方法,并可以在创建实例时进行调用。
4. 总结
__init_subclass__方法是一个很棒的Python特性,它允许在创建子类时调用基类的方法。这样,我们就可以为从基类继承的所有子类添加某些特定行为,而不必在子类中人工添加它。由于Python强大的元编程功能,我们可以将其和元类一起使用,从而使以一种极其灵活的方式添加行为成为可能。