Python在2020的新增功能:第1部分
自從很久以前改用了python3,語(yǔ)言層面的特征變化就相對(duì)較小了,然而對(duì)于每一個(gè)版本,Python都會(huì)添加一些新函數(shù)。隨著Python3.8于2019年10月發(fā)布,我發(fā)現(xiàn)自己使用的是這種語(yǔ)言的一些特性,關(guān)于Python每個(gè)版本新增的特性,有如下3.5-類型注解3.6-異步3.7-數(shù)據(jù)類3.8-海象算子3.9-字典聯(lián)合運(yùn)算符和泛型類型提示以上所有的這些,我都會(huì)在代碼庫(kù)中使用到。
oapbox演講:如果你仍在工作或項(xiàng)目中使用舊版本的Python,不要害怕升級(jí)!你的舊代碼仍然可以工作,而且你將從Python的新特性中獲益!免責(zé)聲明:如果你仍然使用Python2.7,在這種情況下,我知道你很有可能不會(huì)升級(jí)。
下面我將回顧(快速)我最喜歡的一些特性,我希望你可以在你的代碼中使用。它們是:類型注解、數(shù)據(jù)類、字典聯(lián)合運(yùn)算符、海象算子。在這第一部分,我主要介紹:類型注解,海象算子。Python 3.5從Python 3開(kāi)始,Typing就成為了一個(gè)特性。因?yàn)槲覀兪情_(kāi)發(fā)人員,而不是歷史學(xué)家,所以Typing將提供類型注解和類型提示。Python不需要為變量指定類型,這是我如此熱愛(ài)這門語(yǔ)言的部分原因。清晰易讀的語(yǔ)法,可以用20多種不同的方法編寫一個(gè)解決方案,但仍能得到相同的結(jié)果。但后來(lái)隨著應(yīng)用程序的增長(zhǎng),或者回頭看看你幾個(gè)月或幾年沒(méi)碰過(guò)的代碼,或者去閱讀別人寫的代碼。這種情況下,你就會(huì)意識(shí)到變量不指定類型對(duì)你來(lái)說(shuō)沒(méi)有啥好處。Typing 可以幫助你解決這個(gè)問(wèn)題,這也是TypeScript如此流行的原因。from typing import List
def print_cats(cats: List[str]) -> None:
for cat in cats:
print(f"{cat} has a name with {len(cat)} letters.")
class Cat(object):
def __init__(self, name: str, age: int, **attrs):
self.cattributes = {
"name": name,
"age": age,
**attrs
}
cats = "this still works w/o type annotation!"
cats: List[str] = ["Meowie", "Fluffy", "Deathspawn"]
# 不是字符串列表,Python不會(huì)檢查
cats2: List[str] = [Cat("Meowie", 2), Cat("Deathspawn", 8)]
print_cats(cats)
print_cats(cats2) # 失敗
這將返回:Meowie has a name with 6 letters.
Fluffy has a name with 6 letters.
Deathspawn has a name with 10 letters.
--------------------------------------------
...
TypeError: object of type 'Cat' has no len()
類型注解在這里并沒(méi)有起到任何作用,那為什么要使用它們呢?因?yàn)樵趧?chuàng)建變量cats并用List[str]時(shí),很明顯分配的數(shù)據(jù)應(yīng)該與該結(jié)構(gòu)相匹配,因此對(duì)于具有復(fù)雜類型的可維護(hù)代碼來(lái)說(shuō),這將變得更加有用。from typing import List
class Cat(object):
def __init__(self, name: str, age: int, **attrs):
self.cattributes = {
"name": name,
"age": age,
**attrs
}
# 創(chuàng)建類型變量
Cats: type = List[Cat]
def print_cats(cats: Cats) -> None:
for cat in cats:
name: str = cat.cattributes.get("name")
print(f"{name} has a name with {len(name)} letters.")
cats = [Cat("Meowie", 2), Cat("Deathspawn", 8)]
print_cats(cats)
輸出:Meowie has a name with 6 letters.
Deathspawn has a name with 10 letters.
在函數(shù)/方法定義中鍵入?yún)?shù)稱為類型暗示,而且類型甚至不必是Python數(shù)據(jù)類型或來(lái)自typing模塊。例如最后一行提示性字符串是完全合法的:import pandas as pd
cols = ["name", "age", "gender"]
data = [["Meowie", 2, "female"],
["Fluffy", 5, "male"],
["Deathspawn", 8, "rather not say"]]
df: pd.DataFrame = pd.DataFrame()
df: "name (string), age (integer), gender (string)" =
pd.DataFrame(data, columns=cols)
在數(shù)據(jù)處理管道中,如果有很多復(fù)雜類型的變量,那這樣的操作可能會(huì)很有用,因?yàn)槟憧赡芨悴磺宄x取的數(shù)據(jù)是什么結(jié)構(gòu),你會(huì)試圖把它們弄清楚。在IDE上鼠標(biāo)懸停在變量上會(huì)有類型提示的信息,而不是一個(gè)簡(jiǎn)單的pandas.DataFrame提示。額外的好處是:在python4中,前向引用可以開(kāi)箱即用,這意味著你可以對(duì)尚未定義的類型進(jìn)行注解。我們現(xiàn)在仍然可以利用這種優(yōu)勢(shì),在文件頂部編寫from __future__ import annotations,然后執(zhí)行以下操作:from __future__ import annotations
class Food:
"""
Food是合法的,即使沒(méi)有類別的定義。
"""
def __init__(self, ingred_1: Food, ingred_2: Food) -> None:
self.ingred_1 = ingred_1
self.ingred_2 = ingred_2
原生類型注解-3.9內(nèi)置泛型類型是3.9中的一個(gè)特性,我們不需要從typing中導(dǎo)入以向泛型數(shù)據(jù)類型添加參數(shù)。從3.7版開(kāi)始,使用from __futures__ import annotations就可以使用這種方法,但這是因?yàn)樗柚沽嗽谶\(yùn)行時(shí)計(jì)算類型引用。這個(gè)功能讓我很興奮。在3.8中我將typing導(dǎo)入每個(gè)模塊,或者導(dǎo)入在公共模塊中。示例(信貸:PEP 585):>>> l = list[str]()
[]
>>> list is list[str]
False
>>> list == list[str]
False
>>> list[str] == list[str]
True
>>> list[str] == list[int]
False
>>> isinstance([1, 2, 3], list[str])
TypeError: isinstance() arg 2 cannot be a parameterized generic
>>> issubclass(list, list[str])
TypeError: issubclass() arg 2 cannot be a parameterized generic
>>> isinstance(list[str], types.GenericAlias)
True
def find(haystack: dict[str, list[int]]) -> int:
...
海象算子-3.8海象有眼睛:,然后有牙齒=。:=是Python3.8中新增的賦值表達(dá)式。complicated = {
"data": {
"list": [1,2,3],
"other": "stuff"
}
}
if (nums := complicated.get('data').get('list')):
print(nums)
結(jié)果:1
2
3
如果沒(méi)有海象,會(huì)有更多的代碼行。...
nums = complicated.get('data').get('list')
if nums:
print(nums)
由于控制流語(yǔ)句在編程中經(jīng)常使用,使用海象算子可以簡(jiǎn)化代碼。來(lái)自PEP 572:這樣的命名表達(dá)式的值與合并表達(dá)式的值的結(jié)果是相同的,但附加的作用是目標(biāo)被賦給了該值換言之,用一個(gè)表達(dá)式表達(dá)了兩個(gè)語(yǔ)句。在我復(fù)制/粘貼PEP指南的同時(shí),這里還有一些規(guī)范中的示例,我認(rèn)為它們是很好的示例。迫不及待地想嘗試一下海象算子來(lái)理解列表。# #處理匹配正則表達(dá)式
if (match := pattern.search(data)) is not None:
# 匹配后...
# 一個(gè)更直觀易寫的循環(huán)
while chunk := file.read(8192):
process(chunk)
# 重用一個(gè)計(jì)算成本很高的值
[y := f(x), y**2, y**3]
# 在理解filter語(yǔ)句及其輸出之間共享子表達(dá)式
filtered_data = [y for x in data if (y := f(x)) is not None]
結(jié)論最近對(duì)Python語(yǔ)言的添加提供了一些相當(dāng)不錯(cuò)的特性以供實(shí)踐。我希望你覺(jué)得typing和海象算子對(duì)你的編程是有用。

發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
3月27日立即報(bào)名>> 【工程師系列】汽車電子技術(shù)在線大會(huì)
-
4月30日立即下載>> 【村田汽車】汽車E/E架構(gòu)革新中,新智能座艙挑戰(zhàn)的解決方案
-
5月15-17日立即預(yù)約>> 【線下巡回】2025年STM32峰會(huì)
-
即日-5.15立即報(bào)名>>> 【在線會(huì)議】安森美Hyperlux™ ID系列引領(lǐng)iToF技術(shù)革新
-
5月15日立即下載>> 【白皮書】精確和高效地表征3000V/20A功率器件應(yīng)用指南
-
5月16日立即參評(píng) >> 【評(píng)選啟動(dòng)】維科杯·OFweek 2025(第十屆)人工智能行業(yè)年度評(píng)選
推薦專題
-
10 月之暗面,絕地反擊
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達(dá)AI統(tǒng)治的開(kāi)始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產(chǎn)業(yè)發(fā)展新路徑
- 3 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 4 “AI寒武紀(jì)”爆發(fā)至今,五類新物種登上歷史舞臺(tái)
- 5 國(guó)產(chǎn)智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計(jì)算迎來(lái)商業(yè)化突破,但落地仍需時(shí)間
- 7 東陽(yáng)光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開(kāi)成長(zhǎng)空間
- 8 地平線自動(dòng)駕駛方案解讀
- 9 封殺AI“照騙”,“淘寶們”終于不忍了?
- 10 優(yōu)必選:營(yíng)收大增主靠小件,虧損繼續(xù)又逢關(guān)稅,能否乘機(jī)器人東風(fēng)翻身?