[Python] Python工匠(Github)
1、善用变量来改变代码质量
变量命名
- 变量要有描述性,不能太宽泛
- BAD:day, host, cards, temp
- GOOD:day_of_week, hosts_to_reboot, expired_cards
- 变量名最好让人猜出类型
- Python是动态语言,没有变量类型声明,只能根据上下文猜测
- Boolean:is_superuser, has_error, allow_vip
- int/float:user_id, user_count, number_of_apples
- 适当使用“匈牙利命名法”
- 把变量缩写放在变量名的最前面
- students指向一个包含Person对象的list
- students->pl_students
- 变量名尽量短但不要太短
- 两三个单词左右
- 避免只有一两个字母的短名字
- 其他
- 同一段代码内不要使用过于相似的变量名,如user1, user2, user3
- 不要使用带否定含义的变量名,is_not_normal->is_special
变量使用
- 保持一致性
- 不要用一个变量名一会表示str,一会表示list
- 尽量不要用globals()/locals()
- 变量定义尽量靠近使用
- 合理使用namedtuple/dict让函数返回多个值
- 控制单个函数内的变量数量
- 及时删掉没用的变量
- 需要的时候再定义变量
2、编写条件分支代码的技巧
最佳实践
- 避免多层分支嵌套
- 过多的层次缩进影响代码可读性
- 用return/raise提前结束分支
- 封装过于复杂的逻辑判断
- 过多的not/and/or影响代码可读性
- 用函数封装具体判断
- 留意不同分支下的重复代码
- 重复代码令代码使用者难以区分不同分支的区别
- 利用Python的动态特性改善代码
- 谨慎使用三元表达式
- 用 x and a or b 模拟
- 用 if/else 替换
- 只用三元表达式处理简单的逻辑分支
常见技巧
- 使用“的摩根定律”
- not A or not B -> not( A and B )
- 自定义对象的“布尔真假”
- Python对象具有布尔值,适当利用可简化分支代码
- 魔法方法(user-defined method)__bool__和__len__
- 条件判断中使用all()/any()
- all(seq):仅当seq中所有对象为真时返回True
- any(seq):只要seq中有对象为真就返回True
- 使用try/while/for中的else分支
常见陷阱
- 与None值的比较
- 留意and和or的运算优先级
3、使用数字与字符串的技巧
序言
- Python中的三种数据类型:整型(int)、浮点型(float)和复数(complex)
- Python中的整型不区分有无符号,且永不溢出
最佳实践
- 少写数字字面量(integer literal),即那些直接出现在代码里的数字,对于会重复出现的数字,可利用枚举类型enum定义
- 少用裸字符串处理,即只用基本运算操作字符串,可用对象化的方式构建和编辑,如SQLAlchemy、lxml、JSON
- 不必预计算字面量表达式,Python解释器会自动预先计算
实用技巧
- 布尔值其实也是“数字”,如 True+1=2
- 改善超长字符串的可读性,使用\或+拆分,或用()将长字符串包起来
- 在多级缩进里插入多行字符串时,可用textwrap调整缩进
- 别忘了“r”开头的内建字符串函数(从右往左)
- 使用无穷大float("int")和float("-int")
常见误区
- value+=1 并非线程安全,被Python解释器执行时,不是原子操作
- 字符串拼接(+=)并不慢
4、容器的门道
底层看容器
- Python常用的内建容器:列表(list)、元组(tuple)、字典(dict)、集合(set)
- 避免频繁扩充/创建新列表,列表内存是按需分配的,现有内存不够时会触发扩容操作
- 多使用yield关键字,返回生成器对象
- 尽量使用生成器表达式替代列表推导表达式
- 尽量使用模块提供的懒惰对象
- 在列表头部操作多的场景使用deque模块
- 使用集合/字典判断成员是否存在
高层看容器
- Python是“鸭子类型”语言,只某对象满足了该类型的接口规范,就可以被当做该类型的对象使用
- 各个容器类型实现的接口协议定义了容器,不同的容器是“是否可迭代”、“是否可修改”、“有没有长度”等各种特性的组合
- 写代码时应更多关注容器的抽象属性,而非容器类型本身
- 面向接口而非具体实现编程
常用技巧
- 使用元组改善分支代码:二分查找模块bisect
- 在更多地方使用动态解包:使用*或**将可迭代对象“解开”
- 最好不用“获取许可”,也无需“要求原谅”:使用collections.defaultdict,而非捕捉异常
- 使用next()函数:接收一个迭代器作为参数,返回迭代器的下一个元素,配合生成器使用
- 使用有序字典去重:collections.OrderedDict
常见误区
- 当心已经枯竭的迭代器:遍历完后再遍历,就没有结果了
- 别在循环体内修改被迭代对象:遍历的同时修改会出错,应使用一个空列表保存结果,或使用yield返回生成器
5、让函数返回结果的技巧
编程建议
- 单个函数不要返回多种类型(单一职责)
- 使用partial构造新函数
- 抛出异常,而不是返回结果与错误
- 作为操作类函数的默认返回值
- 作为某些“意料之中”的可能没有的值
- 作为调用失败时代表“错误结果”的值,函数签名(名称与参数)与None返回值之间是否存在一种“意料之中”的暗示
- 合理使用“空对象模式”,即使用一个符合正常结果接口的“空类型”来代替空值返回/抛出异常,以降低调用方处理结果的成本
- 使用生成器函数代替返回列表
- 限制递归的使用,Python对递归支持有限,尽量采用循环实现
谨慎使用None返回值,仅在以下情况使用
6、异常处理的三个好习惯
- 异常处理工作由“捕获”和“抛出”两部分组成
三个建议
- 只做最精确的异常捕获
- 永远只捕捉可能会抛出异常的语句块
- 尽量只捕获精确的异常类型,而不是模糊的Exception
- 别让异常破坏抽象一致性
- 让模块只抛出与当前抽象层级一致的异常
- 在必要的地方进行异常包装与转换
- 异常处理不应喧宾夺主
- 使用上下文管理器(context manager)
7、编写地道循环的两个建议
- for <item> in <iterator> 和 while <condition>
- 使用函数修饰被迭代对象来优化循环
- 使用product扁平化多层嵌套循环
- 使用islice实现循环内隔行处理,islice(seq, start, end, step)
- 使用takewhile替代break语句,takewhile(predicate, iterable)
- 使用生成器编写自己的修饰函数
- 按职责拆解循环内的复杂代码块
- 复杂循环体如何应对新需求,避免循环体内的代码膨胀
- 使用生成器函数解耦循环体,隔离不同职责的代码块
8、装饰器使用技巧
- 装饰器(Decorator)可以在函数外部修改函数
最佳实践
- 尝试用类来实现装饰器
常见错误
- “装饰器”并不是“装饰器模式”
- 用functools.wraps()装饰内层函数
- 修改外层变量使用nonlocal
9、一个关于模块的小故事
- Module是用来组织Python代码的基本单位
- 合理的模块结构与分层非常重要
- 整个项目内的模块间依赖关系流向,应该是单向的,不能有环形依赖存在
10、做一个精通规则的玩家
11、高效操作文件的三个建议
- 使用pathlib模块
- 掌握如何流式读取大文件
- 设计接收文件对象的函数
12、写好面向对象代码的原则
Python对OOP的支持
- 没有严格的类私有成员
- 没有接口(interface)对象
SOLID设计原则
- S(单一职责原则):一个类应该只有一种被修改的原因
- O(开放-关闭原则):类应该对改动关闭,对扩展开放
- L(李氏替换原则):子类应该可以任意替换父类被使用
- D(依赖倒置原则):高层模块不应依赖低层模块,二者都应依赖于抽象
- I(接口隔离原则):客户应该不依赖于他不使用的方法
参考
闭包
https://www.liaoxuefeng.com/wiki/1022910821149312/1023021250770016
https://blog.csdn.net/weixin_43586120/article/details/89456183
[Python] Python工匠(Github)的更多相关文章
- Python实用案例,Python脚本,Python实现自动监测Github项目并打开网页
往期回顾 Python实现文件自动归类 前言: 今天我们就利用Python脚本实现Github项目的更新,提醒方式是邮箱.直接开整~ 项目地址: https://github.com/kenwoodj ...
- python --- Python中的callable 函数
python --- Python中的callable 函数 转自: http://archive.cnblogs.com/a/1798319/ Python中的callable 函数 callabl ...
- Micro Python - Python for microcontrollers
Micro Python - Python for microcontrollers MicroPython
- 从Scratch到Python——python turtle 一种比pygame更加简洁的实现
从Scratch到Python--python turtle 一种比pygame更加简洁的实现 现在很多学校都开设了Scratch课程,学生可以利用Scratch创作丰富的作品,然而Scratch之后 ...
- 从Scratch到Python——Python生成二维码
# Python利用pyqrcode模块生成二维码 import pyqrcode import sys number = pyqrcode.create('从Scratch到Python--Pyth ...
- [Python]Python 使用 for 循环的小例子
[Python]Python 使用 for 循环的小例子: In [7]: for i in range(5): ...: print "xxxx" ...: print &quo ...
- [python]python 遍历一个list 的小例子:
[python]python 遍历一个list 的小例子: mlist=["aaa","bbb","ccc"]for ss in enume ...
- [Python]Python日期格式和字符串格式相互转换
由字符串格式转化为日期格式的函数为: datetime.datetime.strptime() 由日期格式转化为字符串格式的函数为: datetime.datetime.strftime() # en ...
- [python]Python 字典(Dictionary) update()方法
update() 函数把字典dict2的键/值对更新到dict里.如果后面的键有重复的会覆盖前面的语法dict.update(dict2) dict = {'Name': 'Zara', 'Age': ...
随机推荐
- 工具 | Typora + PicGo-Core 自动上传图片到图床
0 前言 Markdown 是现在十分流行的标记式语言,在博客等很多场景中应用十分广泛.众所周知,Markdown 中的图片是以链接的形式存在的,不像 Word 等传统文本编辑器直接把图片嵌入文档中. ...
- Java 并发编程 Executor 框架
本文部分摘自<Java 并发编程的艺术> Excutor 框架 1. 两级调度模型 在 HotSpot VM 的线程模型中,Java 线程被一对一映射为本地操作系统线程.在上层,Java ...
- 极简实用的Asp.NetCore模块化框架新增CMS模块
简介 关于这个框架的背景,在前面我已经交代过了.不清楚的可以查看这个链接 极简实用的Asp.NetCore模块化框架决定免费开源了 在最近一段时间内,对这个框架新增了以下功能: 1.新增了CMS模块, ...
- CVE-2010-3333-office RTF栈溢出漏洞分析
0x00 前言 此漏洞是根据泉哥的<漏洞战争>来学习分析的,网上已有大量分析文章在此只是做一个独立的分析记录. 0x01 复现环境 操作系统-->windows7 x64 软件版本- ...
- css详解position五种属性用法及其含义
position(定位) position - 作为css属性三巨头(position.display.float)之一,它的作用是用来决定元素在文档中的定位方式.其属性值有五种,分别是 - stat ...
- python基础(补充):递归的深度
我们在正经人谁用递归呀一节中,简单的讨论了python中的递归 相信用过python递归的朋友可能都碰到过: RecursionError: maximum recursion depth excee ...
- 注册中心与API网关不是这样用的!
之前在做顾问和咨询项目的时候,见到了一种非常经典的关于API网关和注册中心的错误用法.这个案例在我的星球里已经分享过,没想到最近又碰到了两个类似的使用姿势.也许这样的问题还存在不少团队的应用中,所以拿 ...
- mooc人大单元测试3
@font-face { font-family: Wingdings } @font-face { font-family: 宋体 } @font-face { font-family: " ...
- F - Lakes in Berland(BFS)
The map of Berland is a rectangle of the size n × m, which consists of cells of size 1 × 1. Each cel ...
- Python爬取笔趣阁小说,有趣又实用
上班想摸鱼?为了摸鱼方便,今天自己写了个爬取笔阁小说的程序.好吧,其实就是找个目的学习python,分享一下. 1. 首先导入相关的模块 import os import requests from ...