Руководство по стилю NumPy на C
Конвенции кодирования NumPy на C основаны на Python PEP-0007, разработанном Гайдо ван Россумом, с добавлением нескольких строгих правил. Существует множество конвенций кодирования на C, и необходимо подчеркнуть, что основная цель конвенций NumPy — не выбрать «лучшую» (по поводу которой неизбежно возникнет разногласие), а добиться единообразия. Поскольку конвенции NumPy очень близки к конвенциям PEP-0007, этот PEP используется в качестве шаблона ниже с добавлением и изменениями, соответствующими конвенциям NumPy.
Введение
В данном документе приводятся конвенции кодирования для C-кода, составляющего реализацию NumPy на C. Заметьте, правила существуют для того, чтобы их нарушать. Две хорошие причины для нарушения конкретного правила:
- Если применение правила сделает код менее читаемым, даже для того, кто привык читать код, соответствующий правилам.
- Если это необходимо для согласованности с окружающим кодом, который также нарушает это правило (возможно, по историческим причинам). Хотя это также возможность исправить чужие ошибки.
Диалект 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