python教程值得收藏的python語法總結

2022-01-02 python新手教程



python教程

在人工智慧的風口,Python越來越受歡迎,很多小夥伴也紛紛想要開始學習Python。作為一個Python近2年的學習者,為大家獻上一些不錯的Python自學乾貨。

這是我在自學路上,整理的不錯的Python自學資料。需要的小夥伴可以掃描下方二維碼: python教程

                

因為加的人多,大家一定要填寫備註:{333} 否則不通過,請理解。通過後,請主動領取。

作者:袁昊 騰訊專項技術測試工程師python教程

2020年python2停止維護,而隨著Python版本的不斷更新,許多舊的語法在可讀性與效率上都已經有更好的替代了。當然,大部分的重要特性,例如裝飾器、生成器、async等,相信大家都已經瞭然於心,這裡就對一些用的稍微少一些、日常看到的代碼中不太常見的能用得上的語法做一個簡單的筆記,供大家參考。經驗有限,見解甚淺,還望各位大佬們多多指導、補充。

日常的自用Python腳本沒有太大的工程壓力,能緊跟更新步伐、嘗試新的特性。但是語法糖用的好就是效率提升,用的不好就是可讀性災難,有些語法的出現也伴隨著種種的爭議,用更新的語法不代表能寫出更好的代碼。


翻看語言的更新日誌確實蠻有意思


通過語法的更新變化還有變化帶來的爭議,也能窺透語言的設計哲學、匯聚濃縮在一個特定點上的社區開發經驗。選擇合適自己的、保持對代碼精簡可讀的追求才是最重要。

那麼就從老到新,理一理那些有意思的小feature吧。可能有漏掉有趣的點、也可能有解釋不到位的地方,歡迎各位大佬更正補充。

Python 3.0-3.6PEP 3132 可迭代對象解包拓展

Python3.0引入,加強了原本的星號運算符(*),讓星號運算符能夠智能地展開可迭代對象。

>>> a, *b, c = range(5)>>> a0>>> c4>>> b[1, 2, 3]

隱式賦值也同樣適用

>>> for a, *b in [(1, 2, 3), (4, 5, 6, 7)]:>>>     print(b)[2, 3][5, 6, 7]

注意雙星號(**)不能用相同語法展開字典

人畜無害,用處也不大的一個feature

PEP 465 矩陣乘法運算符

Python3.5引入,顧名思義,使用@符號。直接支持numpy、pandas等使用。

>>> a = numpy.array([1, 2, 3])>>> b = numpy.array([10, 20, 30])>>> a @ b140>>> c = numpy.array([[10, 15], [20, 25], [30, 35]])>>> d = numpy.array([[4, 5, 6], [7, 8, 9]])>>> c @ darray([[145, 170, 195],       [255, 300, 345],       [365, 430, 495]])

矩陣乘法運算符的魔術方法為__matmul__()、__rmatmul__()、__imatmul__()三個

本身用處不大,但是提供了一個額外的操作符使用空間,可以用來重載來進行類似距離計算之類的用途。

>>> from math import sqrt>>> class Point:>>>     def __init__(self, x, y):>>>         self.x = x>>>         self.y = y>>> >>>     def __matmul__(self, value):>>>         x_sub = self.x - value.x>>>         y_sub = self.y - value.y>>>         return sqrt(x_sub**2 + y_sub**2)>>> >>> a = Point(1, 3)>>> b = Point(4, 7)>>> print(a @ b)5

爭議主要存在於:作為矩陣乘法來說@操作符沒有直觀聯繫、影響可讀性,不如直接使用matmul

PEP 3107/484/526 函數註解/類型提示/變量註解

Python3.0引入函數註解、3.5引入typing,讓python也能享受靜態類型的福利。可以說是py3中個人最喜歡的feature,使用簡單、效果強大,直接讓開發效率以及代碼可維護性直線增長。

# 參數後加:即可標註類型,函數結構定義後接->即可標註返回類型def get_hello(name: str) -> str:    return f"Hello, {name}!"

如上進行標記之後IDE便能自動讀取參數、返回類型,直接出聯想爽快如java。

而PEP 484 Typing則是極大的擴充了類型定義語法,支持別名、泛型、Callable、Union等等。非常推薦直接閱讀PEP。

https://www.python.org/dev/peps/pep-0484/

下面就是一個泛型的例子

