实现__getattribute__时如何访问形参?

4 投票
7 回答
3057 浏览
提问于 2025-04-15 11:50

看起来 __getattribute__ 这个方法只有两个参数 (self, name)

但是在我实际拦截的代码中,这个方法其实是有其他参数的。

有没有办法可以访问这些参数呢?

谢谢,

Charlie

7 个回答

1

老实说,我不太明白你的问题。如果你想要一种方法来重写 getattribute,同时又想保留原来的属性,你可以使用 __dict__

def __getattribute__(self, attr):
    if attr in self.__dict__:
          return self.__dict__[attr]
    # Add your changes here
3

在Python中,调用一个方法其实是两个步骤。首先,程序会查找这个函数,然后再执行它。如果想了解得更深入,可以看看我对这个问题的回答。

所以你需要做的事情大概是这样的:

def __getattribute__(self, key):
    if key == "something_interesting":
        def func(*args, **kwargs):
            # use arguments, and possibly the self variable from outer scope
        return func
    else:
        return object.__getattribute__(self, key)

另外,重写__getattribute__通常不是个好主意。因为这个方法在每次访问属性时都会被调用,所以很容易就会陷入无限循环。即使你做得再正确,也会对性能造成很大的影响。你确定__getattr__不能满足你的需求吗?或者说,使用一个返回函数的描述符对象会不会更好呢?描述符通常在重用方面表现得更好。

7

__getattribute__ 这个东西就是用来返回你请求的属性。如果你请求的是一个方法,那么就会使用 __call__ 接口来调用这个方法。

与其直接返回这个方法,不如返回一个包装器,举个例子:

def __getattribute__(self, attr):
     def make_interceptor(callble):
         def func(*args, **kwargs):
             print args, kwargs
             return callble(*args, **kwargs)
         return func
     att = self.__dict__[attr]
     if callable(att):
        return make_interceptor(att)

撰写回答