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語法糖