from typing import TypeVar, Iterable, TupleT = TypeVar('T', int, float, complex)Vector = Iterable[Tuple[T, T]]def inproduct(v: Vector[T]) -> T:    return sum(x*y for x, y in v)def dilate(v: Vector[T], scale: T) -> Vector[T]:    return ((x * scale, y * scale) for x, y in v)vec = []  # type: Vector[float]

隨後在3.6引入了眾望所歸的變量註解(PEP 526),使用也很簡單,直接在變量後添加冒號和類型即可,搭配函數註解一起食用體驗極佳

pi: float = 3.142# 也同樣支持Union等from typing import Uniona: Union[float,None] =1.0

3.7中又引入了延遲標記求值(PEP 563),讓typing支持了前向引用、並減輕了標註對程序啟動時間的影響,如虎添翼。

# 3.7前合法class Tree:    def __init__(self, left: 'Tree', right: 'Tree'):        self.left = left        self.right = right# 3.7前不合法、3.7後合法class Tree:    def __init__(self, left: Tree, right: Tree):        self.left = left        self.right = right

更多的python類型檢查示例代碼:

https://github.com/realpython/materials/tree/master/python-type-checking

靜態類型檢查對Python所帶來的副作用主要還是啟動時間上的影響,當然大部分場景所帶來的便利是遠大於這一副作用的。

PEP 498 f-string

Python3.6引入,應該是用的最多的feature之一了,但是看到很多代碼裡面還是str.format,就不得不再提一下。

>>> a = 10>>> #只需要簡單的在任意字符串字面量前加個f,就可以用花括號直接引用變量>>> print(f"a = {a}")a = 10>>> # 格式化也很方便,使用:即可>>> pi = 3.14159>>> print(f"pi = {pi: .2f}")pi = 3.14

也可以在表達式後接!s或者!r來選擇用str()還是repr()方法轉換為字符串。

基本就是str.format的語法糖。在3.8版本以後,又增加了直接套表達式的功能,輸出信息非常方便。

>>> theta = 30>>> print(f'{theta=}  {cos(radians(theta))=:.3f}')theta=30  cos(radians(theta))=0.866

PEP 515 數值字面值下劃線

Python3.6引入。輸入太長的數字字面值怎麼辦?

>>> a = 123_456_789>>> b = 123456789>>> a == bTrue

比較雞肋...

Python 3.7PEP 557 數據類Data Classes

提供了一個方便的dataclass類裝飾器,直接上代碼舉例:

from dataclasses import dataclass@dataclassclass InventoryItem:    name: str    unit_price: float    quantity_on_hand: int = 0    def total_cost(self) -> float:        return self.unit_price * self.quantity_on_hand

對這個例子,這個類會自動生成以下魔術方法

def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0) -> None:    self.name = name    self.unit_price = unit_price    self.quantity_on_hand = quantity_on_handdef __repr__(self):    return f'InventoryItem(name={self.name!r}, unit_price={self.unit_price!r}, quantity_on_hand={self.quantity_on_hand!r})'def __eq__(self, other):    if other.__class__ is self.__class__:        return (self.name, self.unit_price, self.quantity_on_hand) == (other.name, other.unit_price, other.quantity_on_hand)    return NotImplementeddef __ne__(self, other):    if other.__class__ is self.__class__:        return (self.name, self.unit_price, self.quantity_on_hand) != (other.name, other.unit_price, other.quantity_on_hand)    return NotImplementeddef __lt__(self, other):    if other.__class__ is self.__class__:        return (self.name, self.unit_price, self.quantity_on_hand) < (other.name, other.unit_price, other.quantity_on_hand)    return NotImplementeddef __le__(self, other):    if other.__class__ is self.__class__:        return (self.name, self.unit_price, self.quantity_on_hand) <= (other.name, other.unit_price, other.quantity_on_hand)    return NotImplementeddef __gt__(self, other):    if other.__class__ is self.__class__:        return (self.name, self.unit_price, self.quantity_on_hand) > (other.name, other.unit_price, other.quantity_on_hand)    return NotImplementeddef __ge__(self, other):    if other.__class__ is self.__class__:        return (self.name, self.unit_price, self.quantity_on_hand) >= (other.name, other.unit_price, other.quantity_on_hand)    return NotImplemented

這一條PEP也是比較有爭議的,主要原因是Python其實已經內置了不少的類似模型:collection.namedtuple、typing.NamedTuple、attrs等

但是這條PEP的提出還是為了保證方便地創建資料類的同時,保證靜態類型檢查,而已有的方案都不方便直接使用檢查器。

Python 3.8PEP 572 海象牙運算符

