Python語法糖系列

  • 2019 年 10 月 5 日
  • 筆記

語法糖說明

語法糖(Syntactic sugar):

電腦語言中特殊的某種語法

這種語法對語言的功能並沒有影響

對於程式設計師有更好的易用性

能夠增加程式的可讀性

簡而言之,語法糖就是程式語言中提供[奇技淫巧]的一種手段和方式而已。 通過這類方式編寫出來的程式碼,即好看又好用,好似糖一般的語法。固美其名曰:語法糖

一個簡單的例子

假設:有2個數字,現需要從中得到最大的那個數字。如何實現?

b = 2 c = 3 if b > c: a = b else: a = c

其實還有更多的其它實現方式:

a = max(b, c) a = c > b and c or b a = c if c > b else b a = [b, c][c > b]

這些都是可以實現我們需求的方法,殊途同歸。但是它們在易用性、簡潔性、可讀性、性能等方面的表現都不一樣。那麼問題來了!

哪個才是我們所說的語法糖呢?

一些常見的語法糖

a = b = 2; c = 3 b, c = c, b a < c < b < 5 '1' * 100 [1,2,3,4] + [5,6,7,8]

可以看到這些語法,在其它語言里通常不會出現的。但是在Python中卻神奇的被支援了,所以這些都是當之無愧的Python語法糖。

切片操作

像列表這類可以支援**切片**操作的對象,則是我最初喜歡Python的一個非常重要的原因。

l = [1, 2, 3, 4, 5] l[2] l[:3] l[3:] l[2:4] l[:-1] l[:] l[::2]

else語法糖

Python中提供一類else的語法,它可以在原有語法基礎之上,支援更多一種情況的選擇。 主要有for-else,while-else,try-else。需要注意的是,for-else和while-else需要和break語句配合時使用。

for else

for i in range(1): print(i) break else: print('for end')

while else

i = 1 while i: print(i) i -= 1 break else: print('while end')

try else

try: 1 / 1 except Exception as e: print('except occured') else: print('it is fine') finally: print('i am finally')

函數相關語法糖

Python中函數我們都非常的熟悉,而在函數的使用上卻有著與其它語言不同的選擇。

動態參數

def example_dynamic_args(*args, **kwargs): '''動態參數''' print(args) print(kwargs)

這個函數的參數與函數相比,其參數會有些不同之處。因為它們在接收參數時使用了不同方式。

example_dynamic_args(1,'2', True, name='xiaowu', age=18) l = [1,'2',False] d = {'name': 'xiaoming', age: '16'} example_dynamic_args(*l, **d)

匿名函數

匿名函數在很多的語言中都存在,通常在臨時需要一個函數的場景下使用。

lambda x: x * 2

Python中使用lambda表達式來實現匿名函數,觀察上面的lambda表達式。其特點如下:

  • 可以接受函數
  • 函數體只有一個表達式
  • 無需顯式的return語句
  • 整個表達式在一個語法行內實現

值得注意的是,lambda表達式除了一些語法上的限制之外;其它函數該有的特性它都有。比如:支援動態參數。下面是一個使用lambda表示的場景:

in_dict = {'a': 10, 'b': 2, 'c': 3} print('in_dict:', in_dict) out_dict = sorted(in_dict.items(), key=lambda x: x[1]) print('out_dict', out_dict)

推導表達式

推導表達式是Python中常見的語法糖,在很多的數據處理場景中,我們可能會使用的到。 最常見的就是列表推導表達式,可以用來過濾、處理列表中的子項並輸出一個新的列表。除此之外還有幾個推導式也是非常好用的。

列表推導表達式

in_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7] print('array before:', in_list) array = [i for i in in_list if i % 2 != 0] # 列表推導表達式 print('array after:', array)

生成器推導表達式

in_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7] print('array before:', in_list) array = (i for i in in_list if i % 2 != 0) # 生成器推導表達式 print('array after:', array)

集合推導表達式

in_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7] print('array before:', in_list) array = {i for i in in_list if i % 2 != 0} # 集合推導表達式 print('array after:', array)

字典推導表達式

in_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7] print('array before:', in_list) array = {i: i * 2 for i in in_list if i % 2 != 0} # 字典推導表達式 print('array after:', array)

不同推導式在語法使用上基本一致,只是在返回對象的類型上有所差別。

yield表達式

yield語法也是Python中比較有特點的語法糖,可以說是特有的。雖然其它語言有實現類似機制的功能。 yield是Python中實現**協程(coroutine)**的一個重要基礎。

def example_generator(in_list): '''生成器''' for i in in_list: yield i * 2

裝飾器

重要的往往在最後面,裝飾器是學習Python繞不過去的坎。就像學習Java要理解面向對象和設計模式一樣。 學習Python,你就應該要掌握好閉包、生成器、裝飾器等相關知識。而對於編寫高並發程式時則要掌握協程相關知識。

def example_decorator(func): '''裝飾器''' def inner(): func() return inner

更多學習

  • Python裝飾器詳解
  • Python多執行緒GIL
  • Python魔法屬性
  • Python語法糖

Tags: