'《What the f*ck Python!》那難以理解和反人類直覺的例子及原理'

"

歡迎各位小哥哥小姐姐閱讀本<小生>的文章,對大家學習有幫助,請點贊加關注哦!!!!!!!!!!

您的點贊和關注將是我持續更新的動力呢.^v^

有不懂的問題可以私聊我哦!

前言

最近,發現了一個在GitHub關於Python的一個非常有趣的項目。

這個項目叫《What the f*ck Python!》,專門介紹 Python 裡面那些奇奇怪怪的語言坑。


這個有趣的項目意在收集 Python 中那些難以理解和反人類直覺的例子以及鮮為人知的功能特性, 並嘗試討論這些現象背後真正的原理!

雖然下面的有些例子並不一定會讓你覺得 WTFs, 但它們依然有可能會告訴你一些你所不知道的 Python 有趣特性. 我覺得這是一種學習編程語言內部原理的好辦法, 而且我相信你也會從中獲得樂趣!


Strings can be tricky sometimes/微妙的字符串

1.

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

2.

>>> a = "wtf"
>>> b = "wtf"
>>> a is b
True
>>> a = "wtf!"
>>> b = "wtf!"
>>> a is b
False
>>> a, b = "wtf!", "wtf!"
>>> a is b
True

3.

>>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
True
>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
False

