python编写规范

https://www.cnblogs.com/wangcp-2014/p/4838952.html

一、说明

二、内容

  1. 代码布局

    1.1 缩进

    1.2 表达式和语句中的空格

    1.3 行的最大长度

    1.4 空行... 

    1.5 编码... 

 2. 语句... 

扫描二维码关注公众号,回复: 5493301 查看本文章

    2.1 标准头部... 

    2.2 导入(import)... 

    2.3 赋值... 

    2.4 分支和循环... 

 3. 注释... 

    3.1 注释块... 

    3.2 行内注释... 

    3.3 文档字符串... 

    3.4 版本注记... 

    3.5 模块注释... 

    3.6 函数和方法注释... 

    3.7 类注释... 

 4. 命名约定... 

    4.1 说明:命名约定... 

    4.2 模块名... 

    4.4 类名... 

    4.5 异常名... 

    4.6 变量、常量、全局变量名... 

    4.7 函数名... 

    4.8 方法名和实例变量... 

    4.9 特定的命名方式... 

 5. 继承的设计... 

 6. 设计建议... 

一、   说明

为了规范Python代码的书写,提高代码的可读性,使编码人员在代码上更好的协作,制定了本规范。

中标软件有限公司测试中心员工在编写Python代码时,必须遵守本规范。如对规范有异议,请联系维护人员。

编码规范的作用:

  • 提高可读性 ——“任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员。”编码规范,帮助我们写出人类容易理解的代码。
  • 统一全局,促进团队协作—— 开发是一个团队活动,而不是个人的英雄主义。
  • 有助于知识传递,加快工作交接 ——风格的相似性,能让编码人员更迅速,更容易理解一些陌生的代码,更快速地理解别人的代码。
  • 减少名字增生,降低维护成本 ——在没有规范的情况下,很容易为同一类型的实例起不同的名字。
  • 强调变量之间的关系,降低缺陷引入的机会 ——命名可以表示一定的逻辑关系,使开发人员在使用时保持警惕,从而一定程度上减少缺陷被引入的机会。
  • 提高个人能力 。

二、   内容

1. 代码布局

1.1 缩进

推荐以4个空格作为一个缩进层次。

1.2 表达式和语句中的空格

1. 前导空格(缩进)

最流行的Python缩进方式是仅使用空格,其次是仅使用制表符。对于新的项目,应该仅使用空格而不是制表符。

2. 非前导空格

非前导空格在Python代码中没有意义,但适当地加入非前导空格可以增进代码可读性:

(1)在二元算术、逻辑运算符前后加空格,如:

示例:

a = b + c

if a and b:

    pass

(2)在一元前缀运算符后不加空格,如:

示例:

if !flg:

pass

(3)“:”用在行尾时前后皆不加空格,如分支、循环、函数和类定义语言;用在非行尾时后端加空格,如dict对象的定义:

示例:

d = {'key''value'}

(4)括号(含圆括号、方括号和花括号)前后不加空格,如:

示例:

do_something(arg1, arg2)

(5)逗号后面加一个空格,前面不加空格。

1.3 行的最大长度

每行的最大长度不得超过80个字符的标准。超过80个字符的,建议使用以下方式将单个长行折叠成多个短行:

(1)为长变量名换一个短名,如:

错误写法:

this.is.a.very.long.variable_name = this.is.another.long.variable_name

正确写法:

variable_name1 = this.is.a.very.long.variable_name

variable_name2 = this.is.another.variable_name

variable_name1 = variable_name2

(2)在括号(包括圆括号、方括号和花括号)内的分隔符后换行,如:

示例:

class Edit(Base):

    def __init__(self, parent, width,

    font = FONT, color = BLACK, pos = POS, style = 0):  # 注意:此行与上一行保持同样缩进

        pass

(3)在长行加入续行符强行断行,断行的位置应在操作符前,如:

示例:

if color == WHITE or color == BLACK \

or color == BLUE:  # 注意:换行与首行保持同样的缩进(或均不缩进)

    do_something(color)

1.4 空行

输入空行时,一般遵循以下原则:

