Skip to content

Python编码规范

JeremyXING edited this page May 25, 2016 · 1 revision

本文档描述Byway采用的Python编码规范。大家共勉

IDE设置

采用PyCharm CE和Sublime Text作为本项目后台通用编辑器

代码布局

缩进

使用tab符作为缩进,tab符的长度为4

空行

  • 用两行空行分割顶层函数和类的定义,类内方法的定义用单个空行分割。
  • 10个空行可用于分隔多个函数组成的功能群
  • 在函数内部,使用1个空行分隔逻辑段

编码及换行格式

  • 编码设置为utf-8
  • 换行格式设置为unix风格
  • 所有py文件的第一行都必须进行编码声明:
# -*- coding: utf-8 -*-

导入(import)

  • imports 通常被放置在文件的顶,在模块注释和文档字符串之后,在模块的全局变量和常量之前。imports应该有顺序地成组安放:
  1. python标准库的导入
  2. 相关主包的导入(django相关包)
  3. web应用自己的包的导入
  • 在上面提到的每组导入之间应该插入一行空格

  • 对于内部包的导入是不推荐使用相对导入的,对所有导入都要使用包的绝对路径。

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

from MyClass import MyClass
from foo.bar.YourClass import YourClass

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

import MyClass
import foo.bar.YourClass

然后这样使用类:

MyClass.MyClass
foo.bar.YourClass.YourClass

空格

  • 所有括号前后都不要有空格
spam( ham[ 1 ], { eggs: 2 } ) #不要这样写
spam(ham[1], {eggs: 2}) #要这样写
  • 逗号,分号,冒号前不要有空格
if x ## 4 : print x , y ; x , y = y , x #不要这样写
if x ## 4: print x, y; x, y = y, x #要这样写
  • 函数名与函数参数列表之间不要有空格
spam (1) #不要这样写
spam(1) #要这样写
  • 索引和切片(slicing)前不要有空格
dict ['key'] = list [index] #不要这样写
dict['key'] = list[index] #要这样写
  • 始终在二元运算符前后放置且只放置一个空格:赋值(=),比较(##, <, >, !=, <>, <=,>=, in, not in, is, is not),布尔运算 (and, or, not)。
#不要这样写 x = 1 y = 2 long_variable = 3
#要这样写 x = 1 y = 2 long_variable = 3

 * 例外不要在用于指定关键字参数或默认参数值的'='号周围使用空格```python
def complex(real, imag=0.0):
  return magic(r=real, i=imag)

- 不要将多条语句写在同一行上:
```python 
#不要这样做 if foo ## 'blah': do_blah_thing()
#要这样做 if foo ## 'blah': do_blah_thing()

#不要这样做 do_one(); do_two(); do_three()

#要这样做 do_one() do_two() do_three()

注释

  • 主要使用中文来完成注释。注释最重要的目的是让别人清楚你所表达的意思。如果能确认用英文更清楚表达意思,可以使用英文。
  • 同代码不一致的注释比没注释更差。当代码修改时,始终优先更新注释!
  • 注释应该是完整的句子,准确,简洁。

注释块

  • 注释块通常应用于跟随着一些(或者全部)代码并和这些代码有着相同的缩进层次。
  • 注释块中每行以'#'开始,注释块内的段落以仅含单个'#'的行分割。
  • 函数、类的注释块通过Aptana中的Ctrl+4快捷键产生
###############################################################################=
# list_news : 显示要闻列表
###############################################################################=
@permission_required('auth.role_editor', login_url="/")
def list_news(request, create_date, cur_page):
  if 'today' ## create_date:
    create_date = time.strftime("%Y-%m-%d")

  #构造用户设置datepicker的default date
  #这里描述够则的算法...
  default_date = [int(x) for x in create_date.split('-')]
  default_date[1] -= 1

行内注释

  • 一个行内注释是和语句在同一行的注释。
  • 行内注释应该<>,行内注释应该至少用两个空格和语句分开,它们应该以'#'开始.
x = x+1  #Increment x
  • 如果语意是很明了的,那么行内注释是不必要的,事实上上面的行内注释是应该被去掉的。

命名

命名风格

  • 命名一般采用unix的c风格,不采用Java的userName风格,应该是user_name
  • 命名中的单词必须是完整的单词,不允许出现缩写形式
btn = Button() #不要这样写
button = Button() #要这样写
  • 常量使用全大写命名
PAGE_COUNT = 20
  • 类的私有函数以两个下划线开始
class Button(object):
def __get_button_name():
 pass
...

命名约定

模块名

  • 模块应该是不含下划线的,简短的,全小写的名字,因为模块名被映射到文件名, 有些文件系统大小写不敏感并且截短长名字。
  • 一个更高层(例如,更面向对象)的接口时,C/C++模块有一个前导下划线(如:_socket)
  • Python包(package)应该是不含下划线的,简短的,全小写的名字。

类名

  • 采用与Java相同的命名约定,类名总是使用首字母大写单词串(CapWords)。

函数名

  • 函数名全小写,单词与单词之间用下划线链接,采用unix的c风格

特殊变量命名

  • 集合变量全部以负数形式命名:
```python 
#不要这样写 name_list = [...] for name in name_list: ...
#要这样写 names = [...] for name in names: ...
  • dict的变量命名要采用x2y的形式,x是key的命名,而v是value的命名:
```python
#不要这样写
name_age_dict = {...}
for name, age in name_age_dict.items():
  ...

#要这样写
name2age = {...}
for name, age in name2age.items():
  ...

设计建议

  • 在检查前缀或后缀时避免对字符串进行切片。用startswith()和endswith()代替,因为它们是明确的并且错误更少。例如:
if foo[:3] ## 'bar':  #不要这样写
if foo.startswith('bar'):  #要这样写
  • 对象类型的比较应该始终用isinstance()代替直接比较类型:
if type(obj) is type(1):  #不要这样写
if isinstance(obj, int):  #要这样写
  • 对序列(字符串(string),列表(list),元组(tuple)),使用空列表是false这个事实,因此"if not seq"或"if seq"比 "if len(seq)"或"if not len(seq)"好。
  • 不要用 ## 来比较布尔型的值以确定是True或False:
if greeting ## True:  #不要这样写
if greeting:  #要这样写