抽象类可以强制继承类将方法实现为静态吗?

Mat*_*und 8 python abstract-class

Python 3.2以防万一...

以下代码显示"具体类"可以将some_method实现为静态方法或实例方法:

import abc

class SomeAbstractClass(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def some_method(self): pass

class ValidConcreteClass1(SomeAbstractClass):

    @staticmethod
    def some_method():
        print("foo!")

class ValidConcreteClass2(SomeAbstractClass):

    def some_method(self):
        print("foo!")

ValidConcreteClass1.some_method()

instance = ValidConcreteClass2()
instance.some_method()
Run Code Online (Sandbox Code Playgroud)

我的问题是,我可以强制some_method的实现在继承类中是静态的吗?

我注意到了@ abc.abstractstaticmethod,并认为这是答案,但以下代码仍然可以正常运行.我认为它会拒绝ValidConreteClass2,因为some_method不是静态的:

import abc

class SomeAbstractClass(metaclass=abc.ABCMeta):

    @abc.abstractstaticmethod
    def some_method(self): pass

class ValidConcreteClass1(SomeAbstractClass):

    @staticmethod
    def some_method():
        print("foo!")

class ValidConcreteClass2(SomeAbstractClass):

    def some_method(self):
        print("foo!")

ValidConcreteClass1.some_method()

instance = ValidConcreteClass2()
instance.some_method()
Run Code Online (Sandbox Code Playgroud)

Ala*_*oni 3

我认为有必要进行一些澄清;

首先,在 Python 中,每个方法都是虚拟的——真正的虚拟;因此,无论方法是静态的,还是绑定到类或实例,这都是子类的问题,而不是父类的问题。你没有真正的理由想要阻止这种情况——你的目的是什么?

其次,ABC 在实例化时检查抽象性 - 如果您尝试实例化仍然具有任何抽象方法的类,则会引发错误。但是 ABC 不能对从类本身调用的静态或类方法执行任何操作 - 不会对方法本身执行任何检查,只是在方法上设置属性 - 当类实例化时,ABCMeta 会做一些肮脏的工作。

第三,abstractstaticmethod的目的是允许抽象方法 - 因此仍然必须由子类以某种方式重写的东西 - 是静态的并可以从任何地方使用 - 再次,没有对方法本身进行检查,所以下面的代码是完美的合法的:

import abc

class SomeAbstractClass(metaclass=abc.ABCMeta):

    @abc.abstractstaticmethod
    def some_method(): 
        return 123

class ValidConcreteClass1(SomeAbstractClass):

    def some_method(self):
        return 456

inst = ValidConcreteClass1()
print(inst.some_method())
print(SomeAbstractClass.some_method())
Run Code Online (Sandbox Code Playgroud)

Abstractstaticmethod/abstractclassmethod 存在的唯一原因是以下内容不起作用,因为装饰方法缺少字典

class NotWorking(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    @staticmethod
    def some_method(self):
        return "asd"
Run Code Online (Sandbox Code Playgroud)

最后一件事:如果您真的愿意,您可能可以通过扩展 ABCMeta 来添加此类功能,但我不会告诉您如何执行此操作,除非您告诉我为什么这样做:-)