关于python:获取修饰类方法的类名

Get the class name of a decorated class method

本方案考虑:P></

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python
# -*- coding: utf-8 -*-
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()

它会输出executed As You can see this,http:/ / / y4xxyjjo:codepad.orgP></

1
2
>> foo
>> foo

我想知道的方式打印出来Test.fooin the first to which the class,在线显示method is to the联。P></

任何想法?它曾经是可能的吗?P></

谢谢你提前。P></


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

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

这将打印方法模块、类和名称,或者仅打印模块和名称(如果这是一个函数)