1

我一直在深入查阅 Python 文档以获取描述符,但我无法理解其中关于描述符调用和给定 Python 等效的object.__getattribute__().

给定的纯 Python 等效项(请参阅下面代码中的“object_getattribute”)应该通过调用作为第一个参数提供的类对象来调用type的版本 ,这会导致对type的调用。问题是,在查找实例调用中涉及type的属性查找(在 中实现)应该会搞砸事情,因为它会桥接到不同的关系线,其中类是对象,元类是类。当类的MRO用尽时(此时将使用getattr ()),由进行的查找搜索应该终止,但调用类型__getattribute__()getattr()__getattribute__()type.__getattribute__()object.__getattribute__()__getattribute__()会不合逻辑地级联搜索以覆盖元类的字典,并可能返回一个名称相似的属性,这是错误的,因为元类定义了类,而不是对象。这是一个创建名为“mytype”的元类的示例,一个名为“base”的基类,它使用以下提供的 Python 等效项:https ://docs.python.org/3/howto/descriptor.html#technical-tutorial ,以及来自“mytype”的实例类“myclass”:

class mytype(type):
    cls_var = 11

class base:
    def object_getattribute(obj, name):
        null = object()
        objtype = type(obj)
        cls_var = getattr(objtype, name, null)
        descr_get = getattr(type(cls_var), '__get__', null)
        if descr_get is not null:
            if (hasattr(type(cls_var), '__set__') or hasattr(type(cls_var), '__delete__')):
                return descr_get(cls_var, obj, objtype)
        if hasattr(obj, '__dict__') and name in vars(obj):
            return vars(obj [name]
        if descr_get is not null:
            return descr_get(cls_var, obj, objtype)
        if cls_var is not null:
            return cls_var
        raise AttributeError(name)
    
    def __init__(s, v):
        s.core = v

    @property
    def core(s):
        return '-- ' + s._core + ' --'

    @core.setter
    def core(s, v):
        s._core = v

myclass = mytype('myclass', (base, ), {'a':97})

o = myclass('IRON')

(注意:我不知道在创建类时如何向类添加方法定义 throw 调用类型new (),所以我想出了类“base”作为提供“object_getattribute()”方法的方法文档)

现在,如果我运行:

print(o.__getattribute__('cls_var'))

或者,更简单地说:

print(o.cls_var

我得到:

...
AttributeError: 'myclass' object has no attribute 'cls_var'

[Program finished]

结果是我通常所期望的。搜索不会在元类中查找用于评估名称 - 那是不同的领域。但是,如果我使用文档中的纯 Python 等效项,如下所示:

print(o.object_getattribute('cls_var'))

然后我得到:

11

mytype上。

总结:是不是文档中提供的纯Python版本错了?

4

0 回答 0