Python装饰器使函数忘记它属于一个类

标签 python reflection metaprogramming

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

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' 的范围有关,但我不知道是什么。

最佳答案

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

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()

正如我所说,这在您从父类继承函数的情况下将无法正常工作;在这种情况下你可能会说

class B(C):
    pass

b = B()
b.f()

并得到消息 Entering B.f ,因为这是正确的类。另一方面,这可能是可以接受的,在这种情况下,我会推荐这种方法而不是 Claudiu 的建议。

关于Python装饰器使函数忘记它属于一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/306130/

相关文章:

c++ - T::* 在模板参数中是什么意思?

c++ - 这个名称解析如何与实现函数和回退函数一起工作?

python - Mongodb : AutoReconnect, 连接被对端重置

python - 如何使用 sklearn 的 CountVectorizer 进行矢量化和去矢量化?

java - 如何从java反射中的方法获取 "genericInfo"

c# - 如何避免使用反射访问类的私有(private)成员?

c# - 何时使用泛型和类型检查?

F#如何将代码引用编译为程序集

python - 尝试抓取 HTML 表并转换为 Python 中的数据框。代码无法正常工作

python - 如何在Python中执行多重查询?