Python 3.x 在_getattribute__方法中打印函数参数和值

Python 3.x 在_getattribute__方法中打印函数参数和值,python-3.x,getattribute,Python 3.x,Getattribute,我试图打印出实例每次调用函数时调用的函数名和参数 我正在使用getattribute方法来实现这一点,我的代码如下 def __getattribute__(self, attr): def newfunc(*args, **kwargs): print( "%r Calling %r with %r %r" % (self, attr, args, kwargs)) return newfunc 代码会打印出函数的名称和参数,

我试图打印出实例每次调用函数时调用的函数名和参数

我正在使用getattribute方法来实现这一点,我的代码如下

    def __getattribute__(self, attr):

        def newfunc(*args, **kwargs):

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


    return newfunc 
代码会打印出函数的名称和参数,但不会执行origin方法,因为它返回一个新函数而不是调用旧函数

我做了一些搜索,像这样,在这个答案中的最高票数使用dict在字典中按函数名检索函数,我尝试了,但结果是递归调用

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

或者,是否有一种方法可以在实例每次调用其方法时打印出函数的名称和参数



另外,除了使用decorator,我知道我可以使用decorator,但我不想把decorator放在我使用的每个方法前面。代码的主要问题是,在任何时候都无法检索实例中的原始属性,这是
\uuuu getattribute\uuuuu
的工作-破坏
\uuuu getattribute\uuuuuu
是一种100%致命的方法,它会让你的类根本无法工作

因此,第一件事是在超类上调用一个工作的
\uuu getattribute\uuu
来检索属性

然后,代码中第二个明显缺少的部分是,您甚至没有尝试从“printer”函数调用原始函数或方法。 我们把这样一个调用放在代码的末尾

如果这样做了,请更加小心,比如,不要尝试返回包装在函数中的不可调用属性,因为那样会失败

在注意到这三点后,它应该按照您的预期工作:

def\uuu getattribute\uuu(self,attr):
original=super()。\uuuuu getattribute\uuuuuuu(属性)
如果可调用(原件):
def newfunc(*args,**kwargs):
打印(“%r使用%r%r%”调用%r(self、attr、args、kwargs))
返回原件(*args,**kwargs)
返回newfunc
归还原件

由于您不想应用decorator,但仍然需要“打印出
\uuuu getattribute\uuuuu
方法中的函数名和参数”,请使用以下方法:

为了避免
\uuuu getattribute\uuuu
方法中的无限递归,它的实现应该始终使用相同的名称调用基类方法来访问它需要的任何属性

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) {}
用(1,2){
用(3,4){}调用“my_func”

谢谢!它对我来说是有效的,我实际上尝试使用getattr调用该函数,但它不起作用。
\uu getattr\uu
仅对实例上找不到的属性进行调用-其目的是提供它单独公开的动态属性。在contrst中,为每个属性访问调用
\uuuu getattribute\uuu
。(并且在
对象内调用
\uuuuuuuGetAttr\uuuuuuuuuuu
本身。\uuuuuuuuuGetAttribute\uuuuuuuuuu
作为属性查找的一部分,而不是在返回之后)