(1)在import不同种类的模块间加空行;

(2)顶层函数和类的定义之间加空行;

(3)在类与类的定义之间加空行;

(4)在函数与函数的定义之间加空行;

(5)在class定义行和其第一个方法定义之间加空行;

(6)在函数中的逻辑段落间加空行,即把相关的代码紧凑写在一起,作为一个逻辑段落,段落间以空行分隔。

1.5 编码

所有的Python脚本文件都应在文件头标上#-*- coding:utf8 -*- ;用于设置编辑器,默认保存为utf8格式:

#-*- coding:utf8 -*-

2. 语句

2.1 标准头部

一般情况下使用如下标准头部语句:

#!/usr/bin/python

如果需要使用自定义的Python编译环境,可使用类似如下的头部语句:

#!/usr/bin/env python2.7

说明:该行语句的作用是帮助内核找到Python解释器,但通常在Python导入模块时被忽略;只有直接执行单个文件时,该语句才是必要的。

2.2 导入(import)

1. 通常应该在单独的行中导入(import),例如“正确写法1”;若需要在一行中从一个模块导入多个类,可参照“正确写法2”:

错误写法:

import sys, os

正确写法1

import sys

import os

正确写法2

from types import StringType, ListType

2. 导入语句的位置及导入顺序

通常将import语句放置在文件的顶部,仅在模块注释和文档字符串之后,在模块的全局变量和常量之前。导入语句应该有顺序地成组安放:

(1)首先,导入标准库(内置模块);

(2)其次,导入第三方模块(引用的第三方包);

(3)最后,导入自己开发的项目中的其他模块;

在每组导入之间放置一个空行。

3. 导入类的方法

从一个包含类的模块中导入类时,通常可以写成这样:

示例:

from MyClass import MyClass

from foo.bar.YourClass import YourClass

如果上述写法导致了本地名字冲突,那么就这样写:

示例:

import MyClass

import foo.bar.YourClass

然后使用MyClass.MyClass和foo.bar.YourClass.YourClass方式即可。

2.3 赋值

对于赋值语言,主要是不要做无谓的对齐,如:

错误写法:

a        = 1

var      = 2

fn       = callback_function

正确写法:

a = 1

var = 2

fn = callback_function

2.4 分支和循环

各种分支和循环语句不要写成一行,如:

错误写法:

if !flg: pass

for i in xrange(10): print i

正确写法:

if !flg:

    pass

for i in xrange(10):

    print i

3. 注释

代码修改时,始终优先更新注释。注释应该是完整的句子,如果注释是一个短语或句子,首字母应该大写,除非他是一个以小写字母开头的标识符(如果以中文注释可忽略此要求)。

3.1 注释块

注释块通常用于跟随着一些代码并和这些代码有着相同的缩进层次。注释块中每行均以“#”和一个空格开始。注释块内的段落间以仅含单个“#”的行分割。注释块上下方最好各有一空行。

3.2 行内注释

行内注释是和语句在同一行的注释。行内注释应该至少用两个空格和语句分开,且应该以“#”和单个空格开始,如:

示例:

x = x + 1  # Increment x

如果语意很明了,那么行内注释则不必要。

3.3 文档字符串

为所有公共模块、函数、类和方法编写文档字符串。文档字符串对非公开的方法不是必要的,但应该有一个注释描述这个方法的作用。这个注释应该在“def”行之后。

一定注意,多行文档字符串结尾的"""应该单独成行,例如:

示例:

"""Return a foobang

Optional plotz says to frobnicate the bizbaz first

"""

对单行的文档字符串,结尾的"""在同一行也可以,例如:

"""Return a foobang"""

3.4 版本注记

版本注记可以参照如下示例代码:

示例:

__version__ = "$Revision: 1.4 $"

这行应该包含在模块的文档字符串之后,所有代码之前,上下用一个空行分割。

3.5 模块注释

每个模块注释都应该包含下列项,依次是:

(1)版权声明;

(2)模块注释内容,包括模块描述、模块中的类和方法的描述、版本及维护信息等;

(3)作者声明,标识文件的原作者;

