符合語言習慣的 Python 優雅程式設計技巧

dicksonjyl560101發表於2018-11-08

來源:安生      連結:

Python最大的優點之一就是語法簡潔,好的程式碼就像虛擬碼一樣,乾淨、整潔、一目瞭然。要寫出 Pythonic(優雅的、地道的、整潔的)程式碼,需要多看多學大牛們寫的程式碼,github 上有很多非常 優秀的原始碼值得閱讀,比如:requests、flask、tornado,下面列舉一些常見的Pythonic寫法。

0. 程式必須先讓人讀懂,然後才能讓計算機執行。

“Programs must be written for people to read, and only incidentally for machines to execute.”

1. 交換賦值



##不推薦


temp = a
a = b
b = a  

##推薦
a, b = b, a   #  先生成一個元組(tuple)物件,然後unpack

2. Unpacking



##不推薦


l = [ 'David' 'Pythonista' '+1-514-555-1234' ]
first_name = l[ ]
last_name = l[ 1 ]
phone_number = l[ 2 ]  

##推薦
l = [ 'David' 'Pythonista' '+1-514-555-1234' ]
first_name, last_name, phone_number = l
# Python 3 Only
first, *middle, last = another_list

3. 使用運算子in



##不推薦


if  fruit ==  "apple"   or  fruit ==  "orange"   or  fruit ==  "berry" :
     # 多次判斷  

##推薦
if  fruit  in  [ "apple" "orange" "berry" ]:
     # 使用 in 更加簡潔

4. 字串操作



##不推薦


colors = [ 'red' 'blue' 'green' 'yellow' ]

result =  ''
for  s  in  colors:
    result += s   #  每次賦值都丟棄以前的字串物件, 生成一個新物件  

##推薦
colors = [ 'red' 'blue' 'green' 'yellow' ]
result =  '' .join(colors)   #  沒有額外的記憶體分配

5. 字典鍵值列表



##不推薦


for  key  in  my_dict.keys():
     #  my_dict[key] ...  

##推薦
for  key  in  my_dict:
     #  my_dict[key] ...

# 只有當迴圈中需要更改key值的情況下,我們需要使用 my_dict.keys()
# 生成靜態的鍵值列表。

6. 字典鍵值判斷



##不推薦


if  my_dict.has_key(key):
     # ...do something with d[key]  

##推薦
if  key  in  my_dict:
     # ...do something with d[key]

7. 字典 get 和 setdefault 方法



##不推薦


navs = {}
for  (portfolio, equity, position)  in  data:
     if  portfolio  not   in  navs:
            navs[portfolio] = 
    navs[portfolio] += position * prices[equity]
##推薦
navs = {}
for  (portfolio, equity, position)  in  data:
     # 使用 get 方法
    navs[portfolio] = navs.get(portfolio,  ) + position * prices[equity]
     # 或者使用 setdefault 方法
    navs.setdefault(portfolio,  )
    navs[portfolio] += position * prices[equity]

8. 判斷真偽



##不推薦


if  x ==  True :
     # ....
if  len(items) !=  :
     # ...
if  items != []:
     # ...  

##推薦
if  x:
     # ....
if  items:
     # ...

9. 遍歷列表以及索引



##不推薦


items =  'zero one two three' .split()
# method 1
i = 
for  item  in  items:
     print  i, item
    i +=  1
# method 2
for  i  in  range(len(items)):
     print  i, items[i]

##推薦
items =  'zero one two three' .split()
for  i, item  in  enumerate(items):
     print  i, item

10. 列表推導



##不推薦


new_list = []
for  item  in  a_list:
     if  condition(item):
        new_list.append(fn(item))  

##推薦
new_list = [fn(item)  for  item  in  a_list  if  condition(item)]

11. 列表推導-巢狀



##不推薦


for  sub_list  in  nested_list:
     if  list_condition(sub_list):
         for  item  in  sub_list:
             if  item_condition(item):
                 # do something...  
##推薦
gen = (item  for  sl  in  nested_list  if  list_condition(sl) \
             for  item  in  sl  if  item_condition(item))
for  item  in  gen:
     # do something...

12. 迴圈巢狀



##不推薦


for  x  in  x_list:
     for  y  in  y_list:
         for  z  in  z_list:
             # do something for x & y  

##推薦
from  itertools  import  product
for  x, y, z  in  product(x_list, y_list, z_list):
     # do something for x, y, z

13. 儘量使用生成器代替列表



##不推薦


def   my_range (n) :
    i = 
    result = []
     while  i < n:
        result.append(fn(i))
        i +=  1
     return  result   #  返回列表

##推薦
def   my_range (n) :
    i = 
    result = []
     while  i < n:
         yield  fn(i)   #  使用生成器代替列表
        i +=  1
*儘量用生成器代替列表,除非必須用到列表特有的函式。

14. 中間結果儘量使用imap/ifilter代替map/filter



##不推薦


reduce(rf, filter(ff, map(mf, a_list)))

##推薦
from  itertools  import  ifilter, imap
reduce(rf, ifilter(ff, imap(mf, a_list)))
*lazy evaluation 會帶來更高的記憶體使用效率,特別是當處理大資料操作的時候。

15. 使用any/all函式



##不推薦


found =  False
for  item  in  a_list:
     if  condition(item):
        found =  True
         break
if  found:
     # do something if found...  

##推薦
if  any(condition(item)  for  item  in  a_list):
     # do something if found...

16. 屬性(property)



##不推薦


class   Clock (object) :
     def   __init__ (self) :
        self.__hour =  1
     def   setHour (self, hour) :
         if   25  > hour >  : self.__hour = hour
         else raise  BadHourException
     def   getHour (self) :
         return  self.__hour

##推薦
class   Clock (object) :
     def   __init__ (self) :
        self.__hour =  1
     def   __setHour (self, hour) :
         if   25  > hour >  : self.__hour = hour
         else raise  BadHourException
     def   __getHour (self) :
         return  self.__hour
    hour = property(__getHour, __setHour)

17. 使用 with 處理檔案開啟



##不推薦


f = open( "some_file.txt" )
try :
    data = f.read()
     # 其他檔案操作..
finally :
    f.close()

##推薦
with  open( "some_file.txt" as  f:
    data = f.read()
     # 其他檔案操作...

18. 使用 with 忽視異常(僅限Python 3)



##不推薦


try :
    os.remove( "somefile.txt" )
except  OSError:
     pass

##推薦
from  contextlib  import  ignored   # Python 3 only

with  ignored(OSError):
    os.remove( "somefile.txt" )

19. 使用 with 處理加鎖



##不推薦


import  threading
lock = threading.Lock()

lock.acquire()
try :
     # 互斥操作...
finally :
    lock.release()

##推薦
import  threading
lock = threading.Lock()

with  lock:
     # 互斥操作...

20. 參考

1) Idiomatic Python: 

~goodger/projects/pycon/2007/idiomatic/handout.html

2) PEP 8: Style Guide for Python Code: 

http://www.python.org/dev/peps/pep-0008/

轉自: http://blog.sina.com.cn/s/blog_cfa68e330102z11j.html


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29829936/viewspace-2219181/,如需轉載,請註明出處,否則將追究法律責任。

相關文章