最近閑著時(shí)就看看《Python核心編程》第二版拌屏,這本書很老了但是基礎(chǔ)知識(shí)挺全的,自己一直用Python3實(shí)踐天试,發(fā)現(xiàn)一個(gè)有趣的現(xiàn)象槐壳。
Python作用域與C/C++的區(qū)別
首先說到作為C++er剛接觸Python時(shí)遇到一個(gè)疑惑的問題,就是類似下面這樣的代碼
if 1 < 2:
x = 1
else:
x = -1
print(x)
現(xiàn)代C++er的基本素質(zhì)是時(shí)刻銘記某變量的生命周期喜每,所以按照C++的變量離開作用域即銷毀的思路务唐,我會(huì)覺得這里的變量x已經(jīng)被回收了。在if-else塊之外打印x带兜,相當(dāng)于引用一個(gè)未定義的對(duì)象枫笛。
然而這段代碼是正確的,因?yàn)閜ython的作用域概念和C++不一樣刚照,只有def/class/lambda影響python變量的作用域刑巧,if-else塊/try-except-finally塊/for塊/while塊均不改變變量的作用域。
Python異常參數(shù)在2和3的作用域區(qū)別
然后實(shí)踐10.3.6節(jié)的代碼時(shí)發(fā)現(xiàn)python2和3在異常參數(shù)的生命周期上有區(qū)別
Python 2.7.12 (default, Nov 20 2017, 18:23:56)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
... 1 / 0
... except Exception, e:
... pass
...
>>> type(e)
<type 'exceptions.ZeroDivisionError'>
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
... 1 / 0
... except Exception as e:
... pass
...
>>> type(e)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'e' is not defined
可以發(fā)現(xiàn)在python2中无畔,except后接的異常參數(shù)e在try-except塊之外可以訪問啊楚,然而在python3中則不可以,提示e未被定義浑彰。
但是如果在except塊中定義的變量是可以被外部訪問的
>>> try:
... 1 / 0
... except Exception as e:
... e0 = e
... pass
...
>>> type(e0)
<class 'ZeroDivisionError'>
也就是說python3中try-except塊仍然不改變變量的作用域恭理,但是except后接的異常參數(shù)是默認(rèn)對(duì)外部不可見的。