<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有什么不為人知的坑?

          共 5094字,需瀏覽 11分鐘

           ·

          2021-05-28 09:51

          Python有什么不為人知的坑?
          TO MY CHILDREN
          一、首先,一些關(guān)于字符串的“基本”操作

          1.


          1. >>> a = "some_string"

          2. >>> id(a)

          3. 140420665652016

          4. >>> id("some" + "_" + "string") # 注意兩個的id值是相同的.

          5. 140420665652016

          2.


          1. >>> a = "wtf"

          2. >>> b = "wtf"

          3. >>> a is b

          4. True

          5. >>> a = "wtf!"

          6. >>> b = "wtf!"

          7. >>> a is b

          8. False

          9. >>> a, b = "wtf!", "wtf!"

          10. >>> a is b

          11. True # 3.7 版本返回結(jié)果為 False.

          3.


          1. >>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'

          2. True

          3. >>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'

          4. False # 3.7 版本返回結(jié)果為 True
          說明:

          這些行為是由于 Cpython 在編譯優(yōu)化時, 某些情況下會嘗試使用已經(jīng)存在的不可變對象而不是每次都創(chuàng)建一個新對象. (這種行為被稱作字符串的駐留[string interning])

          發(fā)生駐留之后, 許多變量可能指向內(nèi)存中的相同字符串對象. (從而節(jié)省內(nèi)存)

          在上面的代碼中, 字符串是隱式駐留的. 何時發(fā)生隱式駐留則取決于具體的實現(xiàn). 這里有一些方法可以用來猜測字符串是否會被駐留:所有長度為 0 和長度為 1 的字符串都被駐留.

          字符串在編譯時被實現(xiàn) ('wtf' 將被駐留, 但是 ''.join(['w', 't', 'f']) 將不會被駐留)

          字符串中只包含字母,數(shù)字或下劃線時將會駐留. 所以 'wtf!' 由于包含 ! 而未被駐留.

          當在同一行將 a 和 b 的值設置為 "wtf!" 的時候, Python 解釋器會創(chuàng)建一個新對象, 然后同時引用第二個變量(譯: 僅適用于3.7以下, 詳細情況請看這里). 如果你在不同的行上進行賦值操作, 它就不會“知道”已經(jīng)有一個 wtf! 對象 (因為 "wtf!" 不是按照上面提到的方式被隱式駐留的). 它是一種編譯器優(yōu)化, 特別適用于交互式環(huán)境.

          常量折疊(constant folding) 是 Python 中的一種窺孔優(yōu)化(peephole optimization)技術(shù). 這意味著在編譯時表達式 'a'*20 會被替換為 'aaaaaaaaaaaaaaaaaaaa' 以減少運行時的時鐘周期. 只有長度小于 20 的字符串才會發(fā)生常量折疊.

          二、關(guān)于函數(shù)的返回值


          1. def some_func():

          2. try:

          3. return 'from_try'

          4. finally:

          5. return 'from_finally'

          輸出:


          1. >>> some_func()

          2. 'from_finally'
          說明:

          當在 "try...finally" 語句的 try 中執(zhí)行 return, break 或 continue 后, finally 子句依然會執(zhí)行.

          函數(shù)的返回值由最后執(zhí)行的 return 語句決定. 由于 finally 子句一定會執(zhí)行, 所以 finally 子句中的 return 將始終是最后執(zhí)行的語句.

          三、關(guān)于類的本質(zhì)


          1. class WTF:

          2. pass

          輸出:


          1. >>> WTF() == WTF() # 兩個不同的對象應該不相等

          2. False

          3. >>> WTF() is WTF() # 也不相同

          4. False

          5. >>> hash(WTF()) == hash(WTF()) # 哈希值也應該不同

          6. True

          7. >>> id(WTF()) == id(WTF())

          8. True
          說明:

          當調(diào)用 id 函數(shù)時, Python 創(chuàng)建了一個 WTF 類的對象并傳給 id 函數(shù). 然后 id 函數(shù)獲取其id值 (也就是內(nèi)存地址), 然后丟棄該對象. 該對象就被銷毀了.

          當我們連續(xù)兩次進行這個操作時, Python會將相同的內(nèi)存地址分配給第二個對象. 因為 (在CPython中) id 函數(shù)使用對象的內(nèi)存地址作為對象的id值, 所以兩個對象的id值是相同的.

          綜上, 對象的id值僅僅在對象的生命周期內(nèi)唯一. 在對象被銷毀之后, 或被創(chuàng)建之前, 其他對象可以具有相同的id值.

          那為什么 is 操作的結(jié)果為 False 呢? 這是由對象銷毀的順序造成的.

          四、你了解Python中的for循環(huán)語句嗎


          1. for i in range(4):

          2. print(i)

          3. i = 10

          輸出:


          1. 0

          2. 1

          3. 2

          4. 3
          說明:

          由于循環(huán)在Python中工作方式, 賦值語句 i = 10 并不會影響迭代循環(huán), 在每次迭代開始之前, 迭代器(這里指 range(4)) 生成的下一個元素就被解包并賦值給目標列表的變量(這里指 i)了.


          五、“is”究竟是什么


          1. >>> a = 256

          2. >>> b = 256

          3. >>> a is b

          4. True

          5. >>> a = 257

          6. >>> b = 257

          7. >>> a is b

          8. False

          9. >>> a = 257; b = 257

          10. >>> a is b

          11. True
          說明:

          is 和 == 的區(qū)別

          is 運算符檢查兩個運算對象是否引用自同一對象 (即, 它檢查兩個運算對象是否相同).

          == 運算符比較兩個運算對象的值是否相等.

          因此 is 代表引用相同, == 代表值相等. 還有一個例子可以用來說明這一點——


          1. >>> [] == []

          2. True

          3. >>> [] is [] # 這兩個空列表位于不同的內(nèi)存地址.

          4. False
          256 是一個已經(jīng)存在的對象, 而 257 不是

          當你啟動Python 的時候, 數(shù)值為 -5 到 256 的對象就已經(jīng)被分配好了. 這些數(shù)字因為經(jīng)常被使用, 所以會被提前準備好.

          Python 通過這種創(chuàng)建小整數(shù)池的方式來避免小整數(shù)頻繁的申請和銷毀內(nèi)存空間.

          六、is not … is not is (not …) 你在說繞口令嗎?


          1. >>> 'something' is not None

          2. True

          3. >>> 'something' is (not None)

          4. False
          說明:

          is not 是個單獨的二元運算符, 與分別使用 is 和 not 不同.

          如果操作符兩側(cè)的變量指向同一個對象, 則 is not 的結(jié)果為 False, 否則結(jié)果為 True.

          七、三個引號


          1. >>> print('wtfpython''')

          2. wtfpython

          3. >>> print("wtfpython""")

          4. wtfpython

          5. >>> # 下面的語句會拋出 `SyntaxError` 異常

          6. >>> # print('''wtfpython')

          7. >>> # print("""wtfpython")
          說明:

          Python 提供隱式的字符串連接, 例如:

          >>> print("wtf" "python")

          wtfpython

          >>> print("wtf" "") # or "wtf"""

          wtf

          ''' 和 """ 在 Python中也是字符串定界符, Python 解釋器在先遇到三個引號的的時候會嘗試再尋找三個終止引號作為定界符, 如果不存在則會導致 SyntaxError 異常.


          八、假作真時真亦假
          TO MY CHILDREN

          1. True = False

          2. if True == False:

          3. print("I've lost faith in truth!")

          輸出:

          I've lost faith in truth!
          說明:

          最初, Python 并沒有 bool 型 (人們用0表示假值, 用非零值比如1作為真值). 后來他們添加了 True, False, 和 bool 型, 但是, 為了向后兼容, 他們沒法把 True 和 False 設置為常量, 只是設置成了內(nèi)置變量.

          Python 3 由于不再需要向后兼容, 終于可以修復這個問題了, 所以這個例子無法在 Python 3.x 中執(zhí)行!


          九、騙過你的眼睛
          TO MY CHILDREN

          1. >>> value = 11

          2. >>> valuе = 32

          3. >>> value

          4. 11
          說明:

          一些非西方字符雖然看起來和英語字母相同, 但會被解釋器識別為不同的字母.


          1. >>> ord('е') # 西里爾語的 'e' (Ye)

          2. 1077

          3. >>> ord('e') # 拉丁語的 'e', 用于英文并使用標準鍵盤輸入

          4. 101

          5. >>> 'е' == 'e'

          6. False

          7. >>> value = 42 # 拉丁語 e

          8. >>> valuе = 23 # 西里爾語 'e', Python 2.x 的解釋器在這會拋出 `SyntaxError` 異常

          9. >>> value

          10. 42
          十、奇怪的加號

          1.


          1. a = [1, 2, 3, 4]

          2. b = a

          3. a = a + [5, 6, 7, 8]

          輸出:


          1. >>> a

          2. [1, 2, 3, 4, 5, 6, 7, 8]

          3. >>> b

          4. [1, 2, 3, 4]

          2.


          1. a = [1, 2, 3, 4]

          2. b = a

          3. a += [5, 6, 7, 8]

          輸出:


          1. >>> a

          2. [1, 2, 3, 4, 5, 6, 7, 8]

          3. >>> b

          4. [1, 2, 3, 4, 5, 6, 7, 8]
          說明:

          a += b 并不總是與 a = a + b 表現(xiàn)相同. 類實現(xiàn) op= 運算符的方式 也許 是不同的, 列表就是這樣做的.

          表達式 a = a + [5,6,7,8] 會生成一個新列表, 并讓 a 引用這個新列表, 同時保持 b 不變.

          表達式 a += [5,6,7,8] 實際上是使用的是 "extend" 函數(shù), 所以 a 和 b 仍然指向已被修改的同一列表.

          十一、最后,再來一條超極機密

          import antigravity

          別問,自己試一試就知道了!

          一鍵,三連


          有一種幸福叫關(guān)注~
          那是肯定的表現(xiàn)~



          瀏覽 43
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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人妻天天摸天天爽天天 | 69av在线 | 日韩a| 999999精品 |