2016-04-19 4 views
2

От обучения питона книги 5th Edition:Являются ли __next__ и __str__ вызываемыми эквивалентными next и str функциями внутри?

Страница 421 footnote2:

Технически говоря, цикл for вызывает внутренний эквивалент I.__next__, вместо next(I) используется здесь, хотя редко бывает какая-то разница между двумя. В ваших ручных итерациях обычно может использоваться либо схема вызовов.

Что это значит? Означает ли это, что I.__next__ вызывается функцией C вместо str встроенной функции в цикле for или любых встроенных итерационных контекстах?

Страница 914:

__str__ пробуется первым для print операции и встроенные функции str (внутренний эквивалент которой print работает). Обычно он должен возвращать удобный дисплей.

Помимо книги, Python ли вызывает __str__ или __next__ с помощью функций C внутренне как я понял из книги?

ответ

5

реализации Python C использовать функции C, которые являются по существу то же самое, как функции Python, в том, что функции Python как str() и next(), как правило, тонкие обертки вокруг функций 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 int.

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. Если он существует, он вызывается для создания фактической длины. Различные типы могут определять эту функцию, а специальная структура C для . Python экземпляры могут обрабатывать перенаправление обратно на метод 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