繁体   English   中英

将 self 的方法作为参数传递给装饰器

[英]Passing a method of self to decorator as an argument

我有一个 class A,它有很多旧的复杂方法,我已经重写了。

class A:
    def __init__(self):
        self.x = 1

    def old_func(self):
        return 2

    @property
    def b(self):
        if not hasattr(self, 'b'):
            self._b = B(self)
        return _b

class B:
    def __init__(self, a: A):
         self.a = a

    def new_func(self):
        return 2

我想用`a.new_func逐渐替换a.old_func 但首先,我想确保新方法始终以与旧方法相同的方式工作。 所以我写了一个装饰器来检查:

def refactor_factory(new_func):
    def refactor(old_func):
        def _wrapper(*args, **kwargs):
            old_return_value = old_func(*args, **kwargs)
            new_return_value = new_func(**kwargs)

            if old_return_value != new_return_value:
                raise Exception("Mismatch")  # Add a complete log info

            return old_return_value

        return _wrapper

    return refactor

我想这样称呼它:

class A:
    def __init__(self):
        self.x = 1
    
    @refactor_factory(self.b.new_func)
    def old_func(self):
        return 2
    
    def new_func(self):
        return 2

问题是我无法将 new_func 传递给装饰器。 我知道我可以在装饰器中访问self ,但是在传递 arguments 时,我无法访问它,因此我无法传递它的方法。 有没有办法可以做到这一点?

ps 我知道有不同的设计来实现我想要的,就像下面的那样,我只是觉得第一种方式更干净。

def refactor(old_func):
    def _wrapper(*args, **kwargs):
        self = args[0]
        if isinstance(old_func, self.old_func):
            new_func = self.b.new_func
            
        old_return_value = old_func(*args, **kwargs)
        new_return_value = new_func(**kwargs)

        if old_return_value != new_return_value:
            raise Exception("Mismatch")  # Add a complete log info

        return old_return_value

    return _wrapper


class A:
    def __init__(self):
        self.x = 1

    @refactor_factory
    def old_func(self):
        return 2

    def new_func(self):
        return 2

我认为您可以通过A.new_func 在包装器中, self将是*args之一,因此它将正确传递。

class A:
    def __init__(self):
        self.x = 1
    
    @refactor_factory(A.new_func)
    def old_func(self):
        return 2
    
    def new_func(self):
        return 2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM