目 錄
1、海象表達(dá)式****1
2、強(qiáng)制位置參數(shù)****2
3、增強(qiáng)型f-string****2
4、continue關(guān)鍵字的使用****3
5、as_integer_ratio()方法****3
6、其他新增語法特性****3
(1)添加 \N{name} 轉(zhuǎn)義符在正則表達(dá)式 中的支持: 3
(2) 字典反向迭代 4
(3) 函數(shù)關(guān)鍵字參數(shù)限制 4
(4) yield和return語法增強(qiáng) 4
(5) 組合數(shù)據(jù)類型語法警告提示 4
(6) 日期時(shí)間對(duì)象改進(jìn) 5
(7) Ctrl-C終止程序的改進(jìn) 5
(8) 數(shù)據(jù)拷貝增強(qiáng)型語法 5
(9) pow()函數(shù)的改進(jìn) 5
(10) mod()取模的改進(jìn) 6
(11) 字典推導(dǎo)式的改進(jìn) 6
(12) 字典數(shù)據(jù)執(zhí)行順序 6
大牧出品,必屬精品
1、海象表達(dá)式
海象表達(dá)式,the walrus operator,一種語法上的優(yōu)化
可以在表達(dá)式內(nèi)部給變量進(jìn)行賦值
name = "damu"
if n := len(name) > 2:
print("hello the walrus operator")
print(n) # True
等價(jià)于
name = "damu"
n = len(name) > 2
if n:
print("hello the walrus operator")
print(n)
擴(kuò)展
類似的益處還可出現(xiàn)在正則表達(dá)式匹配中需要使用兩次匹配對(duì)象的情況中,一次檢測用于匹配是否發(fā)生,另一次用于提取子分組:
discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
discount = float(mo.group(1)) / 100.0**
另一個(gè)值得介紹的用例出現(xiàn)于列表推導(dǎo)式中,在篩選條件中計(jì)算一個(gè)值,而同一個(gè)值又在表達(dá)式中需要被使用:
[clean_name.title() for name in names
if (clean_name := normalize('NFC', name)) in allowed_names]
請(qǐng)盡量將海象運(yùn)算符的使用限制在清晰的場合中,以降低復(fù)雜性并提升可讀性
2、強(qiáng)制位置參數(shù)
python3.8提供了強(qiáng)制位置參數(shù),優(yōu)化參數(shù)較少的情況下的函數(shù)調(diào)用方式
# 強(qiáng)制位置參數(shù),符號(hào)/前面的參數(shù)必須使用位置參數(shù)的方式進(jìn)行數(shù)據(jù)傳值
def intro(name, /, gender, age):
print(f"name: {name}, gender: {gender}, age: {age}")
intro("damu", "male", 18) # 合法調(diào)用
intro(gender="male", age=18) # 合法調(diào)用intro(name="damu", gender="male", age=18) # 非法調(diào)用
3、增強(qiáng)型f-string
f-string是python3.6以后的版本中添加的一個(gè)快捷格式化字符數(shù)據(jù)的表達(dá)式
為了更好的完成程序中數(shù)據(jù)的調(diào)試和表示,python3.8添加了f-string=增強(qiáng)型語法
name = "DAMU"
age = 18
print(f"{name=}, {age=:d}") # name='DAMU', age=18
import math
print(f"{math.cos(math.radians(60))}") # 0.5
print(f"{math.cos(math.radians(60))=}") # math.cos(math.radians(60))=0.5
4、continue關(guān)鍵字的使用
python的循環(huán)語法中,continue關(guān)鍵字不允許在finally子句中使用
python3.8版本取消了該限制
index = 0
while index < 3:
try:
print("開始執(zhí)行運(yùn)算操作")
finally:
index += 1
if index == 2:
continue
print(f"大牧家的小姑娘的玩具又多啦,現(xiàn)在{index=}個(gè)啦")
5、as_integer_ratio()方法
bool、int和functions.Function類型,都添加了as_integer_ratio()方法,和現(xiàn)有的float以及decimal.Decimal類型中的已有方法類似,提高多種類型在數(shù)字使用上的通用性;將已有數(shù)值類數(shù)據(jù)轉(zhuǎn)換成分?jǐn)?shù)的通用表示形式,其中分母是整數(shù)
from decimal import Decimal
i = 12
b = False
d = Decimal('0.5')
f2 = 0.5
print(i.as_integer_ratio()) # (12, 1)
print(b.as_integer_ratio()) # (0, 1)
print(d.as_integer_ratio()) # (1, 2)
print(f2.as_integer_ratio()) # (1, 2)
6、其他新增語法特性
(1)添加\N{name} 轉(zhuǎn)義符在正則表達(dá)式中的支持:
>>> notice = 'Copyright ? 2019'
>>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})')
>>> int(copyright_year_pattern.search(notice).group(1))2019
#(由 Jonathan Eunice 和 Serhiy Storchaka 在[bpo-30688](https://bugs.python.org/issue30688) 中貢獻(xiàn)。)
(2) 字典反向迭代
現(xiàn)在 dict 和 dictview 可以使用reversed() 按插入順序反向迭代。 (由 Rémi Lapeyre 在bpo-33462 中貢獻(xiàn)。)
(3) 函數(shù)關(guān)鍵字參數(shù)限制
函數(shù)調(diào)用中允許使用的關(guān)鍵字名稱語法受到進(jìn)一步的限制。 特別地,f((keyword)=arg) 不再被允許。 關(guān)鍵字參數(shù)賦值形式的左側(cè)絕不允許一般標(biāo)識(shí)符以外的其他內(nèi)容。 (由 Benjamin Peterson 在bpo-34641 中貢獻(xiàn)。)
(4)yield和return語法增強(qiáng)
yield 和return 語句中的一般可迭代對(duì)象解包不再要求加圓括號(hào)。 這使得 yield 和 return 的語法與正常的賦值語法更為一致:
>>> def parse(family): lastname, *members = family.split() return lastname.upper(), *members
>>> parse('simpsons homer marge bart lisa sally')('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'sally')
(由 David Cuthbert 和 Jordan Chapman 在bpo-32117 中貢獻(xiàn)。)
(5) 組合數(shù)據(jù)類型語法警告提示
類似 [(10, 20) (30, 40)] 這樣在代碼中少了一個(gè)逗號(hào)時(shí),編譯器將顯示SyntaxWarning 并附帶更有幫助的提示。 這相比原來用TypeError 來提示第一個(gè)元組是不可調(diào)用的更容易被理解。 (由 Serhiy Storchaka 在bpo-15248 中貢獻(xiàn)。)
(6)日期時(shí)間對(duì)象改進(jìn)
datetime.date 或datetime.datetime 和datetime.timedelta 對(duì)象之間的算術(shù)運(yùn)算現(xiàn)在將返回相應(yīng)子類的實(shí)例而不是基類的實(shí)例。 這也會(huì)影響到在具體實(shí)現(xiàn)中(直接或間接地)使用了datetime.timedelta 算術(shù)運(yùn)算的返回類型,例如astimezone()。 (由 Paul Ganssle 在bpo-32417 中貢獻(xiàn)。)
(7) Ctrl-C終止程序的改進(jìn)
當(dāng) Python 解釋器通過 Ctrl-C (SIGINT) 被中斷并且所產(chǎn)生的KeyboardInterrupt 異常未被捕獲,Python 進(jìn)程現(xiàn)在會(huì)通過一個(gè) SIGINT 信號(hào)或是使得發(fā)起調(diào)用的進(jìn)程能檢測到它是由 Ctrl-C 操作殺死的正確退出代碼來退出。 POSIX 和 Windows 上的終端會(huì)相應(yīng)地使用此代碼在交互式會(huì)話中終止腳本。 (由 Google 的 Gregory P. Smith 在bpo-1054041 中貢獻(xiàn)。)
(8)數(shù)據(jù)拷貝增強(qiáng)型語法
某些高級(jí)編程風(fēng)格要求為現(xiàn)有的函數(shù)更新 types.CodeType 對(duì)象。 由于代碼對(duì)象是不可變的,需要基于現(xiàn)有代碼對(duì)象模型創(chuàng)建一個(gè)新的代碼對(duì)象。 使用 19 個(gè)形參將會(huì)相當(dāng)繁瑣。 現(xiàn)在,新的 replace() 方法使得通過少量修改的形參創(chuàng)建克隆對(duì)象成為可能。
下面是一個(gè)修改 statistics.mean() 函數(shù)來防止 data 形參被用作關(guān)鍵字參數(shù)的例子:
>>> from statistics import mean
>>> mean(data=[10, 20, 90])
40
>>> mean.__code__ = mean.__code__.replace(co_posonlyargcount=1)
>>> mean(data=[10, 20, 90])Traceback (most recent call last):
...TypeError: mean() got some positional-only arguments passed as keyword arguments: 'data'**
#(由 Victor Stinner 在**[bpo-37032](https://bugs.python.org/issue37032)** 中貢獻(xiàn)。)
(9)pow()函數(shù)的改進(jìn)
對(duì)于整數(shù),現(xiàn)在 pow() 函數(shù)的三參數(shù)形式在底數(shù)與模數(shù)不可約的情況下允許指數(shù)為負(fù)值。 隨后它會(huì)在指數(shù)為 -1 時(shí)計(jì)算底數(shù)的模乘逆元,并對(duì)其他負(fù)指數(shù)計(jì)算反模的適當(dāng)冪次。 例如,要計(jì)算 38 模 137 的模乘逆元 則可寫為:
>>> pow(38, -1, 137)119
>>> 119 * 38 % 1371
(10)mod()取模的改進(jìn)
模乘逆元在求解 線性丟番圖方程 會(huì)被用到。 例如,想要求出 4258 + 147 = 369 的整數(shù)解,首先應(yīng)重寫為 4258 ≡ 369 (mod 147) 然后求解:
>>> x = 369 * pow(4258, -1, 147) % 147
>>> y = (4258 * x - 369) // -147
>>> 4258 * x + 147 * y
369
(由 Mark Dickinson 在bpo-36027** 中貢獻(xiàn)。)**
(11) 字典推導(dǎo)式的改進(jìn)
字典推導(dǎo)式已與字典字面值實(shí)現(xiàn)同步,會(huì)先計(jì)算鍵再計(jì)算值:
>>> # Dict comprehension
>>> cast = {input('role? '): input('actor? ') for i in range(2)}
role? King Arthur
actor? Chapman
role? Black Knight
actor? Cleese
>>> # Dict literal
>>> cast = {input('role? '): input('actor? ')}
role? Sir Robin
actor? Eric Idle
(12) 字典數(shù)據(jù)執(zhí)行順序
對(duì)執(zhí)行順序的保證,對(duì)賦值表達(dá)式來說很有用,因?yàn)樵阪I表達(dá)式中賦值的變量將可在值表達(dá)式中被使用:
>>> names = ['Martin von L?wis', '?ukasz Langa', 'Walter D?rwald']
>>> {(n := normalize('NFC', name)).casefold() : n for name in names}
{'martin von l?wis': 'Martin von L?wis', '?ukasz langa': '?ukasz Langa', 'walter d?rwald': 'Walter D?rwald'}**
#(由 J?rn Heissler 在**[bpo-35224](https://bugs.python.org/issue35224)** 中貢獻(xiàn)。)
object.reduce() 方法現(xiàn)在可返回長度為二至六個(gè)元素的元組。 之前的上限為五個(gè)。 新增的第六個(gè)可選元素是簽名為 (obj, state) 的可調(diào)用對(duì)象。 這樣就允許直接控制特定對(duì)象的狀態(tài)更新。 如果元素值不為 None,該可調(diào)用對(duì)象將優(yōu)先于對(duì)象的setstate() 方法。 (由 Pierre Glaser 和 Olivier Grisel 在bpo-35900 中貢獻(xiàn)。)