我一直在深入查阅 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版本错了?