当前位置: 首页 > news >正文

读书笔记--《编写高质量代码:改善Python程序的91个建议》

 

第一章 引论

建议写Pythonic式的代码,我理解为充分利用pythonAPI,用最简洁方式写出代码

1、两个变量交换:

a, b = b, a

2、翻转list:

a = [1, 2, 3, 4] print(list(reversed(a)))

3、格式化字符串

.format

print ( 'my name is {} '.format('jack'))

3.6版本新的格式化字符串方法

name = 'Mollylin' print(f'hello,{name}~!') >>>'hello,Mollylin~!'

第二章

1、assert

其基本语法如下:

assert expression1, ["," expression2],使用的例子如下:

x, y = 1, 2 assert x == y, "not equal"

其中会计算expression1 的值,返回true false,值为false的时候会引起AssertionErrorexpression2是可选的,用来传递具体的异常信息

断言不可滥用:

  •  断言是有代价的,它会对性能产生一定的影响,通常禁用断言的方法是在运行脚本的时候加上 -O 标志,这种方式带来的影响是它并不优化字节码,而是忽略与断言相关的语句。
  •  不要滥用。若由于断言引发了异常,通常代表程序中存在 bug。因此断言应该使用在正常逻辑不可到达的地方或正常情况下总是为真的场合。
  •  如果 Python 本身的异常能够处理就不要再使用断言。如对于类似于数组越界、类型不匹配、除数为 0 之类的错误,不建议使用断言来进行处理。

# 下面的断言是多余的, 如果类型不匹配本身就会抛出异常 def stradd(x, y):    assert isinstance(x, basestring)    assert isinstance(y, basestring)    return x + y

  •  不要使用断言来检查用户的输入。如对于一个数字类型,如果根据用户的设计该值的范围应该是 2~10,较好的做法是使用条件判断,并在不符合条件的时候输出错误提示信息。
  •  在函数调用后,当需要确认返回值是否合理时可以使用断言
  •  当条件是业务逻辑继续下去的先决条件时可以使用断言,比如 list1 和其副本 list2,如果由于某些不可控的因素,如使用了浅拷贝而 list1 中含有可变对象等,就可以使用断言来判断这两者的关系。

2、isinstance()

所有基本类型对应的名称都可以在 types 模块中找到,然而使用 type() 函数并不适合用来进行变量类型检查。

  •  基于内建类型扩展的用户自定义类型,type 函数并不能准确返回结果
  •  在古典类中,所有类的实例的 type 值都相等

对于内建的基本类型来说,使用 type() 进行类型检查问题不大,但在某些特殊场合 type() 方法并不可靠。解决方法是,如果类型有对应的工厂函数,可以使用工厂函数对类型做相应转换,否则可以使用 isinstance() 函数来检测。

  •  type() 不会认为子类是一种父类类型,不考虑继承关系。
  •  isinstance() 会认为子类是一种父类类型,考虑继承关系
>>>a = 2 
>>> isinstance (a,int)
True
>>> isinstance (a,str)
False
>>> isinstance (a,(str,int,list)) # 是元组中的一个返回 True True

3、eval()的安全漏洞

Python eval() 函数将字符串 str 当成有效的表达式来求值并返回计算结果。其函数声明如下:eval(expression[, globals[, locals]])

