编写Python的建议(一)

1. 数据交换值不推荐使用中间变量


交换两个值,大家都熟悉的代码如下:

temp = x
x = y
y = temp

其实Python还有一种更简单的方式

x, y = y, x

我们测试一下上面两种方式交换值的性能

from timeit import Timer
if __name__ == "__main__":
    time_value1 = Timer('temp = x; x = y; y = temp', 'x = 2; y = 3').timeit()
    print('time_value1: ', time_value1)
    time_value2 = Timer('x, y = y, x', 'x = 2; y = 3').timeit()
    print('time_value2: ', time_value2)
output:
time_value1:  0.021976965380765903
time_value2:  0.018517656058779114

从结果可以看出来第二种方式耗时的时间更少,并且由于不需要借助中间变量,代码也更加简洁,是我们平时写代码需要学习的地方。

为什么第二种方式更优呢?

一般情况下Python表达式的计算顺序是从左到右,但是遇到表达式赋值的时候表达式右边的操作数先于左边的操作数计算,因此表达式

expr3, expr4 = expr1, expr2
计算顺序是
expr1, expr2 >>>>> expr3, expr4

所以对于表达式x, y = y, x计算的顺序如下:

  1. 先计算右边的表达式y, x, 因此现在内存中创建元组(y, x),其标示符和值分别为y,x及其对应的值(即就是x = 2, y = 3),其中y和x是在初始化时已经存在于内存中的对象。
  2. 计算表达式左边的值并进行赋值,元组被依次分配给左边的标示符,通过解压缩(unpacking),元组第一标示符(为y)分配给左边第一个元素(此时为x),元组第二个标示符(为x)分配给第二个元素(此时为y),从而达到x,y值交换的目的。

2. 利用assert语句排查问题


断言(assert)在很多语言中都存在,它主要为调试程序服务,能够快速方便地检查程序的异常或者发现不恰当的输入,可防止意想不到的情况

断言语句

assert expression1 ["," expression2]

其中计算expression1的值会返回True或者False,当值为False的时候会引发AssertionError,而expression2是可选的,常用来传递具体的异常信息。 一个简单的例子

if __name__ == "__main__":
    value1 = 1
    value2 = 2
    assert value1 == value2, "not equals"
output:
Traceback (most recent call last):
  File "E:/PycharmProjects/test/run.py", line 13, in <module>
    assert value1 == value2, "not equals"
AssertionError: not equals

使用assert说明:

  • __debug__的值默认设置为True,且是只读的,在Python2.7中还无法修改该值
  • 断言的缺点是对性能有影响,对于编译型语言,如C/C++,这或许不重要,因为断言只在debug模式下生效,但是Python并没有严格定义debug和release模式之间的区别,通常禁用断言的方法是在 运行脚本的时候加上-O标志,这种方式并不优化字节码,而是忽略与断言相关的语句。如:

在使用assert需要注意:

  1. 不要滥用,这是使用assert最基本的原则,若由于断言引发了异常,一般就是因为程序中存在bug。因此断言应该在正常逻辑不可到达的地方或者正常情况下总是正确的场合使用。
  2. 如果Python本身的异常能够处理就不要使用assert。如对于类似于数组越界,类型不匹配,除数为0之类的错误,不建议使用断言来进行处理。
  3. 不要使用断言来检查用户的输入。如对于一个数字类型,如果用户设计该值是2~10,一般应该使用条件判断,并在不符合条件的时候输出错误提示信息。assert只是帮助我们可以快速定位到代码位置。
  4. 在函数调用后,当需要确认返回值是否合理可以使用断言。
  5. 当条件是业务逻辑继续下去的必要条件时可以使用断言。如list1和其副本list2,业务继续下去的条件是两个list必须是一样的,这时就可以使用断言来判断两者的关系。

 

上一篇:缝缝补补


下一篇:Pytest之assert常用断言记录