获取修饰类方法的类名

2024-05-15 05:12:34 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑以下场景:

import functools

def wrapmethod(f):
    @functools.wraps(f)
    def wrap(*args, **kwargs):
        print '>> %s' % (f.func_name)

        # Here I'll do pre-processing
        r = f(*args, **kwargs)
        # Here I'll do post-processing

        return r

    return wrap

@wrapmethod
def foo():
    pass

class Test(object):
    @wrapmethod
    def foo(self):
        pass

test = Test()
test.foo()
foo()

它将输出以下内容,如您在http://codepad.org/Y4xXyjJO中看到的执行:

^{pr2}$

我想知道在第一行输出Test.foo的方法,指示方法链接到的类。在

有什么想法吗?有可能吗?在

提前谢谢你。在


Tags: testreturnherefoodefargspassdo
2条回答

这是不容易做到的。 如果您添加了self作为内部函数的第一个参数,则可以使用self.__class__.__name__访问类名,但在装饰没有参数的无类函数时,它将中断(如果它有参数,它将把第一个参数视为self)。在

因此,除非有一种方法可以确定函数是否在对象上下文中被调用,否则您不可能做您想做的事情。在

顺便说一句。。你为什么需要这个?这听起来像是可以用更好的方法解决的问题。在

实际上,您可以使用inspect module获取函数的签名,并且假设您遵循通过第一个参数“self”引用类对象的约定,则可以执行以下操作:

import inspect  
def print_name(*_args):
    def _print_name(fn):
        def wrapper(*args, **kwargs):
            try :
                is_method   = inspect.getargspec(fn)[0][0] == 'self'
            except :
                is_method   = False

            if is_method :
                name    = '{}.{}.{}'.format(fn.__module__, args[0].__class__.__name__, fn.__name__)
            else :
                name    = '{}.{}'.format(fn.__module__, fn.__name__)

            print (name)
            return  fn(*args,**kwargs)
        return wrapper
    return _print_name

如果这是一个函数,它将打印方法module、class和name,或者只打印module和name

从python3.3以后,fn.__qualname__可用于获取函数/方法的限定名。在

^{pr2}$

这对函数和方法都很有效:

In [1]: class A():
...:     @print_name()
...:     def a():
...:         print('Hi from A.a')
In [2]: A.a()
    __main__.A.a
    Hi from A.a

In [25]: @print_name()
    ...: def b():
    ...:     print('Hi from b')
    ...: 
In [26]: b()
    __main__.b
    Hi from b

相关问题 更多 >

    热门问题