>>>eval("'A'+'B'"
'AB'
>>>eval("1+2")
3
>>>eval("1+1==2")
True

由于网络环境下运行它的用户并非都是可信任的,比如输入 __import__("os").system("dir") ,它会显示当前目录下的所有文件列表;输入 __import__("os").system("del * /Q"),会导致当前目录下的所有文件都被删除了,而这一切没有任何提示。

4、enumerate()

使用 enumerate() 获取序列迭代的索引和值

1 li = ['a', 'b', 'c', 'd', 'e']
2 
3 for i, e in enumerate(li):
4 
5 print "index:", i, "element:", e

推荐使用函数 enumerate(),主要是为了解决在循环中获取索引以及对应值的问题。它具有一定的惰性(lazy),每次仅在需要的时候才会产生一个(index, item)对。其函数签名如下:enumerate(sequence, start=0)

其中,sequence 可以为序列,如 listset 等,也可以为一个 iterator 或者任何可以迭代的对象,默认的 start 0,函数返回本质上为一个迭代器,可以使用 next() 方法获取下一个迭代元素。

5、== 和is

is 表示的是对象标示符(object identity),而 == 表示的意思是相等(equal

is 的作用是用来检查对象的标示符是否一致的,也就是比较两个对象在内存中是否拥有同一块内存空间,它并不适合用来判断两个字符串是否相等。

 

第三章 基础语法

1、++1

Python 解释器会将 ++i 操作解释为 +(+i),其中 + 表示正数符号。对于 --i 操作也是类似。

因此需要明白 ++i Python 中语法上是合法的,但并不是我们理解的通常意义上的自增操作。

 

2、finally

  •   try 块中发生异常的时候,如果在 except 语句中找不到对应的异常处理,异常将会被临时保存起来,当 finally 执行完毕的时候,临时保存的异常将会再次被抛出,但如果 finally 语句中产生了新的异常或者执行了 return 或者 break 语句,那么临时保存的异常将会被丢失,从而导致异常屏蔽。
  •  在实际应用程序开发过程中,并不推荐在 finally 中使用 return 语句进行返回,这种处理方式不仅会带来误解而且可能会引起非常严重的错误。

3、None

其中常量 None 的特殊性体现在它既不是 0False,也不是空字符串,它就是一个空值对象。其数据类型为 NoneType,遵循单例模式,是唯一的,因而不能创建 None 对象。所有赋值为 None 的变量都相等,并且 None 与任何其他非 None 的对象比较结果都为 False

4、join()

 

join() 方法的效率要高于 + 操作符。

  •  当用操作符 + 连接字符串的时候,由于字符串是不可变对象,其工作原理实际上是这样的:如果要连接如下字符串:S1+S2+S3+...+SN,执行一次 + 操作便会在内存中申请一块新的内存空间,并将上一次操作的结果和本次操作的右操作数复制到新申请的内存空间,在 N 个字符串连接的过程中,会产生 N-1 个中间结果,每产生一个中间结果都需要申请和复制一次内存,总共需要申请 N-1 次内存,从而严重影响了执行效率,时间复杂度近似为 O(n^2)
  •  而当用 join() 方法连接字符串的时候,会首先计算需要申请的总的内存空间,然后一次性申请所需内存并将字符序列中的每一个元素复制到内存中去,所以 join 操作的时间复杂度为 O(n)

5、可变对象和不可变对象

  •  数字、字符串、元祖属于不可变对象
  •  字典、列表、字节数组属于可变对象

当有两个对象同时指向一个字符串对象的时候,对其中一个对象的操作并不会影响另一个对象。

 

第四章

1、sort()、sorted()

sorted() 函数会返回一个排序后的列表,原有列表保持不变;而 sort() 函数会直接修改原有列表,函数返回为 None

 

转载于:https://www.cnblogs.com/Mollylin/p/10409621.html

相关文章:

  • Codeforces Round #540 (Div. 3) F1. Tree Cutting (Easy Version) 【DFS】
  • volatilesynchronizeddiff
  • canvas字体样式
  • 5-发音规则(略读)
  • [洛谷P1709] [USACO5.5]隐藏口令Hidden Password
  • 树·二叉查找树ADT(二叉搜索树/排序树)
  • 两种经典电商CSS布局
  • 微信小程序 - 自定义swiper dots样式(非组件)
  • django基础 第四章 模板标签
  • C++重载赋值运算符
  • golang学习之interface与其它类型转换
  • windows系统和IE的兼容性问题
  • PHP TP5 文章评论+积分+签到
  • YAML 基础
  • Cordova 打包签名
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • [译] React v16.8: 含有Hooks的版本
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • 【知识碎片】第三方登录弹窗效果
  • Angular 4.x 动态创建组件
  • java概述
  • JS数组方法汇总
  • JS专题之继承
  • miaov-React 最佳入门
  • Spring Cloud Feign的两种使用姿势
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 开源SQL-on-Hadoop系统一览
  • 理解在java “”i=i++;”所发生的事情
  • 全栈开发——Linux
  • 如何使用 JavaScript 解析 URL
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • 【干货分享】dos命令大全
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • 组复制官方翻译九、Group Replication Technical Details
  • "无招胜有招"nbsp;史上最全的互…
  • # 透过事物看本质的能力怎么培养?
  • #QT(智能家居界面-界面切换)
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • $forceUpdate()函数
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (八十八)VFL语言初步 - 实现布局
  • (正则)提取页面里的img标签
  • (转)visual stdio 书签功能介绍
  • (转)大型网站架构演变和知识体系
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .net 验证控件和javaScript的冲突问题
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .NetCore部署微服务(二)
  • .net分布式压力测试工具(Beetle.DT)
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • :O)修改linux硬件时间