有没有办法在继承期间持久化装饰器?

hek*_*kzu 5 python python-3.x python-decorators

我正在尝试使用未实现的方法编写一个抽象类,这将强制继承子级在重写方法(在装饰器中定义)时返回特定类型的值。

当我使用下面显示的代码时,子方法不会调用装饰器。我认为这是因为该方法被覆盖,这很有意义。我的问题基本上是这样的:有没有办法通过方法覆盖使装饰器持久化?

我不反对使用装饰器以外的东西,但这是一个很快想到的解决方案,我很想知道是否有任何方法可以使它起作用。

如果使用装饰器是正确且可能的选择,它看起来像这样:

def decorator(returntype):
    def real_decorator(function):
        def wrapper(*args, **kwargs):
            result = function(*args, **kwargs)
            if not type(result) == returntype:
                raise TypeError("Method must return {0}".format(returntype))
            else:
                return result
        return wrapper
    return real_decorator
Run Code Online (Sandbox Code Playgroud)

我需要我的父类看起来类似于这个:

class Parent(ABC):
    @decorator(int)
    @abstractmethod
    def aye(self, a):
        raise NotImplementedError
Run Code Online (Sandbox Code Playgroud)

子类会做这样的事情:

class Child(Parent):
    def aye(self, a):
        return a
Run Code Online (Sandbox Code Playgroud)

如果需要,我很乐意更好地澄清我的问题,并感谢所有花时间提前阅读此问题的人!

mgc*_*mgc 6

我不确定您是否可以按照您想要的方式保留装饰器的效果,但是您仍然可以在Parent类中装饰一个不会是 an的包装函数,abstractmethod并让子类实现这样的包装函数:

from abc import ABC, abstractmethod

def decorator(returntype):
    def real_decorator(function):
        def wrapper(*args, **kwargs):
            result = function(*args, **kwargs)
            if not type(result) == returntype:
                raise TypeError("Method must return {0}".format(returntype))
            else:
                return result
        return wrapper
    return real_decorator

class Parent(ABC):
    @decorator(int)
    def aye(self, a):
        return self.impl_aye(a)

    @abstractmethod
    def impl_aye(self, a):
        raise NotImplementedError


class Child(Parent):
    def impl_aye(self, a):
        return a
Run Code Online (Sandbox Code Playgroud)

如果需要,还有一些解决方案可以保护aye方法免受Parent要覆盖的类的影响,例如,请参阅此答案

否则,如果您想使用类型提示并使用mypyPython 的可选静态类型检查器)检查代码,如果您尝试实现返回类型与其父类不兼容的子类,则会收到错误消息:

from abc import ABC, abstractmethod

class Parent(ABC):
    @abstractmethod
    def aye(self, a) -> int:
        raise NotImplementedError

class Child(Parent):
    def aye(self, a) -> str :
        return a
Run Code Online (Sandbox Code Playgroud)

的输出mypy

a.py:9: error: Return type "str" of "aye" incompatible with return type "int" in supertype "Parent"
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)