博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python心得--如何提高代码质量
阅读量:7003 次
发布时间:2019-06-27

本文共 3271 字,大约阅读时间需要 10 分钟。

  前些日子用python基于prometheus开发了一个vsphere volume卷监控的exporter,于是跟vsphere的api(pyvmomi)接口打上了交道,开发的过程中你会发现pyvmomi的接口返回的对象好多列表类型的,当你取其中一个对象的时候可能需要进行多层的循环遍历。于是促使了我写这一篇文章,记录一下在使用python搬砖过程中的一些心得体会。如有错误,欢迎大家指正。

3f2d0000b47b43cd60e1

Python里面所谓高质量的代码,我自己理解的主要是两方面。一是编写具有python风格的代码,即所谓的Pythonic;二是代码的执行效率。Python的执行效率一直被人诟病,这点我承认,但我更认同的一种说法是“编程语言本身没有好坏,关键在于使用者的使用方法是否恰当。”

以下是个人总结的,在python编程过程中常见的几点提高代码质量的方法:

  1. 变量的赋值

1
2
3
4
5
6
7
8
9
10
In [11]: a, b = 10, 50 
# 赋值写在一行
In [12]: a
Out[12]: 10
In [13]: b
Out[13]: 50
In [14]: a, b = b, a 
# a, b互换
In [15]: a
Out[15]: 50
In [16]: b
Out[16]: 10

变量交换的时候尽量避免使用中间变量增加开销。

2. 列表推导提高效率和可读性

如下生成一个新的列表:

1
2
In [17]: [n 
for 
in 
range(10)]
Out[17]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

另一方面,列表推导也可能被滥用。通常的原则是,只用列表推导来创建新的列表并且尽量保持简短。 如果列表推导的代码超过了两行,你可能就要考虑是不是得用 for 循环重写了。就跟写文章一样,并没有什么硬性的规则,这个度需要自己把握。

3. 列表和字典的迭代

列表使用enumerate() 获取list的索引和值,字典使用iteritems方法获取索引和值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
In [18]: l1 = [n 
for 
in 
range(10)]
In [21]: 
for 
k, 
v 
in 
enumerate(l1):
....: print k, 
v
....:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
In [23]: dict1 = {
'a'
:1, 
'b'
:2, 
'c'
:3, 
'd'
:4}
In [24]: dict1
Out[24]: {
'a'
: 1, 
'b'
: 2, 
'c'
: 3, 
'd'
: 4}
In [25]: 
for 
k, 
v 
in 
dict1.iteritems():
....: print k, 
v
....:
a 1
c 3
b 2
d 4

4. 使用三元表达式进行条件赋值

三元表达式允许用简单的一行快速判断,而不是使用复杂的多行if语句,可以使代码简单、可维护。

1
2
3
4
In [26]: 1 
if 
5>3 
else 
0
Out[26]: 1
In [27]: 1 
if 
5>8 
else 
0
Out[27]: 0

举一个在实际生产中运用列表推导和三元表达式结合使用的例子:

1
2
dc_list = [datacenter 
for 
datacenter 
in 
root_folder.childEntity 
if 
isinstance(
datacenter, vim.Datacenter)]

这里生成了一个名为dc_list的列表,首先在"root_folder.childEntity"中遍历出datacenter,接着判断这个datacenter是否是一个"vim.Datacenter"的实例,如果为真,加入到dc_list列表中,最终返回该datacenter列表。

5. 使用 with 自动关闭资源

对文件操作完成后应该立即关闭它们,因为打开的文件不仅会占用系统资源,而且可能影响其他程序或者进程的操作,甚至会导致用户期望与实际操作结果不一致。

1
2
3
4
5
6
7
In [5]: with 
open
(
'111.py'
'rb'
) as 
file
:
...: 
for 
line 
in 
file
:
...: print line
...:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
print 
"name is %s" 
% __file__

6. 使用yield

这里有一个生成斐波那契数列的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
In [8]: def fab(n):
...: a, b = 0, 1
...: 
for 
in 
xrange(n):
...: yield b
...: a, b = b, a + b
...:
In [9]: fab(20)
Out[9]: <generator object fab at 0x1092975a0>
In [10]: 
for 
in 
fab(20):
....: print n
....:
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765

可以看出一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

7. 减少循环内部执行的计算

优化python循环的关键一点,是要减少Python在循环内部执行的工作量。

1
2
3
4
5
6
In [30]: a = range(10000)
In [31]: size_a = len(a)
In [32]: %timeit -n 1000 
for 
in 
a: k = len(a)
1000 loops, best of 3: 658 μs per loop
In [33]: %timeit -n 1000 
for 
in 
a: k = size_a
1000 loops, best of 3: 304 μs per loop

8. 字符串连接优先使用"join",而不是“+”

1
2
3
In [42]: letter = [
'a'
'b'
'c'
'd'
]
In [43]: print 
''
.
join
(letter)
abcd

9. None类型判断

不要使用‘==’ None的形式:

1
2
if 
foo == None:
do_something()

正确用法:

1
2
if 
not foo:
do_something()

3f290002e2c8e4c5f747

10. “过早的优化是万恶之源”

最后不得不提一下这句话,借用一下别人的诠释:

1
2
3
4
Make it Work.
Make it Right.
Make it Fast.
不要跳过前面两个直奔第三个!
      本文转自Jx战壕  51CTO博客,原文链接:http://blog.51cto.com/xujpxm/1971832,如需转载请自行联系原作者
你可能感兴趣的文章
Qt编写的RTSP播放器+视频监控(vlc版本)
查看>>
AspectJ的拓展学习--织入顺序和通知参数指定
查看>>
使用CentOS7卸载自带jdk安装自己的JDK1.8
查看>>
[Android Pro] Android P版本 新功能介绍和兼容性处理(三)Android Studio 3.0 ~ 3.2 其他特性...
查看>>
QT中显示gif图片方法
查看>>
工程投诉过程中各建设主管理部门联系人表
查看>>
一起谈.NET技术,关于Expression Tree和IL Emit的所谓的&quot;性能差别&quot;
查看>>
CGI, mod_perl, PHP, JSP性能比较
查看>>
史上最全面的面试资料(包含所有IT大公司)
查看>>
密码库 链接
查看>>
ZOJ 3505. Yet Another Set of Numbers 解题报告
查看>>
mysql innodb_double_write特性
查看>>
利用光纤磁盘阵列实现存储共享(转)
查看>>
【读书笔记-数据挖掘概念与技术】分类:高级方法
查看>>
ED/EP系列1《简单介绍》
查看>>
oratop 各个指标项说明
查看>>
Android 手势识别类 ( 一 ) GestureDetector 基本介绍
查看>>
安装scapy遇到的问题
查看>>
Appium 一个测试套件多次启动android应用
查看>>
[CareerCup] 17.9 Word Frequency in a Book 书中单词频率
查看>>