下面的例子演示了用3種方法來在外部引用函數內部定義的列表:
成都創新互聯公司是一家集網站建設,高陵企業網站建設,高陵品牌網站建設,網站定制,高陵網站建設報價,網絡營銷,網絡優化,高陵網站推廣為一體的創新建站企業,幫助傳統企業提升企業形象加強企業競爭力。可充分滿足這一群體相比中小企業更為豐富、高端、多元的互聯網需求。同時我們時刻保持專業、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們為更多的企業打造出實用型網站。
#返回函數內部定義的列表
def int_list1():
l=[1,2]
return l
#將函數內部列表定義成全局的
def int_list2():
global l
l=[3,4]
#將函數內部列表定義成函數的一個屬性
def int_list3():
l=[5,6]
int_list3.l=l
print(int_list1())
int_list2()
print(l)
int_list3()
print(int_list3.l)
這是截圖:
(1)unpack tuple和list, 可以讓函數返回多個值
def count():
return (1, 2, 3) # 或者 return [1, 2, 3]
# 把列表解包,把1 2 3 分別賦值給 a b c
a, b, c = count()
print a, b, c
# 輸出 1, 2, 3
(2)假設你知道Python的dict類型。Python中,在函數中定義一個變量的時候,會在一個隱藏的叫locals的dict里面插入key-value,其中key是變量名,value是變量值。而引用一個變量的時候,則首先會在這個叫locals的dict里面,根據變量名作為key,去查對應的值。
var = 1 # 你可以認為這里進行了 locals['var'] = 1 的操作
print var # 在對var變量進行求值的時候,就在locals['var']里面找var變量對應的值
(3)for循環中,每次循環只是給 `i` 重新綁定值
for i in (1, 2, 3):
print i
print i
# 一次輸入 1 2 3 3
每次`for i in (1, 2, 3)`相當于在`print i`之前,進行了
`locals['i'] = 1`
`locals['i'] = 2`
`locals['i'] = 3`
的操作
所以最后的`print i`再去locals字典里面找`i`的時候,就變成 3 了。
(4)閉包是 一個函數加上這個函數引用的外部變量
var = 1
def f():
print var
# 這里的閉包是函數 f 和 f 引用的外部變量 var
def count():
var2 = 2
def f():
print var2
# 這里的閉包是函數 f 和 f 引用的外部變量 var2
return f
拿第一個函數 f 來說。在 f 運行的時候,解釋器拿著'var'這個字符串去locals字典里面找,發現找不到,于是在closure字典里面找,最后closure字典里面找,你可以認為就是找closure['var'],然后發現找到對應的值。count里面的 f 函數同理。
(為了容易理解,我這里說謊了。實際上 f 壓根沒有closure,count里面的 f 才有。其實closure壓根不是像locals那樣的字典)
(5)函數定義時,函數只是記錄變量的名字。
要區分什么是名字,什么是值。
`i = 1`這里 i 只是名字,只是一個字符串 'i' 。這句話運行完,locals['i'] = 1,就說 i 對應的值是1
def count():
fs = []
for i in range(1, 4):
# 定義一個函數,等價于運行了 locals['f'] = 真正生成的函數
# 每次循環,這里都會重新生成一個函數,然后把重新生成的函數賦值給 locals['f']
def f():
return i * i # 引用了'i'這個名字,但并不是引用了'i'對應的值
# 等價于 locals['fs'].append(locals['f'])
# f 不是函數,它只是一個名字'f'。f 引用的東西,也就是locals['f']才是真正的函數
fs.append(f)
# 于是這個for循環生成了三個函數,這三個函數是沒有名字的,這個函數運行完后,它們跟'f'這個名字就毛關系都沒有了(是的我說慌了,但可以先不管)
# 把整個列表返回,這個列表包含了三個函數
return fs
# count()返回三個函數的列表,unpack 列表的語法把列表中的三個函數抽出來,重新給他們命名為 f1, f2, f3
# 也就是說,
# locals['f1'] = 列表中的第1個函數
# locals['f2'] = 列表中的第2個函數
# locals['f3'] = 列表中的第3個函數
# 這三個函數跟'f'這個名字現在毛關系都沒有。(其實是有的,但為了說明需要簡化,現在你可以完全不管括號里面說的話)
f1, f2, f3 = count()
print f1(), f2(), f3()
# 好了我們運行它們,輸入都是 9
# def f():
# return i * i
這是因為 f1 現在對應的函數,里面引用了 'i' 這個字符串,我們根據 'i '這個字符串去找它對應的值,先找到 f 當前的locals字典,發現沒有,因為函數定義的時候沒有定義 i 變量。然后再去closure['i']里面找,因為Python是通過closure字典實現閉包的(就當它是對的好不好),所以我們可以在closure['i']找到值,這個值就是我們上一次運行的時候count函數里面殘留的locals['i'],而由于for循環三遍之后,locals['i'] == 3,所以找到 i 的值就是3。所以最后輸出都是9
變量的引用
變量和數據都是保存在內存中的
變量和數據是分開存儲的
數據保存在內存中某個位置,通過地址來標記
變量保存的是數據的地址,通過地址可以找到數據在內存空間的位置
把變量保存數據地址的過程稱為引用
變量的重新賦值修改的是變量中引用數據的內存地址
變量之間的賦值實際是引用的傳遞
函數參數的傳遞,本質也是引用的傳遞
函數的返回值本身也是引用的傳遞
可變和不可變類型
不可變類型,內存中的數據不允許被修改:數字類型(int,bool,float,complex,long(2,x)、字符串、元組(tuple)
可變類型,內存中的數據可以被修改:列表list、字典dict
無論是可變還是不可變數據類型,通過賦值語句,都會改變變量的引用
Hash函數只能接收不可變數據類型,字典的鍵也只能是不可變數據類型,字典的value值可以是任意數據類型
局部變量
1.在函數內部定義的變量就是局部變量(作用范圍只能是當前函數內部)
2.在函數外部無法直接訪問局部變量
3.不同的函數中可以定義同名的局部變量
4.局部變量的生命周期:從定義變量時開始,到函數運行結束
全局變量
1.在所有函數外邊定義的變量就是全局變量
2.讓所有函數都能訪問到,可以作為函數通信的橋梁
3.一般情況下,為了和普通變量的區別,需要加上g_或gl_前綴
4.全局變量一般放在所有函數的最上面
5.在函數內部修改全局變量,必須要加上global關鍵字,如果不加global只是定義了一個同名的局部變量
函數的多個返回值
沒有復制,函數也是個對象,基本就和你 return 一個 list 一個 dict 沒什么兩樣。
試試看在 Python REPL 中創建一個 function:
def foobar(): print("你好")
foobar
func_list = [foobar, foobar, foobar]
func_list[0]()
后者是一個閉包 ( closure ),簡單來說就是函數對象中包裝了函數中引用的外部變量,可以想象成這個函數被動態創建的時候,引用的外部變量凍結在函數里面了。
你新補充的我沒怎么看懂,*args 的作用嗎?*args 在形參上的作用類似捕獲給函數的實參放在一個 args 的表中作為形參,如果作為實參傳入的話,就是將 args 這個表解開作為分別的形參輸入。
當前文章:python函數返回引用 python中返回函數
文章地址:http://m.kartarina.com/article32/dodsdpc.html
成都網站建設公司_創新互聯,為您提供企業建站、網站改版、ChatGPT、域名注冊、網站營銷、云服務器
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