示例:

# Copyright (C), 2010-2013, China Standard Software Co., Ltd.

"""

FileName: Test.py

Author: fei.liu

Version: 0.1

Date: 2013-02-27

Description: 用一行文字概述模块或脚本,用句号结尾。

    ClassFoo: 一行概述该模块中的类的用途。

    functionBar(): 一行概述该模块中的函数的用途。

History: /* 历史修改记录 */

<Author>   <Date>   <Version>   <Desc>

fei.liu  2013-03-04   1.0      Release

"""

__authors__ = [

  '"John Smith" <[email protected]>',

  '"Joe Paranoid" <[email protected]>',

]

3.6 函数和方法注释

任何函数或方法都需要一个文档字符串,对于任何外部可访问的函数或方法,文档字符串尤为重要。

文档字符串应该包含函数的作用,以及参数、输入和输出的详细描述:

(1)Args:输入参数的具体描述;如果参数要求特定的数据类型或者设置了参数的默认值,那么应该在文档字符串中明确说明;

(2)Returns:输出(返回)数据的具体描述;

(3)Raises:应该列出该函数可能触发的所有异常;

示例:

def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):

    """取出表格中的多行内容

    Retrieves rows pertaining to the given keys from the Table instance

    represented by big_table.  Silly things may happen if

    other_silly_variable is not None.

 

    Args:

        big_table: An open Bigtable Table instance.

        keys: A sequence of strings representing the key of each table rowto fetch.

        other_silly_variable: Another optional variable, that has a much

            longer name than the other args, and which does nothing.

    Returns:

        A dict mapping keys to the corresponding table row data fetched.

Each row is represented as a tuple of strings. For example:

        {'Serak': ('Rigel VII', 'Preparer'),

         'Zim': ('Irk', 'Invader'),

         'Lrrr': ('Omicron Persei 8', 'Emperor')}

        If a key from the keys argument is missing from the dictionary,

        then that row was not found in the table.

    Raises:

        IOError: An error occurred accessing the bigtable.Table object.

    """

    pass

3.7 类注释

类定义下方必须有一个用于描述该类的文档字符串(docString)。如果类中有公共属性(Attributes),那么文档字符串中应该说明这些公共属性的意义。

示例:

class SampleClass(object):

    """Summary of class here.

    Longer class information....

    Longer class information....

 

    Attributes:

        likes_spam: A boolean indicating if we like SPAM or not.

        eggs: An integer count of the eggs we have laid.

    """

 

    def __init__(self, likes_spam=False):

        """Inits SampleClass with blah."""

        self.likes_spam = likes_spam

        self.eggs = 0

 

    def public_method(self):

        """Performs operation blah."""

4. 命名约定

4.1 说明:命名约定

禁止使用字符“l”、“O”或“I”作为单字符的变量名。在某些字体中无法将这些字符与数字1和0区分开。

4.2 模块名

模块名应该是不含下划线的、简短的、全小写的名字;对于默认仅在包(Packages)内使用的模块,可以加一个下划线前缀,如:

示例:

module.py

_internal_module.py

4.4 类名

类名使用CapWords约定(单词首字母大写,不使用下划线连接单词,也不加入C、T等前缀);内部使用的类需要在名称前加一个前导下划线,如:

示例:

class ThisIsAClass(object):

pass

class _ThisIsAClass(object):

pass

4.5 异常名

异常名使用CapWords命名规则(单词首字母大写,不使用下划线连接单词)。

4.6 变量、常量、全局变量名

Python一般通过“from M import *”来从模块中导入相关内容(变量、类、函数等),必须用一个下划线作全局变量(内部函数或类)的前缀防止其被导出(exporting)。

1. 常量

常量名的所有字母均大写,由下划线连接各个单词,如:

示例:

WHITE = 0XFFFFFF

THIS_IS_A_CONSTANT = 1

2. 变量

(1)变量名全部小写,由下划线连接各个单词,如:

示例:

color = WHITE

this_is_a_variable = 1

(2)不论是类成员变量还是全局变量,均不使用m或g前缀。私有类成员使用单一下划线前缀标识;