然後是說明

  1. 這些行為是由於 Cpython 在編譯優化時, 某些情況下會嘗試使用已經存在的不可變對象而不是每次都創建一個新對象. (這種行為被稱作字符串的駐留[string interning])
  2. 發生駐留之後, 許多變量可能指向內存中的相同字符串對象. (從而節省內存)
  3. 在上面的代碼中, 字符串是隱式駐留的. 何時發生隱式駐留則取決於具體的實現. 這裡有一些方法可以用來猜測字符串是否會被駐留:
  • 所有長度為 0 和長度為 1 的字符串都被駐留
  • 字符串在編譯時被實現 ('wtf' 將被駐留, 但是 ''.join(['w', 't', 'f'] 將不會被駐留)
  • 字符串中只包含字母,數字或下劃線時將會駐留. 所以 'wtf!' 由於包含 ! 而未被駐留
"

歡迎各位小哥哥小姐姐閱讀本<小生>的文章,對大家學習有幫助,請點贊加關注哦!!!!!!!!!!

您的點贊和關注將是我持續更新的動力呢.^v^

有不懂的問題可以私聊我哦!

前言

最近,發現了一個在GitHub關於Python的一個非常有趣的項目。

這個項目叫《What the f*ck Python!》,專門介紹 Python 裡面那些奇奇怪怪的語言坑。


這個有趣的項目意在收集 Python 中那些難以理解和反人類直覺的例子以及鮮為人知的功能特性, 並嘗試討論這些現象背後真正的原理!

雖然下面的有些例子並不一定會讓你覺得 WTFs, 但它們依然有可能會告訴你一些你所不知道的 Python 有趣特性. 我覺得這是一種學習編程語言內部原理的好辦法, 而且我相信你也會從中獲得樂趣!


Strings can be tricky sometimes/微妙的字符串

1.

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

2.

>>> a = "wtf"
>>> b = "wtf"
>>> a is b
True
>>> a = "wtf!"
>>> b = "wtf!"
>>> a is b
False
>>> a, b = "wtf!", "wtf!"
>>> a is b
True

3.

>>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
True
>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
False

然後是說明

  1. 這些行為是由於 Cpython 在編譯優化時, 某些情況下會嘗試使用已經存在的不可變對象而不是每次都創建一個新對象. (這種行為被稱作字符串的駐留[string interning])
  2. 發生駐留之後, 許多變量可能指向內存中的相同字符串對象. (從而節省內存)
  3. 在上面的代碼中, 字符串是隱式駐留的. 何時發生隱式駐留則取決於具體的實現. 這裡有一些方法可以用來猜測字符串是否會被駐留:
  • 所有長度為 0 和長度為 1 的字符串都被駐留
  • 字符串在編譯時被實現 ('wtf' 將被駐留, 但是 ''.join(['w', 't', 'f'] 將不會被駐留)
  • 字符串中只包含字母,數字或下劃線時將會駐留. 所以 'wtf!' 由於包含 ! 而未被駐留
《What the f*ck Python!》那難以理解和反人類直覺的例子及原理

  • 當在同一行將 a 和 b 的值設置為 "wtf!" 的時候, Python 解釋器會創建一個新對象, 然後同時引用第二個變量. 如果你在不同的行上進行賦值操作, 它就不會“知道”已經有一個 wtf! 對象 (因為 "wtf!" 不是按照上面提到的方式被隱式駐留的). 它是一種編譯器優化, 特別適用於交互式環境.
  • 常量摺疊(constant folding) 是 Python 中的一種 窺孔優化(peephole optimization) 技術. 這意味著在編譯時表達式 'a'*20會被替換為 'aaaaaaaaaaaaaaaaaaaa' 以減少運行時的時鐘週期. 只有長度小於 20 的字符串才會發生常量摺疊. (為啥? 想象一下由於表達式 'a'*10**10 而生成的 .pyc 文件的大小).

Time for some hash brownies!/是時候來點蛋糕了!

"

歡迎各位小哥哥小姐姐閱讀本<小生>的文章,對大家學習有幫助,請點贊加關注哦!!!!!!!!!!

您的點贊和關注將是我持續更新的動力呢.^v^

有不懂的問題可以私聊我哦!

前言

最近,發現了一個在GitHub關於Python的一個非常有趣的項目。

這個項目叫《What the f*ck Python!》,專門介紹 Python 裡面那些奇奇怪怪的語言坑。


這個有趣的項目意在收集 Python 中那些難以理解和反人類直覺的例子以及鮮為人知的功能特性, 並嘗試討論這些現象背後真正的原理!

雖然下面的有些例子並不一定會讓你覺得 WTFs, 但它們依然有可能會告訴你一些你所不知道的 Python 有趣特性. 我覺得這是一種學習編程語言內部原理的好辦法, 而且我相信你也會從中獲得樂趣!


Strings can be tricky sometimes/微妙的字符串

1.

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

2.

>>> a = "wtf"
>>> b = "wtf"
>>> a is b
True
>>> a = "wtf!"
>>> b = "wtf!"
>>> a is b
False
>>> a, b = "wtf!", "wtf!"
>>> a is b
True

3.

>>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
True
>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
False

然後是說明

  1. 這些行為是由於 Cpython 在編譯優化時, 某些情況下會嘗試使用已經存在的不可變對象而不是每次都創建一個新對象. (這種行為被稱作字符串的駐留[string interning])
  2. 發生駐留之後, 許多變量可能指向內存中的相同字符串對象. (從而節省內存)
  3. 在上面的代碼中, 字符串是隱式駐留的. 何時發生隱式駐留則取決於具體的實現. 這裡有一些方法可以用來猜測字符串是否會被駐留:
  • 所有長度為 0 和長度為 1 的字符串都被駐留
  • 字符串在編譯時被實現 ('wtf' 將被駐留, 但是 ''.join(['w', 't', 'f'] 將不會被駐留)
  • 字符串中只包含字母,數字或下劃線時將會駐留. 所以 'wtf!' 由於包含 ! 而未被駐留
《What the f*ck Python!》那難以理解和反人類直覺的例子及原理

  • 當在同一行將 a 和 b 的值設置為 "wtf!" 的時候, Python 解釋器會創建一個新對象, 然後同時引用第二個變量. 如果你在不同的行上進行賦值操作, 它就不會“知道”已經有一個 wtf! 對象 (因為 "wtf!" 不是按照上面提到的方式被隱式駐留的). 它是一種編譯器優化, 特別適用於交互式環境.
  • 常量摺疊(constant folding) 是 Python 中的一種 窺孔優化(peephole optimization) 技術. 這意味著在編譯時表達式 'a'*20會被替換為 'aaaaaaaaaaaaaaaaaaaa' 以減少運行時的時鐘週期. 只有長度小於 20 的字符串才會發生常量摺疊. (為啥? 想象一下由於表達式 'a'*10**10 而生成的 .pyc 文件的大小).

Time for some hash brownies!/是時候來點蛋糕了!

《What the f*ck Python!》那難以理解和反人類直覺的例子及原理

Output:

"

歡迎各位小哥哥小姐姐閱讀本<小生>的文章,對大家學習有幫助,請點贊加關注哦!!!!!!!!!!

您的點贊和關注將是我持續更新的動力呢.^v^

有不懂的問題可以私聊我哦!

前言

最近,發現了一個在GitHub關於Python的一個非常有趣的項目。

這個項目叫《What the f*ck Python!》,專門介紹 Python 裡面那些奇奇怪怪的語言坑。


這個有趣的項目意在收集 Python 中那些難以理解和反人類直覺的例子以及鮮為人知的功能特性, 並嘗試討論這些現象背後真正的原理!

雖然下面的有些例子並不一定會讓你覺得 WTFs, 但它們依然有可能會告訴你一些你所不知道的 Python 有趣特性. 我覺得這是一種學習編程語言內部原理的好辦法, 而且我相信你也會從中獲得樂趣!


Strings can be tricky sometimes/微妙的字符串

1.

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

2.

>>> a = "wtf"
>>> b = "wtf"
>>> a is b
True
>>> a = "wtf!"
>>> b = "wtf!"
>>> a is b
False
>>> a, b = "wtf!", "wtf!"
>>> a is b
True

3.

>>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
True
>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
False

然後是說明

  1. 這些行為是由於 Cpython 在編譯優化時, 某些情況下會嘗試使用已經存在的不可變對象而不是每次都創建一個新對象. (這種行為被稱作字符串的駐留[string interning])
  2. 發生駐留之後, 許多變量可能指向內存中的相同字符串對象. (從而節省內存)
  3. 在上面的代碼中, 字符串是隱式駐留的. 何時發生隱式駐留則取決於具體的實現. 這裡有一些方法可以用來猜測字符串是否會被駐留:
  • 所有長度為 0 和長度為 1 的字符串都被駐留
  • 字符串在編譯時被實現 ('wtf' 將被駐留, 但是 ''.join(['w', 't', 'f'] 將不會被駐留)
  • 字符串中只包含字母,數字或下劃線時將會駐留. 所以 'wtf!' 由於包含 ! 而未被駐留
《What the f*ck Python!》那難以理解和反人類直覺的例子及原理

  • 當在同一行將 a 和 b 的值設置為 "wtf!" 的時候, Python 解釋器會創建一個新對象, 然後同時引用第二個變量. 如果你在不同的行上進行賦值操作, 它就不會“知道”已經有一個 wtf! 對象 (因為 "wtf!" 不是按照上面提到的方式被隱式駐留的). 它是一種編譯器優化, 特別適用於交互式環境.
  • 常量摺疊(constant folding) 是 Python 中的一種 窺孔優化(peephole optimization) 技術. 這意味著在編譯時表達式 'a'*20會被替換為 'aaaaaaaaaaaaaaaaaaaa' 以減少運行時的時鐘週期. 只有長度小於 20 的字符串才會發生常量摺疊. (為啥? 想象一下由於表達式 'a'*10**10 而生成的 .pyc 文件的大小).

Time for some hash brownies!/是時候來點蛋糕了!

《What the f*ck Python!》那難以理解和反人類直覺的例子及原理

Output:

《What the f*ck Python!》那難以理解和反人類直覺的例子及原理

"Python" 消除了 "JavaScript" 的存在?

說明:

  • Python 字典通過檢查鍵值是否相等和比較哈希值來確定兩個鍵是否相同.
  • 具有相同值的不可變對象在Python中始終具有相同的哈希值.
>>> 5 == 5.0
True
>>> hash(5) == hash(5.0)
True
  • 注意: 具有不同值的對象也可能具有相同的哈希值(哈希衝突).
  • 當執行 some_dict[5] = "Python" 語句時, 因為Python將 5 和 5.0 識別為 some_dict 的同一個鍵, 所以已有值 "JavaScript" 就被 "Python" 覆蓋了.

這個 StackOverflow的 回答 漂亮的解釋了這背後的基本原理.

參考ref:https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects

最後多說一句,小編是一名python開發工程師,這裡有我自己整理了一套最新的python系統學習教程,包括從基礎的python腳本到web開發、爬蟲、數據分析、數據可視化、機器學習等。想要這些資料的可以關注小編,並在後臺私信小編:“01”即可領取。

"

相關推薦

推薦中...