为NumPy贡献 > NumPy C风格指南
NumPy C编码约定基于Guido van Rossum的Python PEP-0007,并增加了一些限制。有许多C编码约定,必须强调的是,NumPy约定的主要目标不是选择“最佳”,肯定会有分歧,而是要实现统一。由于NumPy约定与PEP-0007中的约定非常接近,因此该PEP在以下用作模板,并在适当位置添加了NumPy并进行了更改。
本文档给出了包含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语句应该不会让多余的括号:
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
,其中合适的是星号。
Public Macros应该有一个NPY_
前缀,然后使用大写字母,例如NPY_DOUBLE
。
私有函数应使用小写并带有下划线,例如:
array_real_get
。不应使用单个前划线,但由于历史原因,某些当前函数名称违反了该规则。这些功能应在某些时候重命名。
NumPy目前没有C函数文档标准,但需要一个。大多数numpy函数未在代码中记录,因此应该更改。一种可能性是带有插件的Doxygen,以便用于Python函数的NumPy样式也可以用于记录C函数,请参阅doc / cdoc /中的文件。