我正在尝试打印每次实例进行函数调用时实例所调用的函数名称和参数
我正在使用 getattribute 方法来实现此功能,我的代码在
下面 def __getattribute__(self, attr):
def newfunc(*args, **kwargs):
print( "%r Calling %r with %r %r" % (self, attr, args, kwargs))
return newfunc
代码确实打印出函数的名称和参数,但是未执行origin方法,因为它返回的是新函数,而不是调用旧函数。
我进行了一些搜索,例如question,使用 dict 在该答案中获得最高投票,我尝试通过字典中的名称来检索该函数,但我尝试这样做,但结果是递归调用。
我的问题是。有没有办法在__getattribute__method中打印出函数的名称和参数?
还是有一种方法可以在实例调用其方法时打印出函数的名称和参数?
Ps。除了使用装饰器,我知道我可以为此使用装饰器,但是我不想将装饰器放在我使用的每种方法的前面
答案 0 :(得分:0)
代码的主要(也是显而易见的)问题是,您在任何时候都不会检索实例中的原始属性,这是__getattribute__
的工作-破坏__getattribute__
是100%无效证书一种使您的班级根本不起作用的方法。
因此,第一件事是在超类上调用工作的__getattribute__
来检索属性。
然后,您的代码中缺少的第二部分是您甚至没有尝试从“打印机”函数调用原始函数或方法。 我们将这样的调用放在其代码的末尾。
这样做,需要多加注意,例如,不要尝试返回包装在函数中的不可调用属性,因为那样会失败。
照顾完这三点之后,它应该可以按照您的预期工作:
def __getattribute__(self, attr):
original = super().__getattribute__(attr)
if callable(original):
def newfunc(*args, **kwargs):
print( "%r Calling %r with %r %r" % (self, attr, args, kwargs))
return original(*args, **kwargs)
return newfunc
return original
答案 1 :(得分:0)
由于您不想应用装饰器,但仍然需要“在__getattribute__
方法内打印函数的名称和参数” -请使用以下方法:
为了避免在__getattribute__
方法中进行无限递归,其实现应始终调用具有相同名称的基类方法来访问所需的任何属性。
class A:
def my_func(self, a, b):
return a + b
def __getattribute__(self, attr):
def newfunc(*args, **kwargs):
print("%r Calling %r with %r %r" % (self, attr, args, kwargs))
return object.__getattribute__(self, attr)
return newfunc
a = A()
a.my_func(1, 2)
a.my_func(3, 4)
示例输出:
<__main__.A object at 0x116861710> Calling 'my_func' with (1, 2) {}
<__main__.A object at 0x116861710> Calling 'my_func' with (3, 4) {}