當前位置:
首頁 > 知識 > 符合語言習慣的Python優雅編程技巧

符合語言習慣的Python優雅編程技巧


程序員大咖

點擊右側關注,免費進階高級!





http://lovesoo.org/pythonic-python-programming.html




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[

0

]
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] =

0


   navs[portfolio] += position * prices[equity]

##推薦


navs = {}

for

(portfolio, equity, position)

in

data:
   

# 使用 get 方法


   navs[portfolio] = navs.get(portfolio,

0

) + position * prices[equity]
   

# 或者使用 setdefault 方法


   navs.setdefault(portfolio,

0

)
   navs[portfolio] += position * prices[equity]

8、判斷真偽

##不推薦


if

x ==

True

:
   

# ....


if

len(items) !=

0

:
   

# ...


if

items != []:
   

# ...  

##推薦


if

x:
   

# ....


if

items:
   

# ...


9、遍歷列表以及索引

##不推薦


items =

"zero one two three"

.split()

# method 1


i =

0


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 =

0


   result = []
   

while

i < n:
       result.append(fn(i))
       i +=

1


   

return

result  

#  返回列表

##推薦


def

my_range

(n)

:


   i =

0


   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 >

0

: 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 >

0

: 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:
   

# 互斥操作...


參考


1) Idiomatic Python:


http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html


2) PEP 8: Style Guide for Python Code: 


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


【點擊成為源碼大神】

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發 的精彩文章:

現在開始一個全新的Android項目
Scrapy詳解之中間件(Middleware)

TAG:Python開發 |