在 __getattribute__ 方法中打印出函数参数和值

Print out function arguments and values in __getattribute__ method

我正在尝试打印出实例每次调用函数时调用的函数名称和参数

我正在使用 getattribute 方法来实现这个,我的代码在

下面
    def __getattribute__(self, attr):

        def newfunc(*args, **kwargs):

            print( "%r Calling %r with %r %r" % (self, attr, args, kwargs))


    return newfunc 

代码确实打印出函数的名称和参数,但未执行 origin 方法,因为它 returns 一个新函数而不是调用旧函数。

我做了一些搜索,比如这个 question,这个答案中的最高投票使用 dict 通过它在字典中的名称检索函数,我试过了,但它会导致递归调用。

我的问题是。有没有办法在 __getattribute__method 中打印出函数的名称和参数?

或者有没有办法在每次实例调用其方法时打印出函数的名称和参数?


Ps。除了使用装饰器,我知道我可以为此使用装饰器,但我不想将装饰器放在我使用的每个方法前面

您的代码的主要且明显的问题是您在任何时候都无法检索实例中的原始属性,这是 __getattribute__ 的工作 - 打破 __getattribute__ 是 100%使您的 class 根本无法工作的绝对方式。

因此,第一件事是调用一个工作 __getattribute__ 上的超级 class 来检索属性。

那么您的代码中明显缺少的第二部分是您甚至没有尝试从 "printer" 函数调用原始函数或方法。 我们将这样的调用放在其代码的末尾。

完成后,请多加注意,例如,不要尝试将 return 不可调用的属性包装在函数中,因为那样会失败。

处理完这 3 点后,它应该会如您所愿地工作:

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

因为你不想应用装饰器但仍然需要"print out function's name and arguments inside __getattribute__ method" - 使用以下方法:

为了避免 __getattribute__ 方法中的无限递归,其实现应始终调用具有相同名称的基础 class 方法来访问它需要的任何属性。

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) {}