3 個不可思議的 Python 返回值

優質文章,第一時間送達!

3 个不可思议的 Python 返回值

https://github.com/leisurelicht/wtfpython-cn

第一個:神奇的字典鍵

<code>some_dict = {}
some_dict[5.5] = "Ruby"
some_dict[5.0] = "JavaScript"
some_dict[5] = "Python"/<code>

Output:

<code>>>> some_dict[5.5]
"Ruby"
>>> some_dict[5.0]
"Python"
>>> some_dict[5]
"Python"/<code>

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

說明:

  • Python 字典通過檢查鍵值是否相等和比較哈希值來確定兩個鍵是否相同.

  • 具有相同值的不可變對象在Python中始終具有相同的哈希值.


注意: 具有不同值的對象也可能具有相同的哈希值(哈希衝突).

<code>>>> 5 == 5.0
True
>>> hash(5) == hash(5.0)
True/<code>
  • 當執行 <code>some_dict[5] = "Python"/<code>語句時, 因為Python將<code>5/<code>和<code>5.0/<code>識別為<code>some_dict/<code>的同一個鍵, 所以已有值 "JavaScript" 就被 "Python" 覆蓋了.

  • 這個 StackOverflow的 回答(https://stackoverflow.com/a/32211042/4354153) 漂亮的解釋了這背後的基本原理.

第二個:異常處理中的return

<code>def some_func:
try:
return 'from_try'
finally:
return 'from_finally'/<code>

Output:

<code>>>> some_func
'from_finally'/<code>

說明:

  • 當在 "try...finally" 語句的 <code>try/<code>中執行<code>return/<code>,<code>break/<code>或<code>continue/<code>後,<code>finally/<code>子句依然會執行.

  • 函數的返回值由最後執行的 <code>return/<code>語句決定. 由於<code>finally/<code>子句一定會執行, 所以<code>finally/<code>子句中的<code>return/<code>將始終是最後執行的語句.

第三個:相同對象的判斷

<code>class WTF:
pass/<code>

Output:

<code>>>> WTF == WTF # 兩個不同的對象應該不相等
False
>>> WTF is WTF # 也不相同
False
>>> hash(WTF) == hash(WTF) # 哈希值也應該不同
True
>>> id(WTF) == id(WTF)
True/<code>

說明:

  • 當調用 <code>id/<code>函數時, Python 創建了一個<code>WTF/<code>類的對象並傳給<code>id/<code>函數. 然後<code>id/<code>函數獲取其id值 (也就是內存地址), 然後丟棄該對象. 該對象就被銷燬了.

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

  • 綜上, 對象的id值僅僅在對象的生命週期內唯一. 在對象被銷燬之後, 或被創建之前, 其他對象可以具有相同的id值.

  • 那為什麼 <code>is/<code>操作的結果為<code>False/<code>呢? 讓我們看看這段代碼.

<code>class WTF(object):
def __init__(self): print("I")
def __del__(self): print("D")/<code>

Output:

<code>>>> WTF is WTF
I
I
D
D
False
>>> id(WTF) == id(WTF)
I
D
I
D
True/<code>

正如你所看到的, 對象銷燬的順序是造成所有不同之處的原因.

好文章,我在看❤️


分享到:


相關文章: