模仿Python(纯)虚函数,像c#一样

本文关键字:一样 函数 Python 模仿 | 更新日期: 2023-09-27 18:18:27

在Python中模仿c#中的虚函数和纯虚函数的最佳方式是什么?

目前我使用的模式如下:

class AbstractClass(object):
    '''Abstract class'''
    def __init__(self):
        assert False, 'Class cannot be instantiated'
    def _virtual_init(self):
        print 'Base "constructor"'
    def pure_virtual_function(self):
        assert False, 'Pure virtual function should be derived'
    def virtual_function(self):
        print 'Base: virtual function'
class Derived1(AbstractClass):
    '''All functions derived'''
    def __init__(self):
        print 'Derived1: constructor'
        AbstractClass._virtual_init(self)
    def pure_virtual_function(self):
        print 'Derived1: pure virtual function'
    def virtual_function(self):
        print 'Derived1: virtual function'
class Derived2(AbstractClass):
    '''Pure virtual method missing.'''
    def __init__(self):
        print 'Derived2: constructor'
        AbstractClass._virtual_init(self)
    def virtual_function(self):
        print 'Derived3: virtual function'
class Derived3(AbstractClass):
    '''Virtual method missing (use base class)'''
    def __init__(self):
        print 'Derived3: constructor'
        AbstractClass._virtual_init(self)
    def pure_virtual_function(self):
        print 'Derived3: pure virtual function'

# ab = AbstractClass() # Gives error -> OK
print 'DERIVED 1'    
dv1 = Derived1()
dv1.pure_virtual_function()
dv1.virtual_function()
print 'DERIVED 2'    
dv2 = Derived2()
# dv2.pure_virtual_function() # Gives error: Pure virtual function should be derived -> OK
dv2.virtual_function()
print 'DERIVED 3'    
dv3 = Derived3()
# dv3.pure_virtual_function() # Gives error: Pure virtual function should be derived -> OK
dv3.virtual_function()

我得到如下输出:

DERIVED 1
Derived1: constructor
Base "constructor"
Derived1: pure virtual function
Derived1: virtual function
DERIVED 2
Derived2: constructor
Base "constructor"
Derived3: virtual function
DERIVED 3
Derived3: constructor
Base "constructor"
Derived3: pure virtual function
Base: virtual function

但是我的具体问题是:

    在Python(2.7)中是否有更优雅的方式来定义抽象基类?上面的解决方案只在运行时给出错误(例如pylint)Python中没有抽象关键字。在Python(2.7)中是否有更优雅的方式来定义纯虚方法?同样,上面的解决方案只在运行时给出一个错误。在Python(2.7)中是否有更优雅的方法来定义虚方法?不需要检查,但是Python中没有像'virtual'这样的关键字。

模仿Python(纯)虚函数,像c#一样

我不确定你问虚方法到底是什么意思,因为在Python中所有的方法都是虚的。我也不知道你为什么用_virtual_init而不是__init__…简单地重命名一个方法能给你带来什么吗?

更新:啊,我有个主意。这样做可能是为了禁止基类的实例化,但仍保留了基类的初始化功能。这里的答案是:强迫事物不是python的。只要证明这个类是抽象的(可能叫它AbstractSmth)。

关于运行时错误。Python是一种动态语言,所以,这就是它的工作方式。一个常见的习惯用法是在__init__中增加NotImplementedError以表明您的类是抽象的(对于抽象(纯虚拟)方法也是如此)。你也可以看看abc,因为它做了你想要的:它禁止抽象类的实例化。但是我也强烈建议阅读PEP-3119来理解什么是抽象基类以及它们不是

AFAIK,提高NotImplementedError足以让pylint理解你的类/方法是抽象的。

class AbstractBaseClass(object):
    def __init__(self):
        if self.__class__.__name__ == 'AbstractBaseClass':
            raise NotImplementedError("Can't instantiate AbstractBaseClass")
class DerivedClass(AbstractBaseClass):
    def __init__(self):
        super().__init__()
        # ...

这个例子显示了派生类(具有不同的__class__.__name__成员)可以被实例化,并继承AbstractBaseClass提供的属性。但是如果AbstractBaseClass被直接实例化,则会抛出NotImplementedError异常。