"逼走"了Guido van Rossum,最有爭議的PEP之一。首先引入了海象牙運算符:=,代表行內賦值。

# Beforewhile True:    command = input("> ");    if command == "quit":        break    print("You entered:", command)    # Afterwhile (command := input("> ")) != "quit":    print("You entered:", command)

assignment expressions在進行分支判斷時非常好用,寫的時候能夠舒服很多。本身使用也集中在if/while這種場景,雖然讓語法變複雜了,但是總體還是可控的,舒適程度大於風險。

海象運算符本身問題不大,但是爭議主要存在於PEP 572的第二點,對於生成器語義的變化。

在PEP 572後,生成器的in後的運算順序產生了變化,原本是作為生成器輸入,結果現在變成了生成器閉包的一部分。

temp_list = ["abc","bcd"]result_list = (x for x in range(len(temp_list)))print(list(result_list))# 等價於# Beforetemp_list = ["abc", "bcd"]def func_data(data: int):    for x in range(data):        yield xresult_list = func_data(len(temp_list))print(list(result_list))# Aftertemp_list = ["abc", "bcd"]def func_data():    for x in range(len(temp_list)):        yield xresult_list = func_data()print(list(result_list))

這樣的修改目的是配合海象牙運算符增加代碼可讀性,但無疑是帶破壞性的修改,且讓運行順序變得迷惑,讓一些老代碼出現難以發現的bug。

python社區在激烈辯論後,這一部分的修改被成功撤銷,只保留了海象牙運算符。

關於這個PEP,知乎上有難得一見的有價值討論,這部分範例代碼也引用自此:

https://www.zhihu.com/question/274823057/answer/376917512

PEP 570 僅限位置形參

在函數形參處新增一個/語法,劃分非關鍵字與關鍵字形參。例如

def f(a, b, /, c, d, *, e, f):    print(a, b, c, d, e, f)# 以下調用均合法f(10, 20, 30, d=40, e=50, f=60)# 以下調用均不合法f(10, b=20, c=30, d=40, e=50, f=60)   # b cannot be a keyword argumentf(10, 20, 30, 40, 50, f=60)           # e must be a keyword argument

/語法的添加讓調用函數時可以在可讀性與簡潔之間自由選擇,可以選擇強制不接受關鍵字參數、不需要形參名稱時也可以省略。同時也讓接受任意參數函數的實現變得方便了許多,例如:

class Counter(dict):    def __init__(self, iterable=None, /, **kwds):        # Note "iterable" is a possible keyword argument

這條本來也有其他方案,例如裝飾器實現、def fn(.arg1, .arg2, arg3):、def fn(a, (b, c), d):等,這裡就不一一展開了,推薦閱讀PEP原文。

Python 3.9PEP 584 字典合併運算符

在此之前,要想合併兩個字典的畫風是這樣的

a={'a':1,'b':2}b={'c':3}a.update(b)# 或者是c = {**a, **b}

但自從有了|之後,可以變成這樣

a |= bc = a | b

當然這個操作符也伴隨著一些爭議,大概是這樣:

反方:合併不符合交換律 正方:python字典合併本身就不符合交換律,特別是python3.6之後統一到有序字典後,相比合併應該更類似於拼接

反方:類似管道寫法進行多次合併效率低,反覆創建和銷毀臨時映射 正方:這種問題在序列級聯時同樣會出現。如果真出現了合併大量字典的使用場景,應當直接顯式循環合併

反方:|操作符容易和位運算混淆。運算符行為強依賴於變量種類,這在python是非常不利於可讀性的 正方:確實有這個問題,但是|已經很混亂了(位運算、集合操作、__or__()魔術方法重載),所以還是先規範變量命名吧

即將到來的Python 3.10PEP 617 / bpo-12782 括號內的上下文管理

這一條是針對with語法(PEP 343)的小變動,讓一個with可以管理多個上下文。使用也很簡單

with (CtxManager() as example):    ...with (    CtxManager1(),    CtxManager2()):    ...with (CtxManager1() as example,      CtxManager2()):    ...with (CtxManager1(),      CtxManager2() as example):    ...with (    CtxManager1() as example1,    CtxManager2() as example2):    ...

比較實用,避免了with下面接with產生不必要縮進的尷尬。值得注意的是,這一條語法變動是新的非LL(1)文法CPython PEG解析器所帶來的副產物。所以PEP 617的標題是New PEG parser for CPython。

PEP 634 結構化模式匹配match-case

