“不能实例化抽象类……使用抽象方法"在不应该有任何抽象方法的类上 [英] “Can't instantiate abstract class … with abstract methods” on class that shouldn't have any abstract method
问题描述
以以下最小示例为例:
import abc
class FooClass(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def FooMethod(self):
raise NotImplementedError()
def main():
derived_type = type('Derived', (FooClass,), {})
def BarOverride(self):
print 'Hello, world!'
derived_type.FooMethod = BarOverride
instance = derived_type()
运行 main()
让你:
TypeError: Can't instantiate abstract class Derived with abstract methods FooMethod
(异常发生在 instance =derived_type()
行.)
(The exception occurs on the instance = derived_type()
line.)
但是FooMethod
不应该是抽象的:我已经用BarOverride
覆盖了它.那么,为什么这会引发异常?
But FooMethod
shouldn't be abstract: I've overridden it with BarOverride
. So, why is this raising exceptions?
免责声明: 是的,我可以使用显式的 class
语法,并完成完全相同的事情.(更好的是,我可以让它工作!)但这是一个最小的测试用例,更大的例子是动态创建类.:-) 我很好奇为什么这不起作用.
Disclaimer: Yes, I could use the explicit class
syntax, and accomplish the exact same thing. (And even better, I can make it work!) But this is a minimal test case, and the larger example is dynamically creating classes. :-) And I'm curious as to why this doesn't work.
并防止其他明显的非答案:我不想将 BarOverride
在第三个参数中传递给 type
: 在实际例子中,BarOverride
需要绑定 derived_type
.如果我可以在创建 derived_type
之后定义 BarOverride
,这样做会更容易.(如果我做不到,那为什么?)
And to prevent the other obvious non-answer: I don't want to pass BarOverride
in the third argument to type
: In the real example, BarOverride
needs to have derived_type
bound to it. It is easier to do this if I can define BarOverride
after the creation of derived_type
. (If I can't do this, then why?)
推荐答案
动态地向类添加抽象方法,或尝试添加抽象方法创建方法或类后,修改其抽象状态,不支持.abstractmethod() 只影响子类使用常规继承派生;虚拟子类"注册ABC 的 register() 方法不受影响.
Dynamically adding abstract methods to a class, or attempting to modify the abstraction status of a method or class once it is created, are not supported. The abstractmethod() only affects subclasses derived using regular inheritance; "virtual subclasses" registered with the ABC’s register() method are not affected.
元类仅在定义类时调用.当 abstractmethod
将一个类标记为抽象时,该状态以后不会改变.
A metaclass is only called when a class is defined. When abstractmethod
has marked a class as abstract that status won't change later.
这篇关于“不能实例化抽象类……使用抽象方法"在不应该有任何抽象方法的类上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!