没有抽象方法的抽象类在python中创建对象 [英] abstract classes without abstract methods creating objects in python

查看:154
本文介绍了没有抽象方法的抽象类在python中创建对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我知道抽象基类与常规类一样被用作骨架类,但是强制抽象方法应由子类/继承的类覆盖,如果子类/继承类如下所示

Basically, I knew that abstract base classes are used as skeleton classes just like regular classes, but enforces that abstract methods should be overridden by the child/inherited classes if it has one like below

Class AbstractClass(object):
    __metaclass__ = abc.ABCMeta

    @abstractmethod
    def absmethod(self):
        pass

class ChildClass(AbstractClass):
    def absmethod(self):
        print "Yeah!"

obj = ChildClass()

因此我们可以创建 ChildClass 如上

我们知道我们不能实例化一个抽象类,因为它只是骨架,我们将如果尝试按以下方式实例化,则会出现错误

We know we can't instantiate an abstract class as it meant to be just skeleton and we will get an error if we try to instantiate it as below

obj = AbstractClass()

*** TypeError: Can't instantiate abstract class AbstractClass with abstract methods absmethod

实例化抽象类AbstractClass,但是我实际关于发布的查询是什么这个 StackOverflow 是如果我们使用 abc.ABCMeta 创建一个抽象类,而没有抽象方法,我可以创建一个抽象类的实例,不应该是这种情况(如果我错了,请纠正我)

But what my actual query about posting this StackOverflow is if we create an abstract class by using abc.ABCMeta, without abstract methods, I can able to create an instance of the abstract class which should not be the case(correct me if I am wrong)

Class AbstractClass(object):
    __metaclass__ = abc.ABCMeta

obj = AbstractClass()

OOOPPPSS ,我们实际上可以创建一个抽象类的对象没有抽象方法?因此,请让我知道其背后的关键点

OOOPPPSS it worked, we can actually create an object of abstract classes without abstract methods? So please let me know the key points behind this

推荐答案

来自文档


A类具有从 ABCMeta 派生的元类的实例不能被
实例化,除非其所有抽象方法和属性都被
覆盖。

A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.

相反,这意味着任何没有抽象方法或属性(例如您的 AbstractClass )的类都可以

Conversely, this means that any class with no abstract methods or properties like your AbstractClass can be instantiated.

如果要禁止实例化最顶层的父类,则可以编写一个自定义类在其 __ new __ 方法:

If you want to disallow instantiation of the topmost parent class, you can write a custom class that performs a type check in its __new__ method:

class SubclassOnlyABC(object):
    __metaclass__ = abc.ABCMeta

    def __new__(cls, *args, **kwargs):
        if cls.__bases__ == (SubclassOnlyABC,):
            msg = 'Abstract class {} cannot be instantiated'.format(cls.__name__)
            raise TypeError(msg)

        return super(SubclassOnlyABC, cls).__new__(cls, *args, **kwargs)





class AbstractClass(SubclassOnlyABC):
    pass

class ChildClass(AbstractClass):
    pass

ChildClass()  # works because it's a child class of an abstract class
AbstractClass()  # throws TypeError because its parent class is "object"






您也可以编写 __new __ 方法,该方法可防止不使用抽象方法实例化类:


You can also write a __new__ method that prevents instantiation of classes with no abstract methods:

class NonEmptyABC(object):
    __metaclass__ = abc.ABCMeta

    def __new__(cls, *args, **kwargs):
        # check if ANY abstractmethod exists
        for parentcls in cls.__mro__:
            if any(getattr(attr, '__isabstractmethod__', False)
                               for attr in vars(parentcls).values()):
                break
        else:
            msg = 'Abstract class {} cannot be instantiated'.format(cls.__name__)
            raise TypeError(msg)

        return super(NonEmptyABC, cls).__new__(cls, *args, **kwargs)





class EmptyAbstractClass(NonEmptyABC):
    pass

class NonemptyAbstractClass(NonEmptyABC):
    @abc.abstractmethod
    def foo(self):
        pass

class NonemptyChild(NonemptyAbstractClass):
    def foo(self):
        pass

NonemptyChild()  # works because "foo" is an abstractmethod
EmptyAbstractClass()  # throws TypeError because there are no abstractmethods

这篇关于没有抽象方法的抽象类在python中创建对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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