直接上結構:

match subject:    case <pattern_1>:        <action_1>    case <pattern_2>:        <action_2>    case <pattern_3>:        <action_3>    case _:        <action_wildcard>

是不是感覺熟悉又臭名昭著的switch-case終於來了?當然還是有區別的:

這個寫法基本還是if-elif-else的語法糖,運行完case就自動break出來。再加上一些看著不錯的模式匹配特性。

def http_error(status):    match status:        case 400:            return "Bad request"        case 401 | 403 | 404:            return "Not allowed"        case 404:            return "Not found"        case 418:            return "I'm a teapot"        case _:            return "Something's wrong with the Internet"

這樣的寫法看著就比if-elif-else看著清爽了許多。針對元組、類、列表也有不錯的支持:

# point is an (x, y) tuplematch point:    case (0, 0):        print("Origin")    case (0, y):        print(f"Y={y}")    case (x, 0):        print(f"X={x}")    case (x, y):        print(f"X={x}, Y={y}")    case _:        raise ValueError("Not a point")

結語

語言的發展是由技術的進步、工程的需求凝結出的結晶,從中透露出的是滿滿的代碼設計哲學。充分了解語法,可以讓開發變得順暢舒適;理解了語法背後的原因與爭議,則可以開拓計算機科學領域的視野。與時俱進,深入了解各種新興技術,才是真正的極客~

推薦閱讀

What's new in Python https://docs.python.org/zh-cn/3.10/whatsnew/index.html

相關焦點

  • python基礎學習教程:Python基礎語法
    教程」關注我們喲!在本章中我們將來學習 Python 的基礎語法,讓你快速學會 Python 編程。第一個 Python 程序交互式編程交互式編程不需要創建腳本文件,是通過 Python 解釋器的交互模式進來編寫代碼。
  • python語法基礎
    學一門語言,基礎語法一定要紮實。很多入門的編程書籍,都會花大量的篇幅來介紹基礎語法,對於毫無編程經驗的新手而言,這樣的書籍無疑是很友好的,但是對於有編程經驗的開發者而言,很多的基礎語法是通用的, 只需花費較少的時間瀏覽下基礎語法,將精力集中在語言獨有的特徵上即可。
  • 【python基礎語法】python基礎語法合集,視頻講解
    python基礎語法合集資源,涵蓋了python語法的各個方面的知識點內容,全程視頻講解,匯集python語法:初級、中級、高級教程資源,關注公眾號
  • Python入門教程小孩兒都能學會的零基礎Python學習教程
    本套python學習路線從零開始,讓你?步步掌握Python開發的各項相關技能,最終達到企業對Python開發、後端開發、爬?開發、數據分析等職位的要求。內容很全面,從python基礎知識到最後的項目開發,每個階段都有配套的學習視頻及相關學習資料,全是乾貨,拒絕做伸手黨,建議收藏後系統的學習。
  • python教程
    python視頻教程     文章底部留言 序號 給您發送視頻教程連結或者加微信 bigzql 索要Python
  • python,語法簡單,容易上手,基本上教程看一遍就能用
    回想下matlab,他們的資料庫都是matlab自帶的,之後學習的時候coding語法也有點熟悉。那麼ai呢?他的基本不是語法上的,是mlinference的經驗,你們寫好的ide能幫助你打到自然語言編程。如果學習的時候就好好學習,以後不僅是你自己開源處理,而且很多公司都會求你分析。
  • Python基本語法V1.5
    不過學習過c/c++、java、php語言的老鳥會有一種感覺,就是python的語法真BT啊~~V1.5版本增加了如下內容的教程:函數參數默認值的使用對象類型屬性和數組類型屬性的坑拋出異常語句的技巧2.
  • 值得收藏的45個Python優質資源(附連結)
    這份清單中包括了各不相同的20個主題,以及一些資深程式設計師分享使用Python的經驗,值得收藏。Mybridge AI 的排名結合了內部機器評估的內容質量和各種人為因素,包括閱讀次數和閱讀時長等。Python列表生成器的教程在這份教程中,你將能夠學習到如何在Python中有效地使用列表生成器來創建列表,替換(嵌套) for循環以及使用 map(), filter(), reduce() 函數等。文章首先簡單回顧了 Python 中列表的基本概念,並與Python中其他的數據結構進行比較。接著講解了列表生成器的學習。
  • 史上最全的 python 基礎知識匯總篇,沒有比這再全面的了,建議收藏
    六十一)秘訣一:基金規模小於1億元不要選爬蟲(六十八)線程池(五十九)港股常見的寬基指數:恒生指數、H股指數和香港中小指數爬蟲(六十九)簡明 jieba 中文分詞教程爬蟲(六十一)網絡編程(五十二)定投的心態,就像還房貸爬蟲(六十)re模塊(五十一)定投的收益爬蟲(五十九)正則表達式語法
  • 書聲琅琅:好的Python入門教程
    好的Python入門教程,書聲琅琅教育番茄老師微信pykf20介紹,python語言現在應用非常廣泛,不管是大數據還是人工智慧,應用最多的語言還是python,因此對於許多小白來講,看到python從業者的高薪資,想要轉行,或者致力於python開發的朋友,如果要學習python,從零基礎開始,一定需要一套完整的學習路線。
  • Python數據分析相關資料整理(博客&視頻連結)
    主要學習內容包括四大部分:Python工作環境及基礎語法知識了解對於Python基礎語法學習部分
  • Python零基礎入門-03-Python基礎語法
    Python零基礎入門-03-Python基礎語法本節課的知識點:1,python系列教程的學習方法。2,熟悉Python的基礎語法內容。1,python系列課程學習方法由於python屬於腳本語言,如果單純的解釋語法沒有什麼實在的意義,所以我python系列的課程都是以視頻講解為主,至於這裡的文章,是給你複習用的。2. 基礎語法python的基礎語法都將以小例子作為驅動來講解。如果你有其他程式語言的基礎,那麼直接看文章就會很快上手。
  • 學python能找到女朋友嗎(python基礎教程)
    本文將會不斷更新更多關於python的信息,敬請收藏本文!python對你來說,這可能還是一個陌生的領域,不過相信隨著逐步深入的了解,你會喜歡上python!首先,讓我們來看一下,python新手應該注意和了解哪些事情吧! 一、python是什麼?
  • python入門教程06-01(python語法入門之字符編碼)
    解釋器執行文件的流程以python test.py為例,執行流程如下#階段1、啟動python解釋器,此時就相當於啟動了一個文本編輯器#階段2、python解釋器相當於文本編輯器,從硬碟上將test.py的內容讀入到內存中#階段3、python解釋器解釋執行剛剛讀入的內存的內容,開始識別python語法2.4 總結python解釋器與文件本編輯的異同如下
  • Python機器學習·微教程
    該教程共分為11小節。在這個教程裡,你將學會:如何處理數據集,並構建精確的預測模型使用Python完成真實的機器學習項目這是一個非常簡潔且實用的教程,希望你能收藏,以備後面複習!接下來進入正題~這個微課程適合誰學習?如果你不符合以下幾點,也沒關係,只要花點額外時間搞清楚知識盲點就能跟上。
  • 一份python書單,值得收藏
    最近,在一些自媒體平臺上面總會看到小白想學習python,卻不知道如何開始的文章。文章評論中,有人說入門難,難在沒有基礎、沒有自信心。也有人說,我英文不好,記不住單詞,這樣情況下如何繼續學習嗎?對於這些狀況,小編也沒有辦法直接告訴大家怎麼辦,其實學習方法有很多,報培訓班系統學習或者買python基礎書籍配合免費視頻學習。
  • Python JSON知識小總結
    本教程我們會下載 Demjson 並安裝:$tar xvfz demjson-1.6.tar.gz$cd demjson-1.6$python setup.py installJSON 函數函數描述encode將 Python 對象編碼成 JSON 字符串decode將已編碼的 JSON 字符串解碼為 Python 對象encode
  • Python系列文章複習總結
    Python系列文章複習總結終於,python文章已經更新完了,這裡做出一下總結複習,相當於是整合出一個目錄以便大家使用。文章的章節梳理在下文中,針對文章的視頻版梳理整理在公眾號左下角找到。主要內容:基礎知識 & 環境搭建。PyCharm的基礎使用。
  • python web學習路線知識點分享!
    教程」關注我們,一起學習成長喲!Python現在非常火,語法簡單而且功能強大,很多同學都想學Python!所以小的給各位看官們準備了高價值Python學習視頻教程及相關電子版書籍,歡迎前來領取!語言,http協議,基礎算法數據結構python: 內置庫,爬蟲庫,web框架,資料庫接口等。
  • Python 從零開始--入門篇
    從這篇文章開始我將分享 python 系列,從 ptyhon 的起始發展,到現在的方方面面, 從最基礎的語法開始,大家一起學習