Python编码及项目相关建议
来源:互联网 发布:java视频教程 百度网盘 编辑:程序博客网 时间:2024/06/13 13:44
Python编码及项目相关建议
遵循良好的编码风格,可以有效的提高代码的可读性,降低出错几率和维护难度。在团队开发中,使用(尽量)统一的编码风格,还可以降低沟通成本。
网上有很多版本的编码规范,基本上都是遵循 PEP8 的规范:
- PEP 0008 – Style Guide for Python Code
- Google 的 Python 风格指南
- Python Guide - Code Style
- Pocoo Styleguide
除了手动遵循规范,还有很多有用的工具:
- IntelliJ IDEA 和 PyCharm 的格式化代码功能
- Google 开源的 Python 文件格式化工具:github.com/google/yapf
- pyflakes, pylint 等工具及各种编辑器的插件
缩进
- 不要使用 tab 缩进
- 使用任何编辑器写 Python,请把一个 tab 展开为 4 个空格
- 绝对不要混用 tab 和空格,否则容易出现
IndentationError
空格
- 在 list, dict, tuple, set, 参数列表的
,
后面加一个空格 - 在 dict 的
:
后面加一个空格 - 在注释符号
#
后面加一个空格,但是#!/usr/bin/python
的#
后不能有空格 - 操作符两端加一个空格,如
+
,-
,*
,/
,|
,&
,=
- 接上一条,在参数列表里的
=
两端不需要空格 - 括号(
()
,{}
,[]
)内的两端不需要空格
空行
- function 和 class 顶上两个空行
- class 的 method 之间一个空行
- 函数内逻辑无关的段落之间空一行,不要过度使用空行
- 不要把多个语句写在一行,然后用
;
隔开 if/for/while 语句中,即使执行语句只有一句,也要另起一行
def add_feedback(self, user_id=None, content="", source=-1, app_version=""): if not user_id: return dict(ret=1, msg=u"缺少反馈人信息") if not content: return dict(ret=1, msg=u"请填写反馈信息") if source == -1: log.error(u"add feedback: 缺少来源信息") return dict(ret=1, msg=u"请求有误,请联系管理员") if not app_version: log.error(u"add feedback: 缺少app版本信息") return dict(ret=1, msg=u"请求有误,请联系管理员") try: Feedback.objects.create( user_id=user_id, content=content, source=source, app_version=app_version) return dict(ret=0) except Exception as e: log.error("new feedback error: %s" % str(e)) return dict(ret=1, msg=u"服务器错误")
换行
- 每一行代码控制在 80 字符以内
使用
\
或()
控制换行,举例:def get_customer_statics_list(self, year=None, month=None, sale_id=None, department_id=None, business_id=None, is_superuser=False): new_contract_finances = ContractFinance.objects \ .filter(contract_detail_id__in=new_contract_detail_ids) \ .filter(sale_user_id__in=sale_ids) \ .filter(business_id__in=filter_business_ids) \ .all()text = ('Long strings can be made up ' 'of several shorter strings.')
命名
- 使用有意义的,英文单词或词组,绝对不要使用汉语拼音
- package/module 名中不要出现
-
各种类型的命名规范:
Type Public Internal Moduleslower_with_under
_lower_with_under
Packageslower_with_under
ClassesCapWords
_CapWords
ExceptionsCapWords
Functionslower_with_under()
_lower_with_under()
Global/Class ConstantsCAPS_WITH_UNDER
_CAPS_WITH_UNDER
Global/Class Variableslower_with_under
_lower_with_under
Instance Variableslower_with_under
_lower_with_under
(protected) or__lower_with_under
(private) Method Nameslower_with_under()
_lower_with_under()
(protected) or__lower_with_under()
(private) Function/Method Parameterslower_with_under
Local Variableslower_with_under
import
- 所有 import 尽量放在文件开头,在 docstring 下面,其他变量定义的上面
- 不要使用
from foo imort *
- import 需要分组,每组之间一个空行,每个分组内的顺序尽量采用字典序,分组顺序是:
- 标准库
- 第三方库
- 本项目的 package 和 module
- 不要使用隐式的相对导入(implicit relative imports),可是使用显示的相对导入(explicit relative imports),如
from ..utils import validator
,最好使用全路径导入(absolute imports) 对于不同的 package,一个 import 单独一行,同一个 package/module 下的内容可以写一起:
# badimport sys, os, time# goodimport osimport sysimport time# okfrom flask import Flask, render_template, jsonifyfrom kpi.models import ( SaleYearKpi, SaleMonthKpi, SaleWeekKpi, BusinessYearKpi, DepartmentYearKpi, DepartmentMonthKpi,)
- 为了避免可能出现的命名冲突,可以使用
as
或导入上一级命名空间 - 不要出现循环导入(cyclic import)
注释
- 文档字符串
docstring
, 是 package, module, class, method, function 级别的注释,可以通过__doc__
成员访问到,注释内容在一对"""
符号之间 - function, method 的文档字符串应当描述其功能、输入参数、返回值,如果有复杂的算法和实现,也需要写清楚
不要写错误的注释,不要无谓的注释
# bad 无谓的注释x = x + 1 # increase x by 1# bad 错误的注释x = x - 1 # increase x by 1
优先使用英文写注释,英文不好全部写中文,否则更加看不懂
异常
- 不要轻易使用
try/except
except
后面需要指定捕捉的异常,裸露的except
会捕捉所有异常,意味着会隐藏潜在的问题- 可以有多个
except
语句,捕捉多种异常,分别做异常处理 - 使用
finally
子句来处理一些收尾操作 try/except
里的内容不要太多,只在可能抛出异常的地方使用,如:# badtry: user = User() user.name = "leon" user.age = int(age) # 可能抛出异常 user.created_at = datetime.datetime.utcnow() db.session.add(user) db.session.commit() # 可能抛出异常except: db.session.rollback()# bettertry: age = int(age)except (TypeError, ValueError): return # 或别的操作user = User()user.name = "leon"user.age = ageuser.created_at = datetime.datetime.utcnow()db.session.add(user)try: db.session.commit()except sqlalchemy.exc.SQLAlchemyError: # 或者更具体的异常 db.session.rollback()finally: db.session.close()
对象
关于对象属性操作
# 获取对象属性值if getattr(obj, 'name', None): return obj.name# 判断对象是否有某种属性并返回属性值if hasattr(obj, 'name') and obj.name: return obj.name
字符串
- 使用字符串的
join
方法拼接字符串 - 使用字符串类型的方法,而不是
string
模块的方法 - 使用
startswith
和endswith
方法比较前缀和后缀 - 使用
format
方法格式化字符串
比较
- 空的
list
,str
,tuple
,set
,dict
和0
,0.0
,None
都是False
- 使用
if some_list
而不是if len(some_list)
判断某个list
是否为空,其他类型同理 - 使用
is
和is not
与单例(如None
)进行比较,而不是用==
和!=
- 使用
if a is not None
而不是if not a is None
- 用
isinstance
而不是type
判断类型 - 不要用
==
和!=
与True
和False
比较(除非有特殊情况,如在 sqlalchemy 中可能用到) 使用
in
操作:用
key in dict
而不是dict.has_key()
# badif d.has_key(k): do_something()# goodif k in d: do_something()
- 用
set
加速 “存在性” 检查,list
的查找是线性的,复杂度 O(n),set
底层是 hash table, 复杂度 O(1),但用set
需要比list
更多内存空间
项目结构参考
Flask Web APP
.├── README.md├── app│ ├── __init__.py│ ├── config.py│ ├── forms│ │ ├── __init__.py│ │ └── order.py│ ├── globals.py│ ├── models│ │ ├── __init__.py│ │ ├── base.py│ │ └── hotel.py│ ├── server.conf -> /path/to/app/etc/server.example.conf│ ├── tasks│ │ ├── __init__.py│ │ └── utils.py│ ├── utils│ │ ├── __init__.py│ │ ├── email.py│ │ ├── middleware.py│ │ └── timeutil.py│ └── views│ ├── __init__.py│ └── order.py├── celery_worker.py├── docs│ ├── api│ │ └── kpi.md│ └── api_category.md├── etc│ ├── server.example.conf│ ├── supervisor.example.conf│ └── unicorn.example.py├── fixtures│ └── regions.json.zip├── manage.py├── requirements.txt├── scripts│ └── encrypt.py└── wsgi.py
关于这个问题,在stackoverflow已有相关的讨论。
关于项目文档
文档有项目说明文档,以及项目安装文档,接口文档。完善的文档可以方便团队协作,节省沟通成本。
CRM项目的文档就比较全。我个人还是比较习惯写文档。
其他
- 使用列表表达式(list comprehension),字典表达式(dict comprehension, Python 2.7+) 和生成器(generator)
dict
的get
方法可以指定默认值,但有些时候应该用[]
操作,使得可以抛出KeyError
- 使用
for item in list
迭代list
,for index, item in enumerate(list)
迭代list
并获取下标 - 使用内建函数
sorted
和list.sort
进行排序 - 适量使用
map
,reduce
,filter
和lambda
,使用内建的all
,any
处理多个条件的判断 - 使用
defaultdict
(Python 2.5+),Counter
(Python 2.7+) 等 “冷门” 但好用的标准库 - 使用装饰器(decorator)
- 使用
logging
记录日志,配置好格式和级别 - 了解 Python 的 Magic Method:A Guide to Python’s Magic Methods, Python 魔术方法指南
- 阅读优秀的开源代码,如 Flask 框架, Requests for Humans
- 不要重复造轮子,查看标准库、PyPi、Github、Google等使用现有的优秀的解决方案
阅读全文
0 0
- Python编码及项目相关建议
- python 相关编码
- Python编码相关问题
- Python使用细节及建议
- python初学者须知的一些编码建议
- Python 常用 PEP8 编码规范和建议
- Python——编码风格建议
- 给Python新手的一些编码建议
- 给Python新手的一些编码建议
- PHP学习建议及编码规范
- Python编码相关文章推荐
- python 编码相关问题总结
- 编码相关2 python编码 之 基本原理
- 图片格式相关,及内存优化建议
- java相关安全漏洞及整改建议
- netmap及相关项目
- python 爬虫及相关
- python编码及文件编ASCII,Unicode和UTF-8相关知识
- html之input 的非空验证
- Oracle Rac 11R2添加节点
- iOS 照片自定义裁剪
- BGP中的Status codes
- 【bzoj4027】[HEOI2015]兔子与樱花(树上贪心)
- Python编码及项目相关建议
- 考试总结
- html 省略列表内容过长
- I/O多路复用之select
- Linux Device和Driver 注册,match以及Probe 过程
- 浅谈CTF中命令执行与绕过的小技巧
- Oracle用户-新增、维护
- 曾鸣:互联网的本质是什么?| 内部干货
- java.lang.IndexOutOfBoundsException: Invalid item position 0(0). Item count:0