在Python中,如何在子类上强制抽象方法是静态的?
这是我想要的设置: A应该是具有静态和抽象方法f()的抽象基类。B应继承A.要求: 1.您不应该能够实例化 2.您应该不能实例化B,除非它实现了静态f() 从这个问题中得到启发,我尝试了几种方法。根据这些定义:在Python中,如何在子类上强制抽象方法是静态的?,python,abstract-class,static-methods,abc,Python,Abstract Class,Static Methods,Abc,这是我想要的设置: A应该是具有静态和抽象方法f()的抽象基类。B应继承A.要求: 1.您不应该能够实例化 2.您应该不能实例化B,除非它实现了静态f() 从这个问题中得到启发,我尝试了几种方法。根据这些定义: class abstractstatic(staticmethod): __slots__ = () def __init__(self, function): super(abstractstatic, self).__init__(function)
class abstractstatic(staticmethod):
__slots__ = ()
def __init__(self, function):
super(abstractstatic, self).__init__(function)
function.__isabstractmethod__ = True
__isabstractmethod__ = True
class A:
__metaclass__ = abc.ABCMeta
@abstractstatic
def f():
pass
class B(A):
def f(self):
print 'f'
class A2:
__metaclass__ = abc.ABCMeta
@staticmethod
@abc.abstractmethod
def f():
pass
class B2(A2):
def f(self):
print 'f'
这里A2和B2是使用常见的Python约定定义的,A&B是使用答案中建议的方式定义的。以下是我尝试过的一些操作和不期望的结果
A/B类:
>>> B().f()
f
#This should have thrown, since B doesn't implement a static f()
对于A2/B2类:
>>> A2()
<__main__.A2 object at 0x105beea90>
#This should have thrown since A2 should be an uninstantiable abstract class
>>> B2().f()
f
#This should have thrown, since B2 doesn't implement a static f()
>>A2()
#由于A2应该是一个不可实例化的抽象类,因此应该引发此错误
>>>B2().f()
F
#这应该抛出,因为B2没有实现静态f()
既然这两种方法都没有给我想要的输出,我该如何实现我想要的呢?你不能用
ABCMeta
做你想做的事。ABC强制执行不执行任何类型检查,只强制执行具有正确名称的属性的存在
例如:
>>> from abc import ABCMeta, abstractmethod, abstractproperty
>>> class Abstract(object):
... __metaclass__ = ABCMeta
... @abstractmethod
... def foo(self): pass
... @abstractproperty
... def bar(self): pass
...
>>> class Concrete(Abstract):
... foo = 'bar'
... bar = 'baz'
...
>>> Concrete()
<__main__.Concrete object at 0x104b4df90>
使用此元类,您可以获得预期的输出:
>>> class Abstract(object):
... __metaclass__ = ABCMetaTypeCheck
... @abstractmethod
... def foo(self): pass
... @abstractproperty
... def bar(self): pass
... @abstractstatic
... def baz(): pass
...
>>> class ConcreteWrong(Abstract):
... foo = 'bar'
... bar = 'baz'
... baz = 'spam'
...
>>> ConcreteWrong()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class ConcreteWrong with abstract methods bar, baz, foo
>>>
>>> class ConcreteCorrect(Abstract):
... def foo(self): return 'bar'
... @property
... def bar(self): return 'baz'
... @staticmethod
... def baz(): return 'spam'
...
>>> ConcreteCorrect()
<__main__.ConcreteCorrect object at 0x104ce1d10>
类抽象(对象):
... __元类=ABCMetaTypeCheck
... @抽象方法
... def foo(自我):通过
... @抽象属性
... def bar(自我):通过
... @抽象静态
... def baz():通过
...
>>>类(摘要):
... foo='bar'
... bar='baz'
... baz=‘垃圾邮件’
...
>>>具体错误()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不能用抽象方法bar、baz、foo实例化抽象类ConcreteError
>>>
>>>类(摘要):
... def foo(self):返回“bar”
... @财产
... def bar(自身):返回“baz”
... @静力学方法
... def baz():返回“垃圾邮件”
...
>>>具体正确()
>>> class Abstract(object):
... __metaclass__ = ABCMetaTypeCheck
... @abstractmethod
... def foo(self): pass
... @abstractproperty
... def bar(self): pass
... @abstractstatic
... def baz(): pass
...
>>> class ConcreteWrong(Abstract):
... foo = 'bar'
... bar = 'baz'
... baz = 'spam'
...
>>> ConcreteWrong()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class ConcreteWrong with abstract methods bar, baz, foo
>>>
>>> class ConcreteCorrect(Abstract):
... def foo(self): return 'bar'
... @property
... def bar(self): return 'baz'
... @staticmethod
... def baz(): return 'spam'
...
>>> ConcreteCorrect()
<__main__.ConcreteCorrect object at 0x104ce1d10>