在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:
在for-in语句、函数返回值上都应该使用Tuple的Unpack功能
比如:
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'))
单独使用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函数。
List会把整个List的元素都产生,并同时装入到内存中。所以对包含大量数据的List来说,这样的处理效果就会很低效。这种情况下,可以用Generator来替换List。Generator每次只装载一个元素,所以效率会比List高很多。但是,当需要list所以元素的计算结果时,则只能选择用List。下面是一个Generator expression
total = sum(num*num for num in xrange(1, 101))
下面的代码:
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]
如果遍历list的时候同时需要index,应该用enumerate
尽量用all、any这两个内置函数, 比如:
numbers = [1, 10, 1000, 10000]
if any(number<10 for number in numbers):
print 'Have number<10'
用zip来整合多个list。
dict和list是可以相互转换的。
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中的静态变量一样
因为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多了
关于getter()和setter(), 我们应该用@property
装饰器
可以用hasattr()和getattr()来判断成员变量是否存在和成员变量的值,但是不要过度使用这两个函数
类方法(通过类直接调用的,而非通过类实例调用的,它们的区别就在于是否有self变量)包含@classmethod
和@staticmethod
- 这里有一份很有趣的文档A Guide to Pythons Magic Methods,讲的是类所包含的那些内置函数的,比如
__init__
__lt__
。有空的时候可以读读- 发现一个WSGI Server bjoern,只有1000行C代码。一直都想了解一下这方面的知识,趁有空看一下