通过 object.__getattribute__(type(self), attr) 调用描述符不起作用

问题描述

简而言之,我有以下信息:

class Descriptor:
    def __set_name__(self,owner,name):
        self.public_name = name
        self.private_name = '_' + name

    def __get__(self,instance,owner):
        print('something')

    def __set__(self,value):
        setattr(instance,self.private_name,value)

class C:
    arg1 = Descriptor()

    def __init__(self,name):
        self.arg1 = name

    def __getattribute__(self,attr):
        if attr == 'arg1':
            object.__getattribute__(type(self),attr)

c = C('Henry')
c.arg1

为什么 c.arg1 什么都不做,而是打印出 something 中定义的 __get__

显然,如果我将 __getattribute__ 中的代码更改为以下替代方案:

它会照常工作。

此外,以下也有效:

  • getattr(C,'arg1')

但当我将其设置为 object.__getattribute__(type(self),attr) 时不会。我想知道为什么它不起作用。

解决方法

object.__getattribute__ 是用于查找类型属性的错误 __getattribute__ 方法。 type.__getattribute__ 是正确的方法。

如果你对一个类型调用 object.__getattribute__,它将为普通对象执行属性查找过程。它不会搜索参数的 MRO,也不会调用描述符,除非在元类中找到它们。

(也就是说,即使你切换到调用 type.__getattribute__,你的 __getattribute__ 实现也没有意义。它会打印你期望它打印的东西,但它不会感觉。)