如何提高python程序_Python心得——如何提高代码质量

原标题:Python心得——如何提高代码质量

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

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

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

变量的赋值

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 n 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 n 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 i in xrange(n):

...: yield b

...: a, b = b, a + b

...:

In [9]: fab(20)

Out[9]:

In [10]: for n 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 i in a: k = len(a)

1000 loops, best of 3: 658 μs per loop

In [33]: %timeit -n 1000 for i 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()

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

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

1

2

3

4

Make it Work.

Make it Right.

Make it Fast.

不要跳过前面两个直奔第三个! 返回搜狐,查看更多

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值