(3)变量名不应带有类型信息,因为Python是动态类型语言;如iValue、names_list、dict_obj等都是不好的命名。

3. 全局变量

必须用一个下划线作为全局变量的前缀防止其被导出。

4.7 函数名

函数名应该为小写,可用下划线风格单词以增加可读性。

4.8 方法名和实例变量

大体上和函数命名规则相同:通常使用小写单词,必要时用下划线分隔增加可读性。

如果是不打算对外公开的内部方法和实例,需要在名称开头使用一个前导下划线。

使用两个前导下划线以表示类私有成员的名字。通常双前导下划线仅被用于避免含子类的类中的属性名冲突。

4.9 特定的命名方式

主要是指__xxx__形式的系统保留字命名法。项目中也可以使用这种命名,它的意义在于这种形式的变量是只读的,这种形式的类成员函数尽量不要重载。如:

示例:

class Base(object):

    def __init__(self, id, parent = None):

        self.__id__ = id

        self.__parent__ = parent

    def __message__(self, msgid):

        # ...

其中__id_、__parent__和__message__都采用了系统保留字命名法。

5. 继承的设计

始终要确定一个类中的方法和实例变量是否要被公开。通常,永远不要将数据变量公开,除非你实现的本质上只是记录,人们总是更喜欢为类提供一个函数的接口来实现数据变量的修改。

同样,确定你的属性是否应为私有的。私有和非私有的区别在于:前者永远不会被用在一个派生类中,而后者可能会。你应该在大脑中就用继承设计好了你的类:(1)私有属性必须有两个前导下划线,无后置下划线;(2)非公有属性必须有一个前导下划线,无后置下划线;(3)公共属性没有前导和后置下划线,除非它们与保留字冲突,在此情况下,单个后置下划线比前置或混乱的拼写要好,例如:class_优于klass。

6. 设计建议

单个元素(singletons)的比较,如None应该使用“is”或“is not”。当你本意是“if x is not None”时,对写成“if x”要小心。例如当你测试一个默认为None的变量或参数是否被设置为其它值时,这个其它值也许在布尔上下文(Boolean context)中是False。

基于类的异常总是好过基于字符串的异常。模块和包应该定义它们自己的域内特定的基异常类,基类应该是内建的Exception类的子类,还始终包含一个类的文档字符串。例如:

示例:

#!/usr/bin/Python

 

class(Exception):

"""Base class for errors in the email package."""

MessageError

使用字符串方法(methods)代替字符串模块,除非必须向后兼容Python 2.0以前的版本。字符串方法总是非常快,而且和unicode字符串共用同样的API(应用程序接口),在检查前缀或后缀时避免对字符串进行切片。用startswith()和endswith()代替,因为这样出现错误的机率更小。例如:

错误写法:

if foo[:3] == 'bar':

正确写法:

if foo.startswith('bar'):

特殊情况下,如果你的代码必须工作在Python 1.5.2,对象类型的比较应该始终用isinstance()代替直接比较类型,例如:

错误写法:

if type(obj) is type(1):

正确写法:

if isinstance(obj, int):

检查一个对象是否是字符串时,谨记它也可能是unicode字符串!在Python 2.3中,str和unicode有公共的基类basestring,所以你可以这样做:

if isinstance(obj, basestring):

在Python 2.2类型模块为此定义了StringTypes类型,例如:

#!/usr/bin/Python

 

from types import StringTypes

 

if isinstance(obj, StringTypes):

对序列(字符串、列表、元组)而言,使用空列表是false这个事实,因此“if not seq”或“if seq”比“if len(seq)”或“if not len(seq)”好。书写字符串文字时不要依赖于有意义的后置空格。这种后置空格在视觉上是不可辨别的,并且有些编辑器会将它们修整掉。不要用“==”来比较布尔型的值以确定是True或False(布尔型是Python2.3中新增的):

错误写法:

if greeting == True:

正确写法:

if greeting:

 
 

猜你喜欢

转载自www.cnblogs.com/linkenpark/p/10511065.html