Spec-Zone.ru › NumPy 1.19

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

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

Введение

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

  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 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 не было единого префикса, но все они начинаются с префикса, за которым следует символ подчеркивания, и написаны в стиле camelCase: 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.19/dev/style_guide.html

Spec-Zone.ru

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