Python装饰器使函数忘记它属于一个类 [英] Python decorator makes function forget that it belongs to a class

查看:59
本文介绍了Python装饰器使函数忘记它属于一个类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个装饰器来记录日志:

I am trying to write a decorator to do logging:

def logger(myFunc):
    def new(*args, **keyargs):
        print 'Entering %s.%s' % (myFunc.im_class.__name__, myFunc.__name__)
        return myFunc(*args, **keyargs)

    return new

class C(object):
    @logger
    def f():
        pass

C().f()

我要打印:

Entering C.f

但我收到此错误消息:

AttributeError: 'function' object has no attribute 'im_class'

大概这与'logger'中'myFunc'的范围有关,但是我不知道是什么.

Presumably this is something to do with the scope of 'myFunc' inside 'logger', but I've no idea what.

推荐答案

Claudiu的答案是正确的,但是您也可以通过从self参数中获取类名来作弊.在继承的情况下,这将产生误导性的日志语句,但会告诉您正在调用其方法的对象的类.例如:

Claudiu's answer is correct, but you can also cheat by getting the class name off of the self argument. This will give misleading log statements in cases of inheritance, but will tell you the class of the object whose method is being called. For example:

from functools import wraps  # use this to preserve function signatures and docstrings
def logger(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print "Entering %s.%s" % (args[0].__class__.__name__, func.__name__)
        return func(*args, **kwargs)
    return with_logging

class C(object):
    @logger
    def f(self):
        pass

C().f()

就像我说的那样,如果您已经从父类继承了一个函数,那么这将无法正常工作.在这种情况下,您可能会说

As I said, this won't work properly in cases where you've inherited a function from a parent class; in this case you might say

class B(C):
    pass

b = B()
b.f()

并获取消息Entering B.f,因为您的确是正确的类,所以您实际上要在其中获取消息Entering C.f.另一方面,这可能是可以接受的,在这种情况下,我会建议这种方法胜过Claudiu的建议.

and get the message Entering B.f where you actually want to get the message Entering C.f since that's the correct class. On the other hand, this might be acceptable, in which case I'd recommend this approach over Claudiu's suggestion.

这篇关于Python装饰器使函数忘记它属于一个类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