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()
我的问题是,我可以强制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()
答案 0 :(得分:2)
我认为需要做一些澄清;
首先,在Python中,每个方法都是虚拟的 - 真的是虚拟的;所以无论方法是静态的,还是绑定到类或实例,都是子类的问题,而不是父类的问题。你没有真正的理由想要阻止它 - 你的目的是什么?
其次,ABCs在实例化时检查抽象性 - 如果你尝试实例化仍然有任何抽象方法的类,则会引发错误。但是ABCs不能对从类本身调用的静态或类方法做任何事情 - 对方法本身执行NO CHECK,只是在方法上设置的属性 - 它是ABCMeta,它在类实例化时执行脏工作。
第三,abstractstatic方法的目的是允许一个抽象方法 - 因此必须仍然被子类覆盖的东西 - 是静态的并且可以从任何地方使用 - 再次,对方法本身没有检查,所以以下代码是完全合法的:
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())
abstractstaticmethod / abstractclassmethod存在的唯一原因是以下方法不起作用,因为装饰方法缺少 dict
class NotWorking(metaclass=abc.ABCMeta):
@abc.abstractmethod
@staticmethod
def some_method(self):
return "asd"
最后一件事: 如果你真的想要,你可以通过扩展ABCMeta来增加这样的功能,但是除非你告诉我你为什么要这样做,否则我不会给你如何做到这一点: - )