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