python dict 属性,Python如何绕过普通属性查找来找到__dict__?

I understand that __dict__ in obj.__dict__ is a descriptor attribute of type(obj), so the lookup for obj.__dict__ is type(obj).__dict__['__dict__'].__get__(obj).

It's tempting to say that __dict__ has to be a descriptor because

implementing it as a __dict__ entry would require you to find the

__dict__ before you can find the __dict__, but Python already

bypasses normal attribute lookup to find __dict__ when looking up

other attributes, so that's not quite as compelling as it initially

sounds. If the descriptors were replaced with a '__dict__' key in

every __dict__, __dict__ would still be findable.

How does "Python already bypasses normal attribute lookup to find __dict__"? What does "normal attribute lookup" mean?

According to the context of the quote in the link, I don't think when the author wrote that, he referred to that the lookup for obj.__dict__ is type(obj).__dict__['__dict__'].__get__(obj).

解决方案

Normal attribute lookup is done by calling the __getattribute__ hook, or more precisely, the C-API tp_getattro slot. The default implementation for this is in the PyObject_GenericGetAttr C-API function.

It is the job of PyObject_GenericGetAttr to invoke descriptors if they exist, and to look at the instance __dict__. And indeed, there is a __dict__ descriptor, but it is faster for __getattribute__ to just access the __dict__ slot in the instance memory structure directly, and that is what the actual implementation does:

if (dict == NULL) {

/* Inline _PyObject_GetDictPtr */

dictoffset = tp->tp_dictoffset;

if (dictoffset != 0) {

if (dictoffset < 0) {

Py_ssize_t tsize;

size_t size;

tsize = ((PyVarObject *)obj)->ob_size;

if (tsize < 0)

tsize = -tsize;

size = _PyObject_VAR_SIZE(tp, tsize);

assert(size <= PY_SSIZE_T_MAX);

dictoffset += (Py_ssize_t)size;

assert(dictoffset > 0);

assert(dictoffset % SIZEOF_VOID_P == 0);

}

dictptr = (PyObject **) ((char *)obj + dictoffset);

dict = *dictptr;

}

}

Note the Inline _PyObject_GetDictPtr comment; this is a performance optimisation, as instance attribute lookups are frequent.

If you try to access instance.__dict__ from Python code, then the descriptor is invoked; it is a data descriptor object so is invoked before instance attributes are even looked at.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值