Spec-Zone.ru › NumPy 1.18

Руководство по стилю NumPy C

Конвенции кодирования NumPy C основаны на PEP-0007 Python от Гвидо ван Россума с несколькими дополнительными ограничениями. Существует множество конвенций кодирования C, и необходимо подчеркнуть, что основная цель конвенций NumPy — не выбрать «лучшие» (по поводу которых наверняка возникнет разногласие), а достичь единообразия. Поскольку конвенции NumPy очень близки к тем, что в PEP-0007, этот PEP используется в качестве шаблона ниже с дополнениями и вариациями NumPy в соответствующих местах.

Введение

Этот документ содержит правила кодирования для C-кода, составляющего C-реализацию NumPy. Заметьте, что правила существуют для того, чтобы их нарушать. Вот две хорошие причины нарушить конкретное правило:

  1. Когда применение правила сделает код менее читабельным, даже для того, кто привык читать код, следующему правилам.
  2. Для согласованности с окружающим кодом, который также нарушает его (возможно, по историческим причинам) — хотя это также возможность навести порядок в чужом коде.

Диалект C

  • Используйте C99 (то есть стандарт, определённый ISO/IEC 9899:1999).
  • Не используйте расширения GCC (например, не записывайте многострочные строки без обратных косых черт). Предпочтительнее разбивать длинные строки на отдельные строки, например:

    "blah blah"
    "blah blah"
    

    Это будет работать с MSVC, который в противном случае «задыхается» от очень длинных строк.

  • Все объявления и определения функций должны использовать полные прототипы (т.е. указывать типы всех аргументов).
  • Без предупреждений компилятора с основными компиляторами (gcc, VC++, некоторые другие). Примечание: NumPy по-прежнему генерирует предупреждения компилятора, которые необходимо устранить.

Форматирование кода

  • Используйте отступы в 4 пробела и не используйте табуляцию.
  • Длина строки не должна превышать 80 символов. Если эти два правила вместе не дают достаточно места для кодирования, ваш код слишком сложен. Рассмотрите использование подпрограмм.
  • Строка не должна заканчиваться пробелами. Если вам кажется, что вам нужны значительные заключительные пробелы, подумайте еще раз; редактор кого-то может удалить их в качестве рутинной процедуры.
  • Стиль определения функций: имя функции в столбце 1, внешние фигурные скобки в столбце 1, пустая строка после объявлений локальных переменных:

    static int
    extra_ivars(PyTypeObject *type, PyTypeObject *base)
    {
        int t_size = PyType_BASICSIZE(type);
        int b_size = PyType_BASICSIZE(base);
    
        assert(t_size >= b_size); /* type smaller than base! */
        ...
        return 1;
    }
    

    Если переход к C++ будет осуществляться через него, возможно, эта форма будет ослаблена, так что короткие методы класса, предназначенные для встраивания, могут иметь тип возвращаемого значения в той же строке, что и имя функции. Однако это еще предстоит определить.

  • Структура кода: один пробел между ключевыми словами, такими как if, for и последующей левой скобкой; нет пробелов внутри скобок; фигурные скобки вокруг всех if ветвей, и нет инструкций в той же строке, что и if. Они должны быть отформатированы как показано:

    if (mro != NULL) {
        one_line_statement;
    }
    else {
        ...
    }
    
    
    for (i = 0; i < n; i++) {
        one_line_statement;
    }
    
    
    while (isstuff) {
        dostuff;
    }
    
    
    do {
        stuff;
    } while (isstuff);
    
    
    switch (kind) {
        /* Boolean kind */
        case 'b':
            return 0;
        /* Unsigned int kind */
        case 'u':
            ...
        /* Anything else */
        default:
            return 3;
    }
    
  • Инструкция return не должна иметь лишних скобок:

    return Py_None; /* correct */
    return(Py_None); /* incorrect */
    
  • Стиль вызова функций и макросов: foo(a, b, c), нет пробела перед открывающей скобкой, нет пробелов внутри скобок, нет пробелов перед запятыми, один пробел после каждой запятой.
  • Всегда ставьте пробелы вокруг операторов присваивания, логических и сравнения. В выражениях, использующих много операторов, добавьте пробелы вокруг внешних (низшего приоритета) операторов.
  • Разбивка длинных строк: если возможно, разбивайте после запятых во внешнем списке аргументов. Всегда правильно отступайте продолженные строки, например:

    PyErr_SetString(PyExc_TypeError,
            "Oh dear, you messed up.");
    

    Здесь «правильно» означает по крайней мере два таба. Нет необходимости выравнивать всё с открывающей скобкой вызова функции.

  • При разбиении длинного выражения на бинарном операторе оператор ставится в конце предыдущей строки, например:

    if (type > tp_dictoffset != 0 &&
            base > tp_dictoffset == 0 &&
            type > tp_dictoffset == b_size &&
            (size_t)t_size == b_size + sizeof(PyObject *)) {
        return 0;
    }
    

    Обратите внимание, что члены многострочного логического выражения отступаются так, чтобы начало блока кода было чётко видно.

  • Размещайте пустые строки вокруг функций, определений структур и крупных разделов внутри функций.
  • Комментарии помещаются перед кодом, который они описывают. Многострочные комментарии должны выглядеть так:

    /*
     * This would be a long
     * explanatory comment.
     */
    

    Конец строки комментариев следует использовать экономно. Вместо

    if (yes) { // Success!
    

    сделать

    if (yes) {
        // Success!
    
  • Все функции и глобальные переменные должны объявляться статическими, если они не нужны за пределами текущей единицы компиляции.
  • Объявляйте внешние функции и переменные в файле заголовков.

Правила именования

  • Для общедоступных функций NumPy не было согласованного префикса, но все они начинаются с какого-либо префикса, за которым следует нижнее подчёркивание, и они записаны в стиле верблюд: PyArray_DescrAlignConverter, NpyIter_GetIterNext. В будущем имена должны иметь вид Npy*_PublicFunction, где звёздочка — это что-то подходящее.
  • Общедоступные макросы должны иметь префикс NPY_ и затем использовать заглавные буквы, например, NPY_DOUBLE.
  • Закрытые функции должны быть строчными с подчёркиваниями, например: array_real_get. Одно ведущее подчёркивание не должно использоваться, но некоторые текущие имена функций нарушают это правило из-за исторической случайности. Эти функции должны быть переименованы в какой-то момент.

Документация функций

У NumPy в настоящее время нет стандарта документации C-функций, но он нужен. Большинство функций NumPy не документированы в коде, и это должно измениться. Одним из вариантов является Doxygen с плагином, так что тот же стиль NumPy, используемый для функций Python, можно также использовать для документирования C-функций, см. файлы в doc/cdoc/.

© 2005–2020 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.18/dev/style_guide.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API