import inspect
import re
def overrides(method):
# actually can't do this because a method is really just a function while inside a class def'n
#assert(inspect.ismethod(method))
stack = inspect.stack()
base_classes = re.search(r'class.+\((.+)\)\s*\:', stack[2][4][0]).group(1)
# handle multiple inheritance
base_classes = [s.strip() for s in base_classes.split(',')]
if not base_classes:
raise ValueError('overrides decorator: unable to determine base class')
# stack[0]=overrides, stack[1]=inside class def'n, stack[2]=outside class def'n
derived_class_locals = stack[2][0].f_locals
# replace each class name in base_classes with the actual class type
for i, base_class in enumerate(base_classes):
if '.' not in base_class:
base_classes[i] = derived_class_locals[base_class]
else:
components = base_class.split('.')
# obj is either a module or a class
obj = derived_class_locals[components[0]]
for c in components[1:]:
assert(inspect.ismodule(obj) or inspect.isclass(obj))
obj = getattr(obj, c)
base_classes[i] = obj
assert( any( hasattr(cls, method.__name__) for cls in base_classes ) )
return method
基于这个和fwc:s的答案,我创建了一个pip可安装包https://github.com/mkorpela/overrides
有时我会在这里看到这个问题。 这主要发生在(再次)在我们的代码库中看到相同的错误之后:有人在重命名“interface”中的方法时忘记了一些实现类的“interface”。。
好吧,Python不是Java,但Python有强大的功能——显式比隐式更好——而且在现实世界中确实有一些具体的例子可以帮助我。
这里是覆盖decorator的草图。这将检查作为参数给定的类是否与要修饰的方法具有相同的方法(或其他)名称。
如果你能想出更好的解决办法,请贴在这里!
其工作原理如下:
如果执行错误的版本,则在类加载期间将引发断言错误:
如果您只想用于文档目的,可以定义自己的重写装饰器:
这真的只是一个视觉糖果,除非您创建覆盖(f)的方式实际上是检查覆盖。
但是,这是Python,为什么要像编写Java一样编写它呢?
这里的实现不需要指定接口的类名。
相关问题 更多 >
编程相关推荐