Python函數(shù)學(xué)習(xí)筆記
更新時(shí)間:2008年10月07日 23:49:40 作者:
Python探測局部作用域的時(shí)候:是在python編譯代碼時(shí)檢測,而不是通過他們在運(yùn)行時(shí)的賦值。
局部名字靜態(tài)檢測
Python探測局部作用域的時(shí)候:是在python編譯代碼時(shí)檢測,而不是通過他們在運(yùn)行時(shí)的賦值。
正常的情況下,沒在函數(shù)中復(fù)制的名字將在包含它的模塊中查找:
>>> x=99
>>> def selector():
... print x
...
>>> selector()
99
但是:
>>> def selector():
... print x
... x=100
...
>>> selector()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in selector
UnboundLocalError: local variable 'x' referenced before assignment
會(huì)得到未定義名字的錯(cuò)誤。
當(dāng) 交互式輸入或從一個(gè)模塊中導(dǎo)入時(shí),python讀取并編譯這段代碼,當(dāng)編譯時(shí)python查看x的賦值,并決定在函數(shù)中任何地方x都將是個(gè)局部名字。到后 來函數(shù)真的運(yùn)行,print執(zhí)行時(shí),賦值還沒有發(fā)生,python會(huì)說你正在使用一個(gè)未定義的名字。根據(jù)他的名字規(guī)則,應(yīng)該是局部的x在賦值前被使用了。
解決辦法:
如果你想打印全局x,你應(yīng)該在global語句中聲明:(這意味著該賦值也改變?nèi)謝,而不是局部x)
>>> def selector():
... global x
... print x
... x=88
...
>>> selector()
99
如果你想打印出全局賦值,在設(shè)定一個(gè)局部的,導(dǎo)入包含它的模塊并用限定得到這個(gè)全局的版本:
>>> x=99
>>> def selector():
... import __main__
... print __main__.x
... x=88
... print x
...
>>> selector()
99
88
限定(.x部分)從一個(gè)名字空間對(duì)象中得到一個(gè)值。交互環(huán)境的名字空間是一個(gè)叫做__main__的模塊。
嵌套函數(shù)可以嵌套作用域(在新版本中和老版本中不同)
>>> def outer(x):
... def inner(i):
... print i,
... if i: inner(i-1)
... inner(x)
...
>>> outer(3)
3 2 1 0
使用默認(rèn)值保存引用
>>> def outer(x):
... def inner(i,self=inner):
... print i,
... if i:self(i-1)
... inner(x)
...
>>> outer(3)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in outer
UnboundLocalError: local variable 'inner' referenced before assignment
解決原則:最簡單的方式總是最正確的方式
>>> def inner(i):
... print i,
... if i:inner(i-1)
...
>>> def outer(x):
... inner(x)
...
>>> outer(3)
3 2 1 0
默認(rèn)的可變對(duì)象
>>> def saver(x=[]):
... x.append(1)
... print x
...
>>> saver([2])
[2, 1]
>>> saver()
[1]
>>> saver()
[1, 1]
>>> saver()
[1, 1, 1]
問題是,這里只有一個(gè)列表對(duì)象——def執(zhí)行時(shí)生成的一個(gè)。在每一次函數(shù)被調(diào)用時(shí),你不會(huì)得到新的列表對(duì)象,而是原列表對(duì)象的增長。
解決辦法:如果那不是你想要的行為,簡單的移動(dòng)默認(rèn)值到函數(shù)體中。只要代碼里的值在每一次函數(shù)運(yùn)行時(shí)都執(zhí)行,你每次將得到一個(gè)新的對(duì)象:
>>> def saver(x=None):
... if x is None:
... x=[]
... x.append(1)
... print x
...
>>> saver([2])
[2, 1]
>>> saver()
[1]
>>> saver()
[1]
>>> saver()
[1]
上 面的if語句幾乎可以被賦值x=x or []代替,因?yàn)閜ython的or將返回他的操作對(duì)象中的一個(gè):如果沒有參數(shù)被傳遞,x默認(rèn)為None,所以or在右側(cè)返回一個(gè)生成的空列表。但這不完全 一樣,當(dāng)傳遞的是空列表時(shí),函數(shù)將擴(kuò)展并返回一個(gè)新生成的列表,而不是向前面的版本那樣擴(kuò)展并返回一個(gè)被傳遞的列表(表達(dá)式變成[] or [],這將計(jì)算出新的列表)
Python探測局部作用域的時(shí)候:是在python編譯代碼時(shí)檢測,而不是通過他們在運(yùn)行時(shí)的賦值。
正常的情況下,沒在函數(shù)中復(fù)制的名字將在包含它的模塊中查找:
>>> x=99
>>> def selector():
... print x
...
>>> selector()
99
但是:
>>> def selector():
... print x
... x=100
...
>>> selector()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in selector
UnboundLocalError: local variable 'x' referenced before assignment
會(huì)得到未定義名字的錯(cuò)誤。
當(dāng) 交互式輸入或從一個(gè)模塊中導(dǎo)入時(shí),python讀取并編譯這段代碼,當(dāng)編譯時(shí)python查看x的賦值,并決定在函數(shù)中任何地方x都將是個(gè)局部名字。到后 來函數(shù)真的運(yùn)行,print執(zhí)行時(shí),賦值還沒有發(fā)生,python會(huì)說你正在使用一個(gè)未定義的名字。根據(jù)他的名字規(guī)則,應(yīng)該是局部的x在賦值前被使用了。
解決辦法:
如果你想打印全局x,你應(yīng)該在global語句中聲明:(這意味著該賦值也改變?nèi)謝,而不是局部x)
>>> def selector():
... global x
... print x
... x=88
...
>>> selector()
99
如果你想打印出全局賦值,在設(shè)定一個(gè)局部的,導(dǎo)入包含它的模塊并用限定得到這個(gè)全局的版本:
>>> x=99
>>> def selector():
... import __main__
... print __main__.x
... x=88
... print x
...
>>> selector()
99
88
限定(.x部分)從一個(gè)名字空間對(duì)象中得到一個(gè)值。交互環(huán)境的名字空間是一個(gè)叫做__main__的模塊。
嵌套函數(shù)可以嵌套作用域(在新版本中和老版本中不同)
>>> def outer(x):
... def inner(i):
... print i,
... if i: inner(i-1)
... inner(x)
...
>>> outer(3)
3 2 1 0
使用默認(rèn)值保存引用
>>> def outer(x):
... def inner(i,self=inner):
... print i,
... if i:self(i-1)
... inner(x)
...
>>> outer(3)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in outer
UnboundLocalError: local variable 'inner' referenced before assignment
解決原則:最簡單的方式總是最正確的方式
>>> def inner(i):
... print i,
... if i:inner(i-1)
...
>>> def outer(x):
... inner(x)
...
>>> outer(3)
3 2 1 0
默認(rèn)的可變對(duì)象
>>> def saver(x=[]):
... x.append(1)
... print x
...
>>> saver([2])
[2, 1]
>>> saver()
[1]
>>> saver()
[1, 1]
>>> saver()
[1, 1, 1]
問題是,這里只有一個(gè)列表對(duì)象——def執(zhí)行時(shí)生成的一個(gè)。在每一次函數(shù)被調(diào)用時(shí),你不會(huì)得到新的列表對(duì)象,而是原列表對(duì)象的增長。
解決辦法:如果那不是你想要的行為,簡單的移動(dòng)默認(rèn)值到函數(shù)體中。只要代碼里的值在每一次函數(shù)運(yùn)行時(shí)都執(zhí)行,你每次將得到一個(gè)新的對(duì)象:
>>> def saver(x=None):
... if x is None:
... x=[]
... x.append(1)
... print x
...
>>> saver([2])
[2, 1]
>>> saver()
[1]
>>> saver()
[1]
>>> saver()
[1]
上 面的if語句幾乎可以被賦值x=x or []代替,因?yàn)閜ython的or將返回他的操作對(duì)象中的一個(gè):如果沒有參數(shù)被傳遞,x默認(rèn)為None,所以or在右側(cè)返回一個(gè)生成的空列表。但這不完全 一樣,當(dāng)傳遞的是空列表時(shí),函數(shù)將擴(kuò)展并返回一個(gè)新生成的列表,而不是向前面的版本那樣擴(kuò)展并返回一個(gè)被傳遞的列表(表達(dá)式變成[] or [],這將計(jì)算出新的列表)
相關(guān)文章
Django集成celery發(fā)送異步郵件實(shí)例
今天小編就為大家分享一篇Django集成celery發(fā)送異步郵件實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12python中not、and和or的優(yōu)先級(jí)與詳細(xì)用法介紹
這篇文章主要給大家介紹了python中not、and和or的優(yōu)先級(jí)與詳細(xì)用法介紹,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Python?pandas處理缺失值方法詳解(dropna、drop、fillna)
缺失數(shù)據(jù)會(huì)在很多數(shù)據(jù)分析應(yīng)用中出現(xiàn),pandas的目標(biāo)之一就是盡可能無痛地處理缺失值,下面這篇文章主要給大家介紹了關(guān)于Python?pandas處理缺失值方法的相關(guān)資料,處理方法分別是dropna、drop、fillna,需要的朋友可以參考下2022-08-08python和pyqt實(shí)現(xiàn)360的CLable控件
這篇文章主要介紹了python和pyqt實(shí)現(xiàn)360的CLable控件示例,需要的朋友可以參考下2014-02-02Python面向?qū)ο蟪绦蛟O(shè)計(jì)中類的定義、實(shí)例化、封裝及私有變量/方法詳解
這篇文章主要介紹了Python面向?qū)ο蟪绦蛟O(shè)計(jì)中類的定義、實(shí)例化、封裝及私有變量/方法,結(jié)合具體實(shí)例形式較為詳細(xì)的分析了Python面向?qū)ο蟪绦蛟O(shè)計(jì)中類的定義、實(shí)例化、封裝、私有變量、私有方法等相關(guān)使用技巧,需要的朋友可以參考下2019-02-02python整小時(shí) 整天時(shí)間戳獲取算法示例
今天小編就為大家分享一篇python整小時(shí) 整天時(shí)間戳獲取算法示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02python進(jìn)階從青銅到王者一定會(huì)用上的Python技巧
這篇文章主要介紹了python進(jìn)階從青銅到王者一定會(huì)用上的Python技巧,本文通過幾個(gè)Python的小案例,讓大家體會(huì)其中蘊(yùn)含的技巧一起來圍觀吧2021-09-09Python實(shí)現(xiàn)圖像去霧效果的示例代碼
本文將利用《bringing old photos back to life》 的開源代碼,并在此基礎(chǔ)上進(jìn)行修改,從而實(shí)現(xiàn)圖像去霧的效果,感興趣的小伙伴可以學(xué)習(xí)一下2022-02-02