如何让python代码更加pythonic

禄奇希
2023-12-01

转载自http://shihongzhi.com/python/2012/05/24/Pythonic/

Pythonic

The Zen of Python

在python终端输入import this,会输出The Zen of Python,详细描述的编写python代码时需要遵守的哲学,禅道。把握好这些准测,就能写出漂亮的python代码。但是这些还是太抽象了,写这篇blog打算记录一下一些pythonic的代码及细节

判断字符串是否为空

不需要判断len(my_string),应该直接

if my_string:
   print 'my_string is not empty'


检测字符串包含问题

不应该是用

if my_string.find('sub_string') != -1:

而应该是

if 'sub_string' in mu_string:

Tuple

在for-in语句、函数返回值上都应该使用Tuple的Unpack功能

Sort

比如:

def get_price(ob):
    return ob['price']

lst.sort(key=get_price)

或者:

lst.sort(key=lambda x: x['price'])

但是最pythonic的写法应该是:

from operator import itemgetter
lst.sort(key=itemgetter('price'))

List Comprehensions

单独使用map和filter时,应该用List Comprehensions代替。因为List Comprehensions比map和filter容易理解

比如

numbers = [1,2,3,4,5]
#No
squares = map(lambda x:x*x, numbers)
#Yes
squares = [number*number for number in numbers]
#No
numbers_under_4 = filter(lambda x:x<4, numbers)
#Yes
numbers_under_4 = [number for number in numbers if nubmer<4]

同时使用map和filter时,也可以用List Comprehensions来替代。比如

squares = [number*number for number in numbers if number<4]

这个例子中是先filter再map的。如果需要先map再filter的话,只能用for语句或nested list comprehension。和filter、map类似的还有reduce函数。

Generator

List会把整个List的元素都产生,并同时装入到内存中。所以对包含大量数据的List来说,这样的处理效果就会很低效。这种情况下,可以用Generator来替换List。Generator每次只装载一个元素,所以效率会比List高很多。但是,当需要list所以元素的计算结果时,则只能选择用List。下面是一个Generator expression

total = sum(num*num for num in xrange(1, 101))

Nested ‘for’ Statements

下面的代码:

for x in (0,1,2,3):
    for y in (0,1,2,3):
        if x < y:
            print (x, y, x*y)

可以写成:

print [(x, y, x*y) for x in (0,1,2,3) for y in (0,1,2,3) if x<y]

enumerate

如果遍历list的时候同时需要index,应该用enumerate

all any

尽量用all、any这两个内置函数, 比如:

numbers = [1, 10, 1000, 10000]
if any(number<10 for number in numbers):
    print 'Have number<10'

zip

用zip来整合多个list。

字典

dict和list是可以相互转换的。

and/or

python中不存在C/C++语言中的三元表达式,python中使用and/or表达式来替换的这种功能的。

result = test and 'Test is true' or 'Test is False'

and/or表达式需要注意的是and后边的,及上式中的’Test is true’必须保证是True的

默认参数问题

这个是老问题了,这个链接说的很清楚了。主要是python中函数调用时,并不是每次都对默认参数进行赋值的,其实默认参数只是在函数编译的时候赋值一次而已。由于这种原因,这就会导致mutable变量出现问题。

当然,我们也可以利用这种特性,就像C中的静态变量一样

用字典来表达’Swith Statement’

因为python没有swith语法,比方说下面这种:

keycode = 2
if keycode == 1:
    key_1_pressed()
elif keycode == 2:
    key_2_pressed()
elif keycode == 2:
    key_3_pressed()
else:
    unknown_key_pressed()

可以用dict的方式来写:

keycode = 2
functions = {1: key_1_pressed, 2: key_2_pressed, 3:key_3_pressed}
functions.get(keycode, unknow_key_pressed)

用这种dict的方式看上去clean多了

Class

关于getter()和setter(), 我们应该用@property装饰器

可以用hasattr()和getattr()来判断成员变量是否存在和成员变量的值,但是不要过度使用这两个函数

类方法(通过类直接调用的,而非通过类实例调用的,它们的区别就在于是否有self变量)包含@classmethod@staticmethod

总结

  1. 遵守 PEP 8 google python sytle guide
  2. 尽量使用Built-in Functions

Reference

  1. Python Tips,Tricks, and Hacks
  2. Be Pythonic
  3. How to Write ‘Pythonic’ Code

PS:

  1. 这里有一份很有趣的文档A Guide to Pythons Magic Methods,讲的是类所包含的那些内置函数的,比如__init__ __lt__。有空的时候可以读读
  2. 发现一个WSGI Server bjoern,只有1000行C代码。一直都想了解一下这方面的知识,趁有空看一下

 类似资料: