我最终升级了python版本,发现了新增加的特性。除此之外,我还在为新的^{
This method is called whenever the containing class is subclassed. cls is then the new subclass. If defined as a normal instance method, this method is implicitly converted to a class method.
因此,我开始按照文档中的示例来处理它:
class Philosopher:
def __init_subclass__(cls, default_name, **kwargs):
super().__init_subclass__(**kwargs)
print(f"Called __init_subclass({cls}, {default_name})")
cls.default_name = default_name
class AustralianPhilosopher(Philosopher, default_name="Bruce"):
pass
class GermanPhilosopher(Philosopher, default_name="Nietzsche"):
default_name = "Hegel"
print("Set name to Hegel")
Bruce = AustralianPhilosopher()
Mistery = GermanPhilosopher()
print(Bruce.default_name)
print(Mistery.default_name)
生成此输出:
Called __init_subclass(<class '__main__.AustralianPhilosopher'>, 'Bruce')
'Set name to Hegel'
Called __init_subclass(<class '__main__.GermanPhilosopher'>, 'Nietzsche')
'Bruce'
'Nietzsche'
我知道这个方法在子类定义之后被称为,但是我的问题是关于这个特性的使用。我也读过PEP 487这篇文章,但没给我多少帮助。这种方法有什么帮助?是为了:
另外,我需要理解^{
__init_subclass__
和__set_name__
是正交的机制-它们不是相互联系的,只是在同一个PEP中描述的。这两个特性以前都需要一个功能齐全的元类。PEP 487解决了元类最常用的2问题:__init_subclass__
)__set_name__
)正如政治公众人物所说:
注意,虽然
__init_subclass__
是在中使用元类的替换,但这个类的继承树中,__set_name__
是在描述符类中使用元类的替换,该类具有描述符的实例作为属性。PEP 487提出了两个常见的元类用例,使它们更容易访问,而不必了解元类的所有内部和外部。这两个新特性
__init_subclass__
和__set_name__
在其他方面是独立的,它们不相互依赖。__init_subclass__
只是一个钩子方法。你想用它做什么都行。对于以某种方式注册子类,和对于在这些子类上设置默认属性值都很有用。我们最近使用它为不同的版本控制系统提供“适配器”,例如:
这使得我们可以为特定的存储库定义处理程序类,而不必使用元类或装饰器。
正如PEP的标题所示,
__init_subclass__
的主要目的是为类提供一种更简单的定制形式。它是一个钩子,允许你在不需要了解元类、跟踪类构造的所有方面或担心元类冲突的情况下修改类。正如Nick Coghlan在本政治公众人物早期阶段所说:
元类之所以被认为是神奇的,是因为你不知道在创建类之后它们的效果会是什么。
__init_subclass__
另一方面,它只是另一个类方法,它只运行一次,然后就完成了。(see its documentation for exact functionality.)PEP 487的整个要点是为了一些常见的用途简化(即不需要使用)元类。
__init_subclass__
负责类后初始化,同时添加__set_name__
(这只对描述符类有意义)以简化描述符的初始化。除此之外,他们没有亲戚关系。第三种常见的元类情况(保持定义顺序)是was also simplified。这是通过使用命名空间的有序映射(在Python3.6中是一个
dict
,但这是一个实现细节:-)相关问题 更多 >
编程相关推荐