继承非抽象 class 并将其所有功能转换为抽象方法
Inheriting a non-abstract class and turning all of its functions into abstractmethods
我得到了一个上游接口,它的所有功能都定义为非抽象的,而实际上它们应该用 @abstractmethod
装饰。当我在调用它时没有实现其中一个功能时,我想收到一个错误。为此,我将创建一个包装器 class 并手动遍历其定义的每个函数并执行如下操作:
from abc import ABC, abstractmethod
class Foo(object):
def foo(self):
print("Foo")
class AbstractFoo(Foo, ABC):
@abstractmethod
def foo(self):
return super().foo()
class ConcreteFoo(AbstractFoo):
def foo(self):
print("Concrete Foo")
super().foo()
f = ConcreteFoo()
f.foo()
输出:
Concrete Foo
Foo
我想要一些方法来对 Foo 定义的 所有 函数执行此操作。显然,像__str__
和__repr__
这样的继承魔法函数应该被适当转发。
有没有人知道一个很好的 pythonic 方式来做这件事?
def validate_base_class_implemntation(cls):
base_cls_funcs = []
for attr in cls.__bases__[0].__dict__:
if callable(getattr(cls, attr)):
base_cls_funcs.append(attr)
cls_funcs = []
for attr in cls.__dict__:
if callable(getattr(cls, attr)):
cls_funcs.append(attr)
missing_funcs = [x for x in base_cls_funcs if x not in cls_funcs]
if len(missing_funcs) > 0:
print("Not implemented functions are: {}".format(','.join(missing_funcs)))
raise Exception("Not implement function exception!")
return cls
class Foo(object):
def foo(self):
print("Foo")
def boo(self):
print("Wow")
@validate_base_class_implemntation
class ConcreteFoo(Foo):
def foo(self):
print("Concrete Foo")
super().foo()
f = ConcreteFoo()
f.foo()
100% 不确定这是否是您的意思。
此装饰器检查 class 装饰器是否实现了所有基本 class 功能(在您的情况下,它们没有用抽象装饰)。如果有一个你的装饰 class 没有实现的功能,它会引发异常。
可以修改原来的classFoo
,把它的所有方法都抽象成抽象方法,然后用[=13=定义一个Foo
的空白subclass ] 为了处理支票:
from abc import ABCMeta, abstractmethod
from types import FunctionType
class AbstractFoo(Foo, metaclass=ABCMeta):
pass
names = set()
for k, v in vars(Foo).items():
if k.startswith('__') and k.endswith('__'):
continue
elif isinstance(v, FunctionType):
names.add(k)
v.__isabstractmethod__ = True
AbstractFoo.__abstractmethods__ = frozenset(names)
旁注: 这种方法依赖于 abc
使用的 dunder 属性,因此可以在不弃用的情况下中断。
我得到了一个上游接口,它的所有功能都定义为非抽象的,而实际上它们应该用 @abstractmethod
装饰。当我在调用它时没有实现其中一个功能时,我想收到一个错误。为此,我将创建一个包装器 class 并手动遍历其定义的每个函数并执行如下操作:
from abc import ABC, abstractmethod
class Foo(object):
def foo(self):
print("Foo")
class AbstractFoo(Foo, ABC):
@abstractmethod
def foo(self):
return super().foo()
class ConcreteFoo(AbstractFoo):
def foo(self):
print("Concrete Foo")
super().foo()
f = ConcreteFoo()
f.foo()
输出:
Concrete Foo
Foo
我想要一些方法来对 Foo 定义的 所有 函数执行此操作。显然,像__str__
和__repr__
这样的继承魔法函数应该被适当转发。
有没有人知道一个很好的 pythonic 方式来做这件事?
def validate_base_class_implemntation(cls):
base_cls_funcs = []
for attr in cls.__bases__[0].__dict__:
if callable(getattr(cls, attr)):
base_cls_funcs.append(attr)
cls_funcs = []
for attr in cls.__dict__:
if callable(getattr(cls, attr)):
cls_funcs.append(attr)
missing_funcs = [x for x in base_cls_funcs if x not in cls_funcs]
if len(missing_funcs) > 0:
print("Not implemented functions are: {}".format(','.join(missing_funcs)))
raise Exception("Not implement function exception!")
return cls
class Foo(object):
def foo(self):
print("Foo")
def boo(self):
print("Wow")
@validate_base_class_implemntation
class ConcreteFoo(Foo):
def foo(self):
print("Concrete Foo")
super().foo()
f = ConcreteFoo()
f.foo()
100% 不确定这是否是您的意思。
此装饰器检查 class 装饰器是否实现了所有基本 class 功能(在您的情况下,它们没有用抽象装饰)。如果有一个你的装饰 class 没有实现的功能,它会引发异常。
可以修改原来的classFoo
,把它的所有方法都抽象成抽象方法,然后用[=13=定义一个Foo
的空白subclass ] 为了处理支票:
from abc import ABCMeta, abstractmethod
from types import FunctionType
class AbstractFoo(Foo, metaclass=ABCMeta):
pass
names = set()
for k, v in vars(Foo).items():
if k.startswith('__') and k.endswith('__'):
continue
elif isinstance(v, FunctionType):
names.add(k)
v.__isabstractmethod__ = True
AbstractFoo.__abstractmethods__ = frozenset(names)
旁注: 这种方法依赖于 abc
使用的 dunder 属性,因此可以在不弃用的情况下中断。