不应使用任何抽象方法的类上的“无法实例化抽象类……使用抽象方法” [英] “Can't instantiate abstract class … with abstract methods” on class that shouldn't have any abstract method

查看:100
本文介绍了不应使用任何抽象方法的类上的“无法实例化抽象类……使用抽象方法”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下面的最小示例为例:

Take the following minimal example:

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

(该异常发生在实例上=派生类型()行。)

但是 FooMethod 不应抽象:我已经用 BarOverride 覆盖了它。那么,为什么会引发异常呢?

But FooMethod shouldn't be abstract: I've overridden it with BarOverride. So, why is this raising exceptions?

免责声明:是的,我可以使用显式的语法,并完成完全相同的操作。 (甚至更好,我可以使它工作!)但这是一个最小的测试用例,而更大的示例是动态创建类。 :-)我很好奇为什么这行不通。

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.

仅当以下情况调用元类时:类已定义。当抽象方法将类标记为抽象时,状态以后将不会更改。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