Python: __qualname__ of function with decorator

若如初见. 提交于 2021-01-28 08:40:50

问题


I'm using a Decorator (class) in an Instance method of another class, like this:

class decorator_with_arguments(object):

    def __init__(self, arg1=0, arg2=0, arg3=0):
        self.arg1 = arg1
        self.arg2 = arg2
        self.arg3 = arg3

    def __call__(self, f):
        print("Inside __call__()")
        def wrapped_f(*args):
            print(f.__qualname__)
            f(*args)
        return wrapped_f

class Lol:
    @decorator_with_arguments("hello")
    def sayHello(self,a1, a2, a3, a4):
        print(self.sayHello.__qualname__)

Now, when I print out self.sayHello.__qualname__ it prints decorator_with_arguments.__call__.<locals>.wrapped_f

Is there any way to override this? I want to see Lol.sayHello (qualname of my original function) in here.

I tried overriding the @property __qualname__ of __call__ (with a static string); didn't work.


回答1:


You can simply copy the __qualname__ attribute across to your wrapped_f wrapper function; it is this function that is returned when the decorator is applied, after all.

You could use the @functools.wraps() decorator to do this for you, together with other attributes of note:

from functools import wraps

class decorator_with_arguments(object): 
    def __init__(self, arg1=0, arg2=0, arg3=0):
        self.arg1 = arg1
        self.arg2 = arg2
        self.arg3 = arg3

    def __call__(self, f):
        print("Inside __call__()")
        @wraps(f)
        def wrapped_f(*args):
            print(f.__qualname__)
            f(*args)
        return wrapped_f

The @wraps(f) decorator there copies the relevant attributes from f onto wrapped_f, including __qualname__:

>>> Lol.sayHello.__qualname__
'Lol.sayHello'


来源:https://stackoverflow.com/questions/50815820/python-qualname-of-function-with-decorator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!