2016-04-19 9 views
2

從Python入門書第5版:__next__和__str__是否由內部等效的next和str函數調用?

頁421,footnote2:

從技術上來講,for循環調用的I.__next__內部的等效,則next(I)這裏來代替,雖然很少有什麼區別兩者之間。您的手動迭代通常可以使用任何一種呼叫方案。

這究竟意味着什麼?這是否意味着I.__next__是由C函數調用的,而不是str內置函數在for循環或任何內置迭代上下文中調用?

頁914:

__str__首先嚐試用於print操作和str內置函數(其print運行的內部等效)。它通常應該返回一個用戶友好的顯示。

從書

除此之外,是否使用Python C函數調用__str____next__內部,因爲我從書上了解?

回答

5

的Python C實現使用對基本上一回事Python的函數C的功能,在該像str()next() Python的函數通常是圍繞C函數薄包裝。

這些C函數然後負責調用右鉤子;這可能是掛鉤的C版本(指向函數的結構中的插槽)或類中的Python函數。

現在,str()next()都比這裏的包裝稍微多一些,因爲這些函數定義了額外的功能,需要更多的實現工作;例如,next()採用定義默認值的第二個參數。

所以我以len()爲例。該功能在builtin_len() C function定義:

static PyObject * 
builtin_len(PyObject *self, PyObject *v) 
{ 
    Py_ssize_t res; 

    res = PyObject_Size(v); 
    if (res < 0 && PyErr_Occurred()) 
     return NULL; 
    return PyInt_FromSsize_t(res); 
} 

注意通話PyObject_Size();這就是C代碼用來獲取對象長度的原因。其餘的只是錯誤處理和生成一個Python對象。

PyObject_Size()然後是implemented like this

Py_ssize_t 
PyObject_Size(PyObject *o) 
{ 
    PySequenceMethods *m; 

    if (o == NULL) { 
     null_error(); 
     return -1; 
    } 

    m = o->ob_type->tp_as_sequence; 
    if (m && m->sq_length) 
     return m->sq_length(o); 

    return PyMapping_Size(o); 
} 

它需要一個PyObject結構,發現從那裏ob_type結構,其具有可選的tp_as_sequence結構,其可以定義一個sq_length函數指針。如果存在,則調用它來產生實際的長度。不同的類型可以定義這個函數,並且Python的實例可以使用特殊的C結構重定向回Python方法。

所有這些都表明,Python的內部實現使用了大量的抽象來實現對象,允許C定義的類型和Python類大致相同。如果您想深入瞭解,Python文檔包含full coverage of the C-API,其中包括dedicated tutorial

盤旋迴原來的兩個功能的next()內部的等效爲PyIter_Next(),並str(),如用於任意對象的字符串轉換,是PyObject_Str()

+0

這是一個很好的解釋,不幸的是我不是C開發人員,但我喜歡深入內部。因此,我從你的解釋中得出結論:'str'和'next'確實是C函數,他們決定調用可以是C或Python函數的右鉤子。 – direprobs

相關問題