文章目录
主要是针对python语言,应当充分利用python语法,但不应过度追求奇淫技巧。
引言
编写pythonic代码
- 避免只用大小写来区分不同的对象
- 避免使用容易引起混淆的名称,变量名要与所要解决的问题域一致
- 不要害怕过长的变量名
- 学会使用库(flask,gevent,requests等)
风格检查程序pycodestyle
学会使用风格检查程序pycodestyle
pip install pycodestyle
然后运行代码如下,可以看到建议
如果觉得报告不够细致,可以加上–show-source
理解python与C的不同
- 缩进来分隔代码块
- 不支持
C ? X:Y
, 应该使用X if C else Y
- 没有
switch...case
在代码中适当加入注释
- 注释和代码最好隔开一段距离
- 函数要注释
- 文件要注释
适当添加空行使代码布局更加优雅
- 完整表达完一个思路后,使用空白行进行间隔
- 函数调用的话,尽可能放在一起,调用者在上,被调用者在下
- 避免过长的代码行。超过的部分使用圆括号、方括号、花括号进行行连接,尽可能对齐。
编写函数的四个原则
- 函数设计尽量短小,嵌套层次不宜过深
- 参数不要过多
- 考虑向下兼容,加入默认参数来避免退化
def readfile(filename,logger=logger.info)
- 一个函数只做一件事情,尽量保证函数语句粒度的一致性。
将常量集中到一个文件
- 通过自定义的类实现常量功能。
很关键,对常量修改和命名不符合规范时都会报错
const.py
class _const(object):
class ConstError(TypeError):pass # TypeError 指对类型无效的操作
class ConstCaseError(ConstError):pass
def __setattr__(self, key, value): # 在对类的属性赋值时会自动调用
if key in self.__dict__: # object.__dict__以dict的形式保存了object内所有可写的属性,name为变量名,value为变量值。
raise self.ConstError("Can't change const.%s" % key)
if not key.isupper():
raise self.ConstCaseError("const name '%s' is not all uppercase" % key)
self.__dict__[key] = value
import sys
sys.modules[__name__] = _const()
# sys.modules保存有当前Python环境中已经导入的模块记录,这是一个全局字典,当Python启动后就加载在内存中。
# dict的key为文件名,value为模块对象。
# __name__就是标识模块的名字的一个系统变量。
# sys.modules['const'] = _const()
# 即,让_const类作为模块的入口点,引入const.py等价于声明了一个_const类的实例。
使用的时候只需要import const就可以直接定义常量了
import const
const.COMPANY = ‘IBM’
一旦赋值则不可以修改,也不可以小写
声明常量,将存放常量的文件命名为constant.py:
import const
const.COMPANY = 'IBM'
const.MY_CONST = 'ABC'
当其他模块引用常量时,按照如下方式进行即可:
from constant import const
print(const.COMPANY)
print(const.MY_CONST+'d')
编程惯用法
利用assert语句来发现问题
assert主要是调试程序服务,能够快速方便检查程序异常或发现不恰当的输入
assert expression1 [",",expression2]
expression1是条件,如果不对则返回false并输出expression2的错误信息
eg:
会对性能有影响,如果用 python -O pythonname.py
可以忽略断言语句
来测试语句的执行时间
from timeit import Timer
Timer('x,y=y,x','x=2;y=3').timeit()
充分利用Lazy evaluation的特性
Lazy evaluation:延迟计算,惰性计算,指的是仅仅在真正需要执行的时候才计算表达式。
好处:
避免不必要的计算,带来性能上的提升,
比如 if x and y,if x or y
如果对于or条件表达式,应该将值为真可能性较高的变量写在or的前面,而and则应该推后
节省空间,使得无限循环的数据结构成为可能,
比如生成器,仅在每次需要计算的时候才通过yield产生所需要的元素
from itertools import islice
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a+b
print(list(islice(fib(),5)))
结果:[0, 1, 1, 2, 3]
介绍一下yield:yield的函数是一个生成器,而不是一个函数了,这个生成器有一个函数就是next函数,next就相当于“下一步”生成哪个数,这一次的next开始的地方是接着上一次的next停止的地方执行的,所以调用next的时候,生成器并不会从foo函数的开始执行,只是接着上一步停止的地方开始,然后遇到yield后,return出要生成的数,此步就结束
理解枚举替代实现的缺陷
考虑用类来实现
class Seasons:
Spring = 0
Summer = 1
Autumn = 2
Winter = 3
print(Seasons.winter)
构建合理的包层次来管理module
大的项目中将所有的文件放在一个目录下并不好,需要合理的组织项目的层次,这就是**“包”**的作用
包即目录,除了包含常规的py文件外,还包含一个_init_.py文件,同时允许嵌套
包中的模块可以通过 “.” 访问符进行访问,即 包名.模块名
from Package.Module1 import Test
—— init.py文件为空
from Package import Test
—— init.py中包含 from Module1 import Test
- 合理组织代码,便于维护和使用
- 有效避免命名冲突
基础语法
使用with自动关闭资源
with open('test.txt','w') as f:
f.write('test)