首页 > 解决方案 > 用另一个实例的方法装饰一个实例的方法

问题描述

我对 Python 还很陌生。我有 2 个类,每个类都有一个实例。我想用另一个实例的方法来装饰其中一个实例的方法,例如:

import functools

class DecoClass():
    def __init__(self, deco_arg):
        self.deco_arg = deco_arg

    def my_decorator(self, f):
        @functools.wraps(f)
        def deco_wrapper(*args):
            print ('deco_wrapper argument :', self.deco_arg) # or just do something with deco_arg
            f = f(*args)
            return f
        return deco_wrapper

###

class MyClass():
    def __init__(self, arg, decorator):
            self.arg = arg
            self.decorator = decorator

    @self.decorator.my_decorator            # this is my problem, how can I do this ?
    def my_function(self):
        print ('my_function : ', self.arg)

###

if __name__ == "__main__":
a = DecoClass(1)
b = MyClass(10, a)
b.my_function()

以上内容当然行不通,因为MyClass不了解self.decorator属性(在类级别)。可以这样做还是有其他方法?

PS。上面的例子过于简单化了。在我的情况下,DecoClass()实际上将负责异常捕获、错误记录(到文件和/或 mysql)和其他各种事情。我只是想实例化一次,这样每次我想使用它时就不必传递参数(记录器、db auth 等)。此外,DecoClass()将驻留在一个模块中,该模块将同时被不同的 python 程序使用(每个实例都有自己的参数)。

感谢您的时间。

标签: pythonpython-decoratorspython-class

解决方案


这可能无法满足您的需求,但您可以尝试以下操作:

import functools

class DecoClass():
    def __init__(self, deco_arg):
        self.deco_arg = deco_arg

    def my_decorator(self, f):
        @functools.wraps(f)
        def deco_wrapper(*args):
            print ('deco_wrapper argument :', self.deco_arg)
            r = f(*args)
            return r
        return deco_wrapper

###

a = DecoClass(1)
decorator = a.my_decorator

class MyClass():
    def __init__(self, arg):
            self.arg = arg
            self.decorator = decorator

    @decorator
    def my_function(self):
        print ('my_function : ', self.arg)

###

if __name__ == "__main__":
    b = MyClass(10)
    b.my_function()

推荐阅读