为什么我可以在Python中调用抽象类方法?
如果使用抽象方法定义抽象类:为什么我可以在Python中调用抽象类方法?,python,Python,如果使用抽象方法定义抽象类: import abc class A(abc.ABC): @classmethod @abc.abstractmethod def foo(cls): pass 我无法实例化它(如预期的那样): 但是我可以毫无错误地调用它的抽象方法 >> A.foo() 这种行为是否有记录 在Python 3.6和3.7上测试。foo是一种classmethod,通过类方法可以由类本身直接调用。 通过做 In [3]:
import abc
class A(abc.ABC):
@classmethod
@abc.abstractmethod
def foo(cls):
pass
我无法实例化它(如预期的那样):
但是我可以毫无错误地调用它的抽象方法
>> A.foo()
这种行为是否有记录
在Python 3.6和3.7上测试。
foo
是一种classmethod
,通过类方法可以由类本身直接调用。通过做
In [3]: A.foo()
您并不是在实例化类
A
,而是在类A上调用函数foo
简单地说,abstractmethod
decorator的文档说明:
具有从ABCMeta派生的元类的类无法实例化,除非其所有抽象方法和属性都被重写
政治公众人物3119说:
无法实例化至少包含一个使用此装饰器声明的方法但尚未重写的类
后来
实现:@abstractmethod
装饰器将函数属性\uuuu isastractmethod\uuuu
的值设置为True。ABCMeta.\uuuuu new\uuuuuu
方法将类型属性\uuuuuu abstractmethods\uuuuuu
计算为具有值为true的\uuuuu isabstractmethod\uuuuu
属性的所有方法名称的集合。它通过组合基类的\uuuu abstractmethods\uuuuuuuuuuu
属性,添加新类dict中所有具有true\uuuuuu isabstractmethod\uuuuuuuu
属性的方法的名称,并删除新类dict中所有不具有true\uuuuu isabstractmethod\uuuuuuuuu
属性的方法的名称来实现。如果生成的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
我对实现部分的解释是,@abstractmethod
从不阻止调用该方法,而是说该类不能实例化,并且子类仍然是抽象的,除非它重写其所有抽象方法
所以我不会说这是出于设计,但至少是一种假定的副作用。子类化abc。abc
表示类A
不能直接实例化
@abc.abstractmethod
装饰程序在类型/名称解析期间强制检查a
的任何子类。如果类subofA(A):
未实现修饰方法,则引发异常
一旦传递了类型/名称解析,abstractmethod装饰器不会阻止您调用该方法。毕竟,如果没有实例,就无法调用该方法,除非它是类方法
通过同时使用@classmethod
和@abstractmethod
装饰foo
,开发人员可以指定A.foo()
可以安全调用,而无需实例化类,但是,对A
进行子类化的任何人都必须实现一个覆盖方法来保持这种行为。官方python文档ABC:docs.python.org/3/library/ABC.html信息:www.python-course.eu/python3_abstract_classes.php
In [3]: A.foo()