<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你在享受十一長假時,Python 已悄悄地變了

          共 4586字,需瀏覽 10分鐘

           ·

          2020-10-13 07:41

          文 |?太陽雪

          來源:Python 技術(shù)「ID: pythonall」


          Python 3.9 在經(jīng)歷了將近一年的試用期后,于 10月5日(2020年)發(fā)布了穩(wěn)定版,意味著,在下一版本發(fā)布之前,不會在做改動,童鞋們可以放心大膽地更新了。享受完愜意的十一長假后,我們快來看看新版本帶來了哪些驚喜

          先附上一個 16 歲印度小哥哥整理的特性圖:

          節(jié)能篇

          這次版本最喜人的特性事節(jié)能,不僅節(jié)省電能,更重要的是節(jié)省了敲代碼的次數(shù),以及我們寶貴的時間

          字典的合并與更新

          毫無疑問,字典對象(Dict)是日常編程中最常用到的數(shù)據(jù)結(jié)構(gòu),從存儲鍵值對到支持復(fù)雜算法,都依賴于字典對象,而且常用一些字段的合并、更新等操作,雖然 Python 中已經(jīng)提供了字段更新的方法和字典展開操作符( ** ),但是仍然不夠簡潔,我理解,在你看到新版本中的更新之前,不會感覺有什么不簡潔的

          原來的合并:

          d1?=?{'a':?'A',?'b':?'B',?'c':?'C'}
          d2?=?{'d':?'D',?'e':?'E'}

          d3?=?{**d1,?**d2}??#?使用展開操作符,將合并結(jié)果存入?d3
          print(d3)??#?{'a':?'A',?'b':?'B',?'c':?'C',?'d':?'D',?'e':?'E'}

          d1.update(d2)??#?update?方法,將?d1?d2?合并,且更新?d1
          print(d1)??#?{'a':?'A',?'b':?'B',?'c':?'C',?'d':?'D',?'e':?'E'}

          現(xiàn)在的合并:

          d1?=?{'a':?'A',?'b':?'B',?'c':?'C'}
          d2?=?{'d':?'D',?'e':?'E'}

          d3?=?d1?|?d2??#?效果等同于展開操作符
          print(d3)??#?{'a':?'A',?'b':?'B',?'c':?'C',?'d':?'D',?'e':?'E'}

          d1?|=?d2??#?等同于?update
          print(d1)??#?{'a':?'A',?'b':?'B',?'c':?'C',?'d':?'D',?'e':?'E'}
          • | 操作符,除了對數(shù)值的 操作之外,現(xiàn)在還可以做字典對象的合并
          • |= 如果要用合并的結(jié)果更新前面的字典對象,在合并操作符后加賦值號就行

          是不是簡潔多了,不僅簡潔了,而且更容易理解了

          這還沒完,合并賦值操作符(|=)除了字典之間的合并,還可以合并類字典對象

          先看一段代碼:

          d1?=?{'a':?'A',?'b':?'B',?'c':?'C'}

          l1?=?[('d',?'D'),?('e',?'E')]

          d1?|=?l1

          print(d1)??#?{'a':?'A',?'b':?'B',?'c':?'C',?'d':?'D',?'e':?'E'}
          • l1 是一個列表對象,其中的元素是二維元組
          • 這里的特別之處在于二維元組對象,合并時,第一個元素被看成字典的 Key,第二個被看成字典的 Value,如果不是這樣,則會報錯

          如果遇到這種特殊的場景,合并運算簡直太方便了,你能想到有哪些類似場景嗎?歡迎留言

          拓撲排序

          首先需要理解什么是拓撲圖,簡單來說就是一定空間內(nèi)若干個點之間的關(guān)系,例如對于一項工作來說,包含有若干個任務(wù),任務(wù)之間有相互依賴的關(guān)系,任務(wù)加上它們之間的關(guān)系,就構(gòu)成了一個拓撲結(jié)構(gòu)圖

          拓撲排序,就是對一個拓撲圖中的點按照點之間的相互關(guān)系的一種排序

          例如這樣一個拓撲圖

          拓撲圖示例

          拓撲排序為

          1、2、3、4、5

          如果用算法生寫的話,需要十行以上,而且還不包括調(diào)試時間,以及為各種適應(yīng)性做的改善所花的時間

          現(xiàn)在,排序只需要一行代碼:

          from?graphlib?import?TopologicalSorter

          tg?=?{5:?{3,?4},?4:?{2,?3},?3:?{2,?1},?2:?{1}}
          ts?=?TopologicalSorter(tg)

          print(list(ts.static_order()))?#?[1,?2,?3,?4,?5]
          • 首先從 graphlib 中引入拓撲排序組件 TopologicalSorter
          • 然后定義一個拓撲結(jié)構(gòu)圖,這里是用字典加集合的方式定義的,表示節(jié)點的前序節(jié)點是哪些
          • 接著用排序組件對拓撲結(jié)構(gòu)進行排序,即創(chuàng)建一個排序?qū)ο?/section>
          • 最好調(diào)用排序?qū)ο蟮?static_order 方法展示排序結(jié)果

          實際上最核心的就是創(chuàng)建排序?qū)ο蟮拇a,新特性提供了優(yōu)雅的封裝

          說到封裝,你可能猜到他的功能并不單一,確實,排序組件 TopologicalSorter 不僅能對以及定義的結(jié)果排序,還可以對動態(tài)結(jié)構(gòu)排序,例如

          from?graphlib?import?TopologicalSorter

          ts?=?TopologicalSorter()
          ts.add(5,?3,?4)
          ts.add(4,?2,?3)
          ts.add(3,?2,?1)
          ts.add(2,?1)

          print(list(ts.static_order()))?#?[1,?2,?3,?4,?5]

          也就是說,可以逐步的將依賴添加進去,在迭代處理的情況下很方便,

          需要注意的是 static_order 方法只能掉用一次,再次排序的話,需要重新創(chuàng)建 TopologicalSorter 對象

          另外,如果拓撲圖結(jié)構(gòu)是個循環(huán)的,排序會報 CycleError 循環(huán)依賴錯誤

          隨機字節(jié)碼

          之前要產(chǎn)生隨機字節(jié)碼,需要先產(chǎn)生隨機數(shù),然后從定義的字符序列中獲取對應(yīng)位置的字符,最好再轉(zhuǎn)換為字節(jié),是挺麻煩的,現(xiàn)在,一行代碼搞定

          import?random

          print(random.randbytes(10))??#?b'\x0fzf\x17K\x00\xfb\x11LF'??隨機的,每次結(jié)果可能不同

          最小公倍數(shù)

          之前的 Python 版本中已經(jīng)實現(xiàn)了最大公約數(shù)的計算,雖然可以用最大公約數(shù)求得最小公倍數(shù),不過需要寫多行代碼(實際上我不記得怎么推送了)

          現(xiàn)在,一行代碼搞定:

          import?math
          math.lcm(49,?14)??#?98

          是不是方便多了,不信的話,和下面生算對比下:

          def?lcm(num1,?num2):
          ??if?num1?==?num2?==?0:
          ????return?0
          ??return?num1?*?num2?//?math.gcd(num1,?num2)

          lcm(49,?14)??#?98

          功能篇

          功能方面,Python 3.9 也做出了很多改善,下面來了解下

          字符串去前綴后綴

          本來字符串在 Python 中的操作已經(jīng)夠強大了,很難想到它會把去前后綴的功能作為更新,先看看效果吧


          "three?cool?features?in?Python".removesuffix("?Python")
          #?three?cool?features?in

          "three?cool?features?in?Python".removeprefix("three?")
          #?cool?features?in?Python

          "three?cool?features?in?Python".removeprefix("Something?else")
          #?three?cool?features?in?Python

          很簡單,很容易想到用其他方式實現(xiàn),代碼也不會多,例如用 字符串的 strip 方法:

          "three?cool?features?in?Python".strip("?Python")
          #?ree?cool?features?i

          很明顯,最終的效果并不是我們想要的,strip 會將前后遇到的字符模式一并修剪!

          如果用其他方式,比如字符串查找,正則匹配等,也能實現(xiàn),不過沒有現(xiàn)成的方法方便,更重要的是,這個特性避免了自己不小心的犯錯

          時區(qū)支持

          對我們中國來說,時區(qū)問題不大,特別是只做在國內(nèi)使用的應(yīng)用的話,但是如果在每個,或者其他地方,時區(qū)會是個問題,之前,可以通過將時間轉(zhuǎn)換為 UTC 格式再轉(zhuǎn)為其他時區(qū)的時間,現(xiàn)在可以方便的用 zoneinfo 模塊實現(xiàn)了

          zoneinfo 模塊為標(biāo)準(zhǔn)庫引入了 IANA 時區(qū)數(shù)據(jù)庫

          from?zoneinfo?import?ZoneInfo
          from?datetime?import?datetime

          dt?=?datetime(2020,?10,?1,?1,?tzinfo=?ZoneInfo("America/Los_Angeles"))

          如代碼所示,可以為本地時間設(shè)置時區(qū),將時間轉(zhuǎn)化為指定時區(qū)的時間

          注意:使用 ZoneInfo 獲取時區(qū)屬性之前,需要安裝 tzdata 模塊

          其他

          數(shù)據(jù)類型提示

          Python 本身是弱類型語言,但在一些大型項目中容易因為數(shù)據(jù)類型引入 bug,為了改善這一點,對聲明了數(shù)據(jù)類型的形參,如果實參與形參類型不符,執(zhí)行時會得到警告提醒,例如

          def?fun(input:?str):
          ??print(str)

          fun(10)??#?此時會得到數(shù)據(jù)類型不匹配的警告

          更強悍的解析器

          Python 3.9 重構(gòu)了解析器,雖然在日常編程中幾乎感覺不到,但這個更新確是最重要的,就行如果你感覺如履平地,必然有人在默默付出一樣

          Python 之前一直使用 LL(1) 解析器將源代碼解析為解析樹,類似于一次讀取一個字符,并解釋源代碼而無需回溯的解析器。

          新解釋器是基于 PEG(parsing expression grammar) 實現(xiàn)的,既高效,又靈活,不過需要使用更多的內(nèi)存

          import()特性修改

          __import__() 在之前的版本中,可能引發(fā) ValueError 異常,按官方解釋:ValueError 曾經(jīng)會在相對導(dǎo)入超出其最高層級包時發(fā)生 (不知所云),在新的版本中,異常時會拋出 ImportError,這樣更加合理

          反正我沒遇到過,可能是沒有用過這種高級用法,就當(dāng)是學(xué)習(xí)了

          總結(jié)

          “人生苦短,用我 Python” —— Python 不但這么說,也這么做,當(dāng)我們享受愜意的雙節(jié)長假時,Python 默默的優(yōu)化自己,只能讓我們苦短的人生,更加精彩

          還等什么,趕緊升級到 Python3.9 試試吧

          參考

          • https://zhuanlan.zhihu.com/p/262914368
          • https://developer.51cto.com/art/202010/627903.htm
          • https://blog.csdn.net/qq_42554007/article/details/107075651
          • https://www.sohu.com/a/422827870_114760
          • https://docs.python.org/zh-cn/3/whatsnew/3.9.html

          PS公號內(nèi)回復(fù)「Python」即可進入Python 新手學(xué)習(xí)交流群,一起 100 天計劃!


          老規(guī)矩,兄弟們還記得么,右下角的 “在看” 點一下,如果感覺文章內(nèi)容不錯的話,記得分享朋友圈讓更多的人知道!

          代碼獲取方式

          識別文末二維碼,回復(fù):201012

          瀏覽 44
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精彩视频免费观看 | 日本欧美一区不卡少妇 | 天天操天天射天天色 | 亚洲丁香网| 中国一级黄片免费视频 |