2017-07-08 26 views
5

的Python果殼中的描述:在查找過程中涉及`__getattribute__`方法?

如何參與上述查找程序__getattribute__方法?

  • 是在__getattribute__方法在查找程序的地方叫什麼名字?

  • 或者,通過調用__getattribute__開始查找過程,然後完成兩個鏈接中的所有工作?

謝謝。

+0

有了你一直在問的所有這些屬性查詢問題,我想你最終都會想聽到這部分內容。 – user2357112

+0

[相關](https://stackoverflow.com/questions/39043912/python-3-getattribute-vs-dot-access-behaviour),雖然重點是不同的細節比你看到的。 – user2357112

回答

2

TLDR:屬性查找從調用__getattribute__開始,它執行鏈接中提到的所有工作。根據對象的類型調用object.__getattribute__type.__getattribute__


任何屬性查找都會在內部產生LOAD_ATTR字節碼。

>>> import dis  
>>> dis.dis(lambda: foo.x) 
    1   0 LOAD_GLOBAL    0 (foo) 
       2 LOAD_ATTR    1 (x) 
       4 RETURN_VALUE 

LOAD_ATTR然後調用PyObject_GetAttr

PyObject_GetAttr現在尋找對象類型的tp_getattrotp_getattr(deprecated)插槽。現在

PyObject * 

PyObject_GetAttr(PyObject *v, PyObject *name) 
{ 
    PyTypeObject *tp = Py_TYPE(v); 
    ... 
    if (tp->tp_getattro != NULL) 
     return (*tp->tp_getattro)(v, name); 
    if (tp->tp_getattr != NULL) { 
     const char *name_str = PyUnicode_AsUTF8(name); 
     if (name_str == NULL) 
      return NULL; 
     return (*tp->tp_getattr)(v, (char *)name_str); 
    } 
    ... 
} 

如果一個對象都有自己的執行__getattribute__,然後將其用在其他它退到要麼object.__getattribute__type.__getattribute__基於類型。 tp_getattro slot如果是object指向PyObject_GenericGetAttr並且對於type指向type_getattro

PyObject_GenericGetAttr and type_getattro基本上做檢查描述符,字典,插槽等(基於類型)的所有工作,並嘗試返回一個值。如果他們甚至在所有事情之後都找不到它,則會引發AttributeError,如果對象的類型定義爲__getattr__,那麼它將被調用。