资讯专栏INFORMATION COLUMN

[翻译]PEP 7 -- C语言风格指南

Kylin_Mountain / 3298人阅读

摘要:原文介绍这篇文档给出了语言编码的风格约定,包括中用实现的部分。译者注不清楚这里是什么意思,括号中原文为语言版本使用标准年版本。这意味着在许多其他事情中所有声明必须放在某个块的顶部并不一定是函数的顶部。

  

原文http://legacy.python.org/dev/peps/pep-0007/

介绍

这篇文档给出了C语言编码的风格约定,包括Python中用C实现的部分。关于Python编码风格的约定,请参阅PEP-8 [1]

注意,有些约定并不一定要恪守。下面是打破约定的两个很好的理由:

某个约定使得代码难以阅读,即使是对于那些习惯于阅读风格良好的代码的人。

某个约定使得新增代码与已有代码不一致(可能是历史原因导致的)。尽管这也是一个清理别人糟糕代码的好机会(用真正的XP风格)。[译者注:不清楚这里XP是什么意思,括号中原文为 in true XP style]

C语言版本

使用ISO/ANSI标准C(1989年版本)。这意味着(在许多其他事情中)所有声明必须放在某个块的顶部(并不一定是函数的顶部)。

不使用gcc的扩展(例,多行字符串不能不加反斜杠)。

所有函数声明和定义必须使用完整的原型(即,明确写出所有参数的类型)

不使用C++风格的//单行注释

对于主流的编译器(如gcc, VC++等),编译时不能有警告

代码布局

使用4个空格作为缩进,不使用tab

每行不超过79个字符。如果这和上一条规则让你没有空间去编码,那你的代码太复杂了 -- 考虑写成子程序

每行都不应该以空格结尾。如果你认为你的代码中有一些行末的空格很重要,再想想吧 -- 别人的编辑器可能会自动删掉它们。

函数定义风格:函数名写在行首,最外部的大括号写在行首,声明局部变量后空一行。

cstatic 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;
}

代码结构:在if for等关键词与括号之间要有一个空格;在括号内部不要有空格;在C允许的时候,大括号可以不写,但如果写了大括号,它们应该是这样的:

cif (mro != NULL) {
    ...
}
else {
    ...
}

返回语句中不要有多余的括号

creturn Py_None; /* correct */
return(Py_None); /* incorrect */

函数或宏的调用风格foo(a, b, c) -- 函数名和左括号之间没有空格,括号内部没有空格,逗号左边没有空格,每个逗号右边有一个空格

总是在赋值、布尔运算符、比较运算符的两边加上空格。在有许多运算符的表达式中,在最外部(最低优先级)的运算符两边加上空格

很长的行应该被折行:如果可以,在第一个参数的逗号后开始折行。总是合适地缩进剩下的行,例如:

cPyErr_Format(PyExc_TypeError,
             "cannot create "%.100s" instances",
             type->tp_name);

当你对一个长的表达式进行折行的时候,运算符总是在上一行的最末尾:

cif (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 &&
    type->tp_dictoffset == b_size &&
    (size_t)t_size == b_size + sizeof(PyObject *))
    return 0; /* "Forgive" adding a __dict__ only */

在函数、结构的定义、函数中的功能块上下都加上空行

先写注释,再写代码

所有函数和全局变量必须被声明为static,除非它们是发布了的或即将发布的接口

对于所有外部变量和函数,我们总是在一个合适的头文件中声明它,这使用了PyAPI_FUNC()宏,例如:

cPyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
命名约定

对于公共的函数,用Py作为前缀,这不能被用在内部函数上。而Py_这个前缀是留给全局服务程序的如Py_FatalError。而特定的程序组(某个类型的接口)会用更长的前缀,例如PyString_是字符串函数的前缀。

公共的函数和变量使用混合大小写以及下划线的命名规则,如PyObject_GetAttr Py_BuildValue PyExc_TypeError

有时候加载器需要知道一个内部函数的名字,那这个内部函数的名字以下划线开头,如_PyObject_Dump

宏应该使用混合大小写的前缀,然后全部大写,如PyString_AS_STRING Py_PRINT_RAW

文档字符串

使用PyDoc_STR()PyDoc_STRVAR()这两个宏来支持构建没有文档字符串的Python(./configure --without-doc-strings)
对于那些需要支持Python 2.3以上的C代码,你可以在includePython.h后再include这个:

c#ifndef PyDoc_STR
#define PyDoc_VAR(name)         static char name[]
#define PyDoc_STR(str)          (str)
#define PyDoc_STRVAR(name, str) PyDoc_VAR(name) = PyDoc_STR(str)
#endif

每条文档字符串的第一行应该是一个对参数和返回值给出摘要的“签名”,例如:

cPyDoc_STRVAR(myfunction__doc__,
"myfunction(name, value) -> bool


Determine whether name and value make a valid pair.");

在“签名”行和下面的描述行之间总是要有空行
如果返回值总是None(因为没有有意义的返回值),不要包括对返回值的推断

写多行文档字符串时,确保使用反斜杠,比如上面那个例子,或者是用字符串字面连接,如下:

cPyDoc_STRVAR(myfunction__doc__,
"myfunction(name, value) -> bool

"
"Determine whether name and value make a valid pair.");

尽管一些编译器也接受下面这种:

c/* BAD -- don"t do this! */
PyDoc_STRVAR(myfunction__doc__,
"myfunction(name, value) -> bool


Determine whether name and value make a valid pair.");

但不是所有的编译器都接受。比如MSVC的编译器就会抱怨这种。

参考

[1] PEP 8, "Style Guide for Python Code", van Rossum, Warsaw (http://www.python.org/dev/peps/pep-0008)

版权

This document has been placed in the public domain.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37456.html

相关文章

  • 如何用PEP 8编写优雅的Python代码

    摘要:如果需要在二元运算符周围做换行操作,例如和,那么需要将换行操作放在前面,这条规则源于数学,数学家同意在二元运算符之前换行以可提高可读性,比较以下两个例子。在二元运算符之前换行可以让代码更加具有可读性,所鼓励这种方式。 原文地址:How to Write Beautiful Python Code With PEP 8 作者:Jasmine Finer 翻译:howie6879 ...

    seanHai 评论0 收藏0
  • 学习Python,怎能不懂点PEP呢?

    摘要:或许你是一个初入门的小白,完全不知道是什么。到目前为止,它拥有个兄弟姐妹。此外,关于对的贡献,还有一种很有效的方式,就是将翻译成中文,造福国内的学习社区。 或许你是一个初入门Python的小白,完全不知道PEP是什么。又或许你是个学会了Python的熟手,见过几个PEP,却不知道这玩意背后是什么。那正好,本文将系统性地介绍一下PEP,与大家一起加深对PEP的了解。 目前,国内各类教程不...

    Magicer 评论0 收藏0
  • Python3 简明教程

    摘要:课程简介简明易懂的课程,不仅适用于那些有其它语言基础的同学,对没有编程经验的同学也非常友好。建议遵守以下约定使用个空格来缩进永远不要混用空格和制表符在函数之间空一行在类之间空两行字典,列表,元组以及参数列表中,在后添加一个空格。 showImg(https://segmentfault.com/img/bVCldE); 课程简介:简明易懂的 Python3 课程,不仅适用于那些有其它语...

    cyqian 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<