如何在函数方法的decorator中知道类的名称?

时间:2011-04-07 14:03:43

标签: python

我有一个简单的时间标记装饰功能:

def dec_timemark(f):
    def tmp(*args, **kwargs):
        sys.stdout.write(strftime("%d.%m.%Y %H:%M:%S") + ' ' + f.__name__ +
                                                         ' begin' + "\n" )
        res = f(*args, **kwargs)
        sys.stdout.write(strftime("%d.%m.%Y %H:%M:%S") + ' ' + f.__name__ +
                                                         ' end' + "\n"     )
        return res
    return tmp

典型用法:

class Task():
    @dec_timemark
    def make_torrent():
        sleep(10)

但是如何添加decorator的{​​{1}}名称? (不是记录:“class”,而是“make_torrent begin”,例如)?

2 个答案:

答案 0 :(得分:3)

假设装饰例程作为方法调用,您可以从self参数中提取类名:

def dump(f):
    def decorated(self, *args, **kwargs):
        print 'Class: {0}'.format(self.__class__.__name__)
        print 'Args passed to decorated function: {0}'.format(args)
        print 'Keyword args passed to decorated function: {0}'.format(kwargs)
        return f(self, *args, **kwargs)
    return decorated

class Test(object):
    """
    >>> Test().test('arg1', 'arg2', kwarg1='kwval1')
    Class: Test
    Args passed to decorated function: ('arg1', 'arg2')
    Keyword args passed to decorated function: {'kwarg1': 'kwval1'}
    """
    @dump
    def test(*args, **kwargs):
        pass

答案 1 :(得分:0)

由于该类尚不存在,因此无法在dec_timemark()范围内访问该信息。但是,当调用tmp()时,第一个参数将为self,因为.make_torrent()被称为实例方法。因此,type(self).__name__应该为您提供班级名称。

修改您的示例:

def dec_timemark(f):
    def tmp(self, *args, **kwargs):
        cname = type(self).__name__
        sys.stdout.write(strftime("%d.%m.%Y %H:%M:%S") + ' ' + cname + '.' + f.__name__ +
                                                     ' begin' + "\n" )
        res = f(self, *args, **kwargs)
        sys.stdout.write(strftime("%d.%m.%Y %H:%M:%S") + ' ' + cname + '.' + f.__name__ +
                                                     ' end' + "\n"     )
        return res
    return tmp