從踩坑學 Python 內部原理(14):​消失的外部變量

2021-03-02 Python開發者

(給Python開發者加星標,提升Python技能)

英文:Satwik Kansal,翻譯:暮晨

Python開發者整理自 GitHub

【導讀】:Python 是一個設計優美的解釋型高級語言,它提供了很多能讓程式設計師感到舒適的功能特性。但有的時候 Python 的一些輸出結果對於初學者來說似乎並不是那麼一目了然。

GitHub 有個倉庫收集 Python 中那些難以理解和鮮為人知的功能特性,並嘗試討論這些現象背後真正的原理!

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

如果你是一位經驗比較豐富的 Python 程式設計師,你可以嘗試挑戰看是否能一次就找到例子的正確答案。你可能對其中的一些例子已經比較熟悉了,那這也許能喚起你當年踩這些坑時的甜蜜回憶。

示例程序基於Python3.5.2。

消失的外部變量
e = 7
try:
    raise Exception()
except Exception as e:
    pass

Output (Python 2.x):

>>> print(e)
# prints nothing

Output (Python 3.x):

>>> print(e)
NameError: name 'e' is not defined

說明:

出處: https://docs.python.org/3/reference/compound_stmts.html#except

當使用 as 為目標分配異常的時候, 將在except子句的末尾清除該異常.

這就好像

except E as N:
    foo

會被翻譯成

except E as N:
    try:
        foo
    finally:
        del N

這意味著異常必須在被賦值給其他變量才能在 except 子句之後引用它. 而異常之所以會被清除, 則是由於上面附加的回溯信息(trackback)會和棧幀(stack frame)形成循環引用, 使得該棧幀中的所有本地變量在下一次垃圾回收發生之前都處於活動狀態.(譯: 也就是說不會被回收)

子句在 Python 中並沒有獨立的作用域. 示例中的所有內容都處於同一作用域內, 所以變量 e 會由於執行了 except 子句而被刪除. 而對於有獨立的內部作用域的函數來說情況就不一樣了. 下面的例子說明了這一點:

def f(x):
    del(x)
    print(x)

x = 5
y = [5, 4, 3]

Output:

>>>f(x)
UnboundLocalError: local variable 'x' referenced before assignment
>>>f(y)
UnboundLocalError: local variable 'x' referenced before assignment
>>> x
5
>>> y
[5, 4, 3]

在 Python 2.x 中, Exception() 實例被賦值給了變量 e, 所以當你嘗試列印結果的時候, 它的輸出為空.(譯: 正常的Exception實例列印出來就是空)

Output (Python 2.x):

>>> e
Exception()
>>> print e
# 沒有列印任何內容!

- EOF -

覺得本文對你有幫助?請分享給更多人

推薦關注「Python開發者」,提升Python技能

點讚和在看就是最大的支持❤️

相關焦點

  • 從踩坑學Python內部原理(8):is not 與逗號
    GitHub 有個倉庫收集 Python 中那些難以理解和鮮為人知的功能特性,並嘗試討論這些現象背後真正的原理!雖然有些例子並不一定會讓你覺得「臥槽」(WTF),但它們依然有可能會告訴你一些你所不知道的 Python 有趣特性。
  • 從踩坑學Python內部原理(4):for 循環怎麼會事兒?
    GitHub 有個倉庫收集 Python 中那些難以理解和鮮為人知的功能特性,並嘗試討論這些現象背後真正的原理!雖然有些例子並不一定會讓你覺得「臥槽」(WTF),但它們依然有可能會告訴你一些你所不知道的 Python 有趣特性。
  • Python基礎篇-13 Python不是內部或外部命令的解決方法
    還有很多不知道學Python能幹什麼?在這裡我會為大家一一分享,我感覺還是很有意思的。雖然對於那些會的人不難,但是對於小白來說這確實是很好的一種學習思路。第一章 Python編程基礎----Python不是內部或外部命令的解決方法安裝 Python 環境沒有問題的讀者,可直接跳過本節,繼續閱讀後續文章。
  • python進階教程之變量
    >print("over")```局部變量的生命周期3.2 全局變量```python定義一個全局變量num = 10def demo1():print(num)def demo2():print(num)demo1() demo2()
  • Python變量作用域及global,nonlocal詳解
    作用域的分類python中的作用域分4種情況:L:local,局部作用域,即函數中定義的變量;E:enclosing,嵌套的父級函數的局部作用域,即包含此函數的上級函數的局部作用域,但不是全局的;G:global,全局變量,就是模塊級別定義的變量;B:built-in,系統固定模塊裡面的變量,比如int
  • 詳解python 局部變量與全局變量
    一旦本文將詳細分析python的全局變量與局部變量,學過php的人都知道,php裡面的全局變量是無法在function裡面去使用的,只有超全局變量才可以
  • Python教程基礎語法、變量基本使用和算術運算符
    python 變量名 = 值變量定義之後,後續就可以直接使用了1) 變量演練1 —— iPython```python定義 qq_number 的變量用來保存 qq 號碼python In [1]: type(name)2.3 不同類型變量之間的計算1) 數字型變量 之間可以直接計算· 在 Python 中,兩個數字型變量是可以直接進行 算數運算的· 如果變量是 bool
  • Python函數詳解一(函數參數、變量作用域)
    Python函數函數是python程序的重要組成部分。所謂函數就是實現某一特定功能的代碼段,可重複使用,提高了代碼的利用率。
  • Python函數中的全局變量與局部變量
    def first():    # 這個變量是函數內部定義的變量,屬於局部變量,只能在函數中使用    c = "Hello"    # 大括號{} 是format()函數的用法,格式化    print("c = {}".format(c))    # 如果局部變量定義的名稱與全局變量相同,相當於是在函數中又定義了一個新的局部變量
  • 利用全局及外部變量實現C51無能數化調用A51函數
    本文引用地址:http://www.eepw.com.cn/article/171925.htm1 C51無參數化調用A51函數的實現原理為了說明其原理,必須理解局部變量、全局變量和外部變量的意義。局部變量:是在函數內部定義的變量,只在定義它的函數內部有效,僅在使用它時,才為它分配內存單元。全局變量:又稱外部變量,是在函數外部定義的變量,可以為多個函數共同使用,其有效作用範圍是從它定義的位置開始直到整個程序文件結束。
  • Python專題 | (三)注釋、變量與輸出
    講完了注釋,我們來看這個程序的第一句(Mark把注釋去掉啦)通過注釋,這句話的意思是用一個變量存儲字符串「hello world」。那麼,什麼是字符串?什麼又是變量?這裡提到的字符串,是編程中數據類型的一種。在python中,數據被分為很多的類型。
  • 深入理解 Python 內部函數和閉包(進階)
    >閉包 clsure學過 JavaScript 的非小白同學可能會對這個概念很熟悉內部函數還有一個很重要的特性:可以訪問它所屬的外部函數的局部變量,這些變量被稱為 nonlocal,或者enclosing 變量可以攜帶這些 nonlocal 變量,讓它們不會被回收
  • 我要悄悄學Python之變量與數據類型
    python world在上面的代碼中,我們添加了一個名為message的變量。每個變量都關聯一個值——與該變量相關聯的信息。在這裡,message指向值為"Hello python world"的文本。Python允許隨時修改變量的值,且始終保持記錄最新的結果。
  • 菜鳥學Python雜談1: 3分鐘學Python變量和數據類型
    大體就這幾個方面,萬丈高樓平地起,我們先從最簡單的變量和數據入手.一:Python的變量類型非常簡單:主要分下面幾類:1.numbers:分整數int和浮點數float整數:比如1,200,-1000,0,也有用十六進位表示的比如0xff00等浮點數:比如1.11,12,13,-10.02,也有比較大的浮點數比如2.12x10^92.String :單引號,雙引號和三引號python
  • 二、Python基礎數據類型、變量、常量
    二、Python基礎數據類型、變量、常量1.變量:把程序運行的中間結果臨時的存在內存中,以便後續的代碼調用變量不僅可以是數組,還可以是任意數據類型。在程序中,變量就是用一個變量名表示,變量名必須是大小寫英文、數字、和『_』下劃線組合,並且不能以數字開頭。
  • 年終總結:這一年踩過的坑
    有句古老的諺語:沒有踩過坑的產品經理不是好的產品經理。因此,工作之外,我專注的只有一件事:踩坑。踩坑,是項技術活。有的人踩坑,踩的七歪八扭,深淺不一。這種踩最後就只剩下坑。我呢,稍微踩的好點,踩的坑都圍繞著同一個基點:教育行業的產品經理。這個詞可以分成兩截理解:教育行業、產品經理。
  • 解讀Python變量的作用域
    變量作用域是指我們在程序中命名的變量在多大範圍能夠訪問到它。在函數內部聲明的變量,在函數外部是否能夠訪問?在模塊中聲明的變量,在函數內部是否能夠訪問?這些都是變量作用域要解決的問題。下面是一段有關變量作用域範圍的代碼。上面的代碼是求圓的面積。
  • Python語言基本語法元素之變量,變量的含義及命名規則
    筆者希望給python初學者提供幫助。上一篇文章寫了相應地,我們可以改變rate變量的值,寫入下列代碼即可。rate = 1.6274變量是一個容器,rate變量就是一個存放匯率數值的容器。如上就是一個賦值語句,將rate變量存放的數值更改為1.6274。
  • Python變量命名需要注意的事項
    我們剛開始學習或者使用python的時候,接觸最多的還是變量,所以,有必要再深入了解一些,但是,還沒有必要全面了解,因為即使你現在看了所有的命名規則
  • Windows上安裝Tensorflow踩的坑
    但失敗的嘗試也不能白失敗了,拿出來曬曬說不定有高人指點呢,特此把踩過的坑述說一二,一來是尋求幫助,二來也是警惕來者,「此處有坑,請小心繞道」吧。sess$run(hello)踩過的一號坑——tensorflow在windows上的安裝    在之前的文章中,曾經通過Docker的方法,實現了在windows上安裝tensorflow,感興趣的出門左轉,在公眾號查看「Deep Learning 學習(三)——在window下運行tensorfolw」。