@zhengyuhong
2015-04-29T12:11:24.000000Z
字数 4481
阅读 1359
Python
PEP8既是一篇关于Python编码风格的指南,它提出保持代码一致性的细节要求。它至少包括对代码布局、注释、命名规范等方面的要求。在印象笔记中有中文的指南。PEP8又是一个编码风格软件
sudo pip install --upgrade pep8pep8 --show--source --show-pep8 xxx.py
3)给外部可访问的函数和方法添加文档注释。注释要清楚地描述函数的功能,并对参数、返回值以及可能发生的异常进行说明,使得外部调用它d人员仅仅看docstring就能正确使用。较为复杂的内部方法也需要进行注释。推荐的函数注释如下:
def FuncName(para1, para2):"""Args:para1:parameter type, what is this parameter used forpara2:parameter type, what is this parameter used forReturns:return type,return value"""function body
4)推荐在文件头包括copyright申明、模块描述等,如有必要,可以考虑加入作者信息以及更新记录
"""Licensed Materials - Property of CorpA(C) Copyright A Corp. 1999,2011 All Right Reserved----------------------------------------------------------------File Nmae : comments.pyDescription : description what the main function of this fileAuthor : Author nameChange Activity :list the change activity and time and author information----------------------------------------------------------------"""
原则1、函数涉及要尽量短小,嵌套层次不宜过深。
原则2、函数申明应该做到合理、简单、易于使用
原则3、函数参数涉及应该考虑向下兼容。如
def readfile(filename):"""version 1.0Args:filename:string type,location of the fileReturns:None"""print 'file read completed'
def readfile(filename,logger):"""version 2.0Args:filename:string type,location of the fileReturns:None"""print 'file read completed'
新的函数与原来的不兼容,调用时会发生错误,应如下修改
def readfile(filename,logger=logger.info):"""version 2.0Args:filename:string type,location of the fileReturns:None"""print 'file read completed'
原则4、一个函数只做一件事,尽量保持函数语句粒度的一致性。
内建函数type用于返回当前对象的类型,如type(1)返回。因此可以通过与Python自带模块types中所定义的名称来进行比较,根据其返回值确定变量类型是否符合要求。例如判断一个变量a是不是list类型可以使用以下代码:
if type(a) is types.ListType:pass#在type模块中还有BooleanType,StringType,DictType
当设计浮点数运算的时候尽量先将操作数转换为浮点数类型再做运算
浮点数比较时最后指定精度。如
i = 1while i != 1.5:i += 0.1print i
陷入死循环,因为浮点数仅仅是近似表示。
Unicode为不同语言设置了唯一的二进制表示形式,可以轻易解决不同字符集之间的字符映射问题,因此可以使用Unicode作为中间介质来完成过渡转换。示例如下:
with fr = open('test.txt'):print (filehandle.read().decode('utf8').encode('gbk'))
常见编码参数
| 编码参数 | 描述 |
|---|---|
| 'ascii' | 7位ASCII码 |
| 'latin-1' or 'iso-8859-1' | Latin-1,ISO-8859-1 |
| 'utf-8' | 8位可变长度编码 |
| 'utf-16' | 16位可变长度编码 |
Python源代码中默认编码位ASCII(这点可以通过sys.getdefaultencoding()验证)。中文字符并不是ASCII字符,而此时源文件中又未指定其他编码方式,Python解释器不知道如何正确处理这种情况,便会抛出异常:SyntaxError:Non-ASCII charater '\xd6'。因此,要避免这种错误需要在源文件进行编码声明,声明可用正则表达式
#coding[:=]\s*([-\w.])+#coding=utf8#coding:utf8# -*- coding:utf8 -*-
尽量避免使用 from a import *,因为这回污染命名空间,并且无法清晰地表示导入了哪些对象。
with open(file,'w') as fw:blabla
for i in range(100):if aa:breakblalbaelse:blabla
当循环因为循环条件不再满足时执行else子句,当因为break结束循环时不执行else子句。同理while循环
while condition:if aa:breakelse:blabla
建议29、区别对待可变对象和不可变对象
def fun(l=[]):l.append(1)print lfun()fun()输出[1][1,1]
由于fun的参数时默认参数,默认参数在函数被调用时仅仅被评估一次,以后都会使用第一次评估结果,因此实际上对象空间里面的l所指向的时list地址,每次操作的实际指向都是同一个list地址。所以最好传入None作为默认参数。
Python支持可变长度的参数列表,可以通过在函数定义的时候使用*args和**kwargs两个特殊语法来实现(args,kwargs可以位其他变量名)
def sum_fun(*args):for arg in args:print argsum_fun(1)sum_fun(1,2)sum_fun(1,2,3)def dict_fun(**kwargs):for k,v in kwargs.items():print k,vdict_fun()
from collections import Countersome_data = [1,2,3,4,5,6,6,7,5,1]cnt = Counter(some_data)cnt.most_common(topk)#找出topk的key以及对应的value
仅仅将栈信息输出到控制台是远远不够的,更为常见的是使用日志保存程序运行过程中的相关信息,如运行时间、描述信息以及错误或者异常发生的时候的特定信息。Python中自带的logging模块提供了日志功能,它将logger分为5个level,可以通过logger.setLevel(lvl)来设定,其中DEBUG为最低级别,CRITICAL为最高级别,默认为WARNING级别。
| Level | 使用情形 |
|---|---|
| DEBUG | 详细的信息,在追踪问题的时候使用 |
| INFO | 正常的信息 |
| WARNING | 一些不可预见的问题发生、或者将要发生,如磁盘低,但不影响程序的运行 |
| ERROR | 由于一些严重问题,程序功能受到影响 |
| CRITICAL | 严重的错误,或者程序本身不能够继续运行 |
很多pythoner会这样子认为,__init__方法就是类的构造方法.因为表面上看它确实很像构造方法:当需要实例化一个对象的时候,使用a=Class(args)便可以返回一个类的实例,其中args的参数与__init__中声明的一样,但是真的是酱紫嘛?如下分析:
class A(object):def __new__(cls, *args, **kwargs):print clsprint argsprint kwargsinstance = object.__new__(cls, *args, **kwargs)print instancedef __init__(self, a, b):print 'init gets called'print 'self is ', selfself.a, self.b = a, b
我们原本期望会输出1,2,但是运行却抛出异常。实际上__init__不是真正意义上的构造方法,它所做的工作是初始化,就是在对象已经创建好了之后初始化它们的值,__new__才是真正创建对象。上面的程序抛出异常时因为__new__没有显式返回已经创建好的对象,因为a1是None,当访问成员数据时就会出错。
如同this->指针,没有加self就是静态成员变量,静态成员函数(C++ 中的static)