<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 特性(讀書(shū)筆記)

          共 2739字,需瀏覽 6分鐘

           ·

          2020-10-23 14:36


          點(diǎn)擊上方“Python學(xué)習(xí)開(kāi)發(fā)”,選擇“加為星標(biāo)

          第一時(shí)間關(guān)注Python技術(shù)干貨!

          1.斷言

          Python 的斷言語(yǔ)句是一種調(diào)試輔助功能,不是用來(lái)處理運(yùn)行時(shí)錯(cuò)誤的機(jī)制。

          assert 在條件為 False 的時(shí)候觸發(fā),后面的內(nèi)容是報(bào)錯(cuò)信息。

          import?sys

          assert?sys.version_info?>=?(3,?7),?"請(qǐng)?jiān)赑ython3.7及以上環(huán)境執(zhí)行"

          如果這個(gè)項(xiàng)目要求最低是 Python3.7 的環(huán)境,那么如果使用 Python3.6 來(lái)運(yùn)行這個(gè)項(xiàng)目,就會(huì)出現(xiàn)這個(gè)錯(cuò)誤信息。

          Traceback?(most?recent?call?last):
          ??File?"/Users/chennan/pythonproject/demo/nyandemo.py",?line?3,?in?<module>
          ????assert?sys.version_info?>?(3,?7),?"請(qǐng)?jiān)赑ython3.7以上環(huán)境執(zhí)行"
          AssertionError:?請(qǐng)?jiān)赑ython3.7以上環(huán)境執(zhí)行

          提前中止項(xiàng)目

          2.巧妙的放置逗號(hào)

          合理的格式化列表里面的元素,更容易維護(hù)

          一般我們?cè)趯?xiě)列表的時(shí)候會(huì)這樣

          l?=?["apple",?"banana",?"orange"]

          使用下面的方式可以更加清晰的區(qū)分每一個(gè)項(xiàng)目,習(xí)慣性的在末尾加個(gè)逗號(hào),防止下次添加元素遺漏了逗號(hào),看著也更 Pythonic

          l?=?[
          ????"apple",?
          ????"banana",?
          ????"orange",
          ]

          3.下劃線(xiàn)、雙下劃線(xiàn)以及其他

          前置單下劃線(xiàn) : _var

          1.是一種約定,前置單下劃線(xiàn)的方法和變量只在內(nèi)部使用

          2.在使用通配符導(dǎo)包的使用 from xx import * 這種,不用導(dǎo)入前置單下劃線(xiàn)的變量,除非定義了 __all__ 覆蓋了這個(gè)行為。PEP8 一般不建議通過(guò)這種方式導(dǎo)包。

          后置單下劃線(xiàn): ?var_

          如果使用的變量名被 Python 中的關(guān)鍵字占用,比如要聲明 class 這個(gè)變量,我們這時(shí)候可以在其后面加個(gè)單下劃線(xiàn) class_

          這個(gè)也是 PEP8 里約定的

          前置雙下劃線(xiàn): __var

          ?????前置雙下劃線(xiàn)會(huì)讓 Python 解釋器重寫(xiě)屬性名稱(chēng),防止被子類(lèi)中的命名覆蓋。
          class?Test:
          ????def?__init__(self):
          ????????self.foo?=?11
          ????????self.__bar?=?2


          t?=?Test()
          print(dir(t))

          查看類(lèi)的屬性可以發(fā)現(xiàn) self.__bar 變?yōu)榱?_Test__bar,這也稱(chēng)之為名稱(chēng)改寫(xiě) (name mangling),解釋器會(huì)更改變量的名稱(chēng),防止拓展這個(gè)類(lèi)型時(shí)命名沖突。

          ['_Test__bar',?'__class__',?'__delattr__',?'__dict__',?'__dir__',?'__doc__',?'__eq__',?'__format__',?'__ge__',?'__getattribute__',?'__gt__',?'__hash__',?'__init__',?'__init_subclass__',?'__le__',?'__lt__',?'__module__',?'__ne__',?'__new__',?'__reduce__',?'__reduce_ex__',?'__repr__',?'__setattr__',?'__sizeof__',?'__str__',?'__subclasshook__',?'__weakref__',?'foo']

          這個(gè)時(shí)候如果想訪(fǎng)問(wèn) __bar, 怎么辦呢,我們可以通過(guò) t._Test__bar進(jìn)行訪(fǎng)問(wèn)。

          如果我們繼承一下Test然后重寫(xiě) __bar會(huì)咋樣呢

          class?ExtendTest(Test):
          ????def?__init__(self):
          ????????super().__init__()
          ????????self.foo?=?"overridden"
          ????????self.__bar?=?"overridden"


          et?=?ExtendTest()
          print(et.foo)
          print(et.__bar)

          發(fā)現(xiàn)出現(xiàn)了錯(cuò)誤

          AttributeError: 'ExtendTest' object has no attribute '__bar'

          原因就是前面的一樣,因?yàn)榻忉屍靼?__bar的名字給改了防止父類(lèi)的這個(gè)變量被改寫(xiě)了。

          我們可以分別訪(fǎng)問(wèn)這兩個(gè)類(lèi)的 __bar發(fā)現(xiàn)他們是同時(shí)存在的,確實(shí)沒(méi)有被覆蓋。

          print(et._Test__bar)
          print(et._ExtendTest__bar)

          得到結(jié)果

          2
          overridden

          順便說(shuō)下 __bar 在英語(yǔ)中一般都是叫做 dunderbar

          除了雙下劃線(xiàn)的變量,雙下劃線(xiàn)的方法名也可以被解釋器名稱(chēng)改寫(xiě)。

          class?ManglingMethod:
          ????def?__mangled(self):
          ????????return?42

          ????def?call_it(self):
          ????????return?self.__mangled()

          md?=?ManglingMethod()
          md.call_it()
          md.__mangled()

          運(yùn)行之后得到出錯(cuò)信息

          AttributeError:?'ManglingMethod'?object?has?no?attribute?'__mangled'

          前后雙下劃線(xiàn): __var__

          所謂的魔法方法,它的名稱(chēng)不會(huì)被解釋器所改變,但是就命名約定而言最好避免使用這種形式變量和方法名

          單下劃線(xiàn): _

          1._ 可以表示變量是臨時(shí)的或者是無(wú)關(guān)緊要的

          for?_?in?rang(5):
          ????print("hello")

          2.在數(shù)字之前使用還可以當(dāng)作是千位分隔符

          for?i?in?range(1000_000):
          ????print(i)

          3.在解包元組的時(shí)候可以當(dāng)作是占位符。

          car?=?("red",?"auto",?12,?332.4?)
          color,_,_,mileage?=?car
          print(color)
          print(_mileage)

          4.如果使用命令行模式的話(huà),_ 可以獲取先前計(jì)算的結(jié)果

          >>>??20+5
          25
          >>>?_
          25
          >>>?print(_)
          25

          4.自定義異常類(lèi)

          我們有以下代碼

          def?validate(name):
          ????if?len(name)?10:
          ????????raise?ValueError

          如果在其他文件中調(diào)用這個(gè)方法,

          validate("lisa")

          在不理解這個(gè)方法的作用的時(shí)候,如果名字驗(yàn)證失敗時(shí),調(diào)用棧會(huì)打印出以下信息

          Traceback?(most?recent?call?last):
          ??File?"/Users/chennan/pythonproject/demo/nyandemo.py",?line?57,?in?<module>
          ????validate("lisa")
          ??File?"/Users/chennan/pythonproject/demo/nyandemo.py",?line?55,?in?validate
          ????raise?ValueError
          ValueError

          這個(gè)棧調(diào)試回溯中的信息指出了,出現(xiàn)了錯(cuò)誤的值,但是并不知道為什么出錯(cuò)了,所以這個(gè)時(shí)候就需要跟進(jìn)這個(gè) validate 一探究竟,

          這個(gè)時(shí)候我們就可以自己定義一個(gè)異常類(lèi)

          class?NameTooShortException(ValueError):
          ???def?__str__(self):
          ???????return?"輸入的名字長(zhǎng)度必須大于等于10"



          def?validate(name):
          ????if?len(name)?10:
          ????????raise?NameTooShortException(name)

          validate("lisa")

          這樣如果再出現(xiàn)錯(cuò)誤,就可以知道為什么錯(cuò)了,同時(shí)調(diào)用法也方便捕獲指定的異常,不用再使用 ValueError。

          try:
          ????validate("lisa")
          except?NameTooShortException?as?e:
          ????print(e)

          5.Python字節(jié)碼

          Cpython 解釋器執(zhí)行時(shí),首先將其翻譯成一系列的字節(jié)碼指令。字節(jié)碼是 Python 虛擬機(jī)的中間語(yǔ)言,可以提高程序的執(zhí)行效率

          Cpython 不直接執(zhí)行人類(lèi)可讀的源碼,而是執(zhí)行由編譯器解析和語(yǔ)法語(yǔ)義分析產(chǎn)生的緊湊的數(shù)、變量和引用。

          這樣,再次執(zhí)行相同程序時(shí)能節(jié)省時(shí)間和內(nèi)存。因?yàn)榫幾g步驟產(chǎn)生的字節(jié)碼會(huì)以 .pyc.pyo 文件的形式緩存在硬盤(pán)上,所以執(zhí)行字節(jié)碼比再次執(zhí)行相同的Python文件速度更快。

          def?greet(name):
          ????return?'hello,?'?+?name?+?'!'


          #__code__可以獲取greet函數(shù)用到的虛擬機(jī)指令,常量和變量
          gc?=?greet.__code__
          print(gc.co_code)??#?指令流

          print(gc.co_consts)??#?常量

          print(gc.co_varnames)??#?傳過(guò)來(lái)的參數(shù)
          dis.dis(greet)

          結(jié)果

          b'd\x01|\x00\x17\x00d\x02\x17\x00S\x00'
          (None,?'hello,?',?'!')
          ('name',)
          ?70???????????0?LOAD_CONST???????????????1?('hello,?')
          ??????????????2?LOAD_FAST????????????????0?(name)
          ??????????????4?BINARY_ADD
          ??????????????6?LOAD_CONST???????????????2?('!')
          ??????????????8?BINARY_ADD
          ?????????????10?RETURN_VALUE

          解釋器在索引1處('hello, ')查找常量,并放入棧中,然后將 name 的變量?jī)?nèi)容放入棧
          Cpython 虛擬機(jī)是基于棧式虛擬機(jī),棧就是虛擬機(jī)的內(nèi)部數(shù)據(jù)結(jié)構(gòu)。
          棧只支持兩種動(dòng)作:入棧和出棧
          入棧:將一個(gè)值添加到棧頂
          出棧:刪除并返回棧頂?shù)闹怠?/p>

          假設(shè)棧初始為空,在執(zhí)行前兩個(gè)操作碼(opcode)之后,虛擬的內(nèi)容(0是最上面的元素)
          比如我們傳入的name為lisa.

          0:?'lisa'
          1:?'hello,?'

          BINARY_ADD 指令從棧中彈出兩個(gè)字符串值,并將他們連接起來(lái)
          然后再次將結(jié)果壓入棧中。

          0:'hello,?lisa'

          然后由下一個(gè) LOAD_CONST 將'!'壓入棧。
          此時(shí)的結(jié)果

          0:'!'
          1:'hello,?lisa'

          下一個(gè) BINARY_ADD 操作碼再次將這兩個(gè)字符串從棧中彈出并連接之后壓入棧,生成最終結(jié)果

          0:'hello,?lisa!'

          最后字節(jié)碼 RETURN_VALUE ,告訴虛擬機(jī)當(dāng)前位于棧頂?shù)氖窃摵瘮?shù)的返回值。

          推薦閱讀


          Python 雜記

          python優(yōu)化和技巧

          Python反編譯之字節(jié)碼

          瀏覽 75
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  色色97| 美日韩一级黄色片中文字幕 | 黄色天堂 | 欧美三级片视频 | 欧美操逼免费观看 |