91个建议系列之6-编程惯用法

6、编程惯用法

注意:本篇属于本书第二章,由于有些部分由于python的更新已经用处不大,所以此处不再列出

1、数据交换值的时候不推荐使用中间变量-建议9

这个问题其实很简单,最为pythonic的方式是使用元组unpacking

x,y = y,x

但是它与我们使用一个中间变量交换有啥差别吗?

temp = x
x = y
y = temp

我们可以采用timeit对两者的运行效率进行对比,

  • timeit 模块定义了接受两个参数的 Timer 类。 第一个参数是要计时的语句或者函数,第二个参数是为第一个参数语句构建环境的导入语句。 从内部讲, timeit 构建起一个独立的虚拟环境, 手工地执行建立语句,然后手工地编译和执行被计时语句。

  • 一旦有了 Timer 对象,最简单的事就是调用 timeit(),它接受一个参数为每个测试中调用被计时语句的次数,默认为一百万次;返回所耗费的秒数。

  • Timer 对象的另一个主要方法是 repeat(), 它接受两个可选参数。 第一个参数是重复整个测试的次数,第二个参数是每个测试中调用被计时语句的次数。 两个参数都是可选的,它们的默认值分别是 3 和1000000。 也就是重复做三次,每次语句执行1000000次。repeat() 方法返回以秒记录的每个测试循环的耗时列表。

    from timeit import Timer
    print(Timer('temp = x;x = y;y = temp', 'x=2;y =3').timeit())
    print(Timer('x,y = y,x', 'x=2;y=3').timeit())
    
    # 输出
    0.04681229999999914
    0.034195500000009815
    

可以看出,unpacking方式耗费的时间更少,并且由于不需要借助中间变量,代码更为简洁,是值得推荐的一种方式。

而对于更深层次的原因笔者觉得用处不大,再次不再详述。

2、充分利用Lazy evaluation的特性-建议10

Lazy evaluation常被译为“延迟计算”或“惰性计算”,指的是仅仅在真正需要执行的时候才计算表达式的值。充分利用Lazy evaluation的特性带来的好处主要体现在以下两个方面:
1)避免不必要的计算,带来性能上的提升。对于Python中的条件表达式if x and y,在x为false的情况下y表达式的值将不再计算。而对于if x or y,当x的值为true的时候将直接返回,不再计算y的值。因此编程中应该充分利用该特性,如果对于or条件表达式应该将值为真可能性较高的变量写在or的前面,而and则应该推后。

2)节省空间,使得无限循环的数据结构成为可能。Python中最典型的使用延迟计算的例子就是生成器表达式了,它仅在每次需要计算的时候才通过yield产生所需要的元素。斐波那契数列在Python中实现起来就显得相当简单,而while True也不会导致其他语言中所遇到的无限循环的问题。

def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a+b

3、警惕使用eval-建议14

Python中eval()函数将字符串str当成有效的表达式来求值并返回计算结果,其语法非常简单:eval(“字符串表达式”),不过“eval is evil”(eval是邪恶的),主要原因在于eval多用于用户输入表达式的求值,对于恶意用户来说可能造成不可挽回的损失。例如如果输入:

eval("__import__('os').system('dir')")

你会发现返回当前工作文件夹内所有的文件,相当于在cmd中输入了dir,如果用户更加邪恶,输入了删除命令:

__import__("os").system("del * /Q")

那当前文件夹内所有的文件都将会被删除。

如果使用对象不是信任源,应该尽量避免使用eval,在需要使用eval的地方可用安全性更好的ast.literal_eval替代:

 ast.literal_eval("__import__('os').system('dir')")
 # 返回
ValueError: malformed node or string
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值