Effective python(一):用Pythonic的方式来思考

1,查看版本

$ python --version

或者使用sys.version_info,sys.version查看版本

 

2,命名风格

  • 变量,函数,属性应该用小写字母拼写
  • 受保护的实例属性以单个下划线开头
  • 私有的实例属性应该以两个下划线开头
  • 类与异常首字母使用大写字母拼写
  • 模块级别常量全部使用大写形式命名
  • 类实例首参数命名self,表示自身
  • 类方法首参数命名cls,表示类自身

 

3,语句风格

  • 不要通过 if len(somelist)==0 的形式判断是否为[]或“”等空值,使用if not somelist空值会自动判断为True,检测somelist是否存在值同理
  • 尽量完整的写出from x import xx,如果要相对写可以from . import x等同于importx

 

4,bytes,str与unicode区别

  1. bytes是字节串,一个字节包含8位2进制数,若想将二进制数据转换为Unicode字符,则需要使用decode方法
  2. str包含Unicode字符,若想把Unicode字符转换为字节串(二进制数据),则需要使用encode方法
  3. open函数获取文件句柄,该句柄会默认以UTF-8的编码格式操作文件,open函数有一个参数encoding默认值为'utf-8',若需要读入和写入一些二进制文件,则可以将open的第二个参数设置为'wb'或'rb'而不是'w'和'r',备注:文件句柄指标识符或指针,可理解为文件描述符,指代将要操作的文件

 

5,将复杂的表达式制作为辅助函数,对取到的值使用if else 和 or可以设置为空情况的默认值

备注:生成器和迭代器都不占用内存,一个是凭空生成迭代,一个是数据抽出迭代

 

6,切片

  1. 切片索引越界不会报错,但使用指针访问单个元素不能越界
  2. 注意:当某些情况会出现切片无法正常工作,如[-n:],当n为0时变成了原列表拷贝
  3. 切片替换值操作不需要新值与原值个数相等如:a[2:7]=[1,2,3]
  4. 对赋值左侧使用切片:b=a[:]是浅拷贝,即假如a列表内有引用对象,那么更改这个引用对象,b内的这个引用对象也会被改变
  5. 对赋值右侧使用切片:a[:]=[1,2,3],也会浅拷贝一份替换左侧内容
  6. 反转字符串或数组x[::-1],但注意,这只对字节串和ASCII字符有效(即英文字符或标点),对UTF-8字符无效(即中文字符等)

 

7,列表,字典,集合推导式

  1. filter函数第一个参数是过滤条件函数,即传入x,传出bool,第二个参数是列表
  2. 字典推导式:d={'a':1,'b':2,'c':3}  dt={x:y for x,y in d.items() }
  3. 集合推导式:s={n for n in d.values() }
  4. 双层或多层for循环列表推导式,例如将二维转一维列表:flat=[x for row in matrix for x in row],注意,for循环会按照从左到右的顺序执行,即左侧在外层,右侧在内层
  5. 创建矩阵列表推导式:matrix=[[x for x in range(n)] for y in range(n)]
  6. 列表推导式也支持多个if条件,同一循环级别中的多项条件,默认形成and表达式,如这两个表达式等效[x for x in a if x>4 if x%2==0],[x for x in a if x>4 and x%2==0]
  7. 每一级别for循环都可以添加条件

 

8,使用生成器表达式处理数据量较大的列表推导式

  1. 例如,读取一份文件,返回每行字符数 [len(line) for line in open('my_file.txt')],这种方法的问题就是,每一行长度都会保存在内存中
  2. 生成器表达式:将[]替换为()即可:it=(len(line) for line in open('my_file.txt')),它会立刻返回一个迭代器,不会深入处理文件内容,此时print(it)只会打印出一个生成器对象
  3. 使用生成器的方法:print(next(it)),这种方法不会保存每一次的数据到内存中,执行速度也很快
  4. 生成器的相互组合,roots=((x,x**0.5) for x in it),print(next(roots))

 

9,enumerate and zip

  1. enumerate第二个参数可以添加开始计数的值,默认为0
  2. zip封装两个或两个以上的迭代器变成生成器zip(lista,listb,listc),然后把这些平行值汇聚成元组
  3. 如果两个迭代器长度相同,zip不会出问题,如果长度不同,有一个耗尽zip就会终止,若不能确定zip列表是否等长,可以使用itertool中的zip_longest,它不会在乎长度是否相等

 

10,for和while后的else块

  1. 如果程序正常结束,则执行else块,如果for或while内使用break跳出,则不会执行else块
  2. 如果for遍历的序列是空的,或者while执行初始条件为False,都会立刻执行else块
  3. 尽量不要写,容易使人误解,可替代方法有很多

 

11,try,except,else,finally(同理,try块无执行异常执行else块),finally可以执行必须要执行的事情,如关闭句柄,退出数据库等等

posted @ 2020-03-22 14:22  石天放  阅读(239)  评论(0编辑  收藏  举报