目錄
1、函式物件
2、函式嵌套
3、閉包函式
3.1 什么是閉包函式
3.2 如何定義閉包函式
3.3 為何要有閉包函式——閉包函式的應用場景
1、函式物件
函式物件:指的是函式可以被當做’資料’來處理,
# func=記憶體地址 def func(): print('from func')
func()
輸出結果: from func
具體可以分為四個方面的使用:
(1)函式可以被參考——f=func
# func=記憶體地址 def func(): print('from func') f=func # 將func的記憶體地址傳給 f print(f,func) #輸出的是 f func 的記憶體地址 f() #呼叫函式 f
輸出結果:
<function func at 0x000001CF11CCA0D0> <function func at 0x000001CF11CCA0D0>
from func
(2)函式可以作為容器型別的元素——l=[func,]
# func=記憶體地址 def func(): print('from func') l=[func,] print(l) l[0]() dic={'k1':func} print(dic) dic['k1']() 輸出結果: [<function func at 0x000001B6BC12A0D0>] from func {'k1': <function func at 0x000001B6BC12A0D0>} from func
(3)函式可以作為引數傳入另外一個函式——foo(func)
def func(): print('from func') def foo(x): # foo(func), x = func的記憶體地址 print(x) #先輸出func 的記憶體地址 x() # x=func的記憶體地址,x()相當于 func() foo(func) # foo(func的記憶體地址) #呼叫函式foo 輸出結果: <function func at 0x000001C3AEF4A0D0> from func
# func=記憶體地址 def func(): print('from func') def foo(x): # x = func的記憶體地址 # print(x) x() foo(func) #即 foo(func的記憶體地址) 輸出結果: from func
(4)函式的回傳值可以是一個函式 ——return 函式名——注意:不加擴號噢
# func=記憶體地址 def func(): print('from func') def foo(x): # x=func的記憶體地址 return x # return func的記憶體地址 res=foo(func) # foo(func的記憶體地址) print(res) # res=func的記憶體地址 res() 輸出結果: <function func at 0x000001C3AEF4A0D0> from func
2、函式的嵌套
(1)函式的嵌套定義:在函式內定義其他函式
def f1(): def f2(): pass
(2)函式的嵌套呼叫:在呼叫一個函式的程序中又呼叫其他函式
def max2(x,y): if x > y: return x else: return y def max4(a,b,c,d): # 第一步:比較a,b得到res1 res1=max2(a,b) # 第二步:比較res1,c得到res2 res2=max2(res1,c) # 第三步:比較res2,d得到res3 res3=max2(res2,d) return res3 res=max4(1,2,3,4) print(res)
好大一顆栗子:
# 圓形 # 求圓形的求周長:2*pi*radius def circle(radius,action=0): from math import pi def perimiter(radius): return 2*pi*radius # 求圓形的求面積:pi*(radius**2) def area(radius): return pi*(radius**2) if action == 0: return 2*pi*radius elif action == 1: return area(radius) circle(33,action=0)
3、閉包函式
【大前提】
基于函式物件的概念,可以將函式回傳到任意位置去呼叫,
但作用域的關系是在定義完函式時就已經被確定了的,與函式的呼叫位置無關,
也就是說函式被當做資料處理時,始終以自帶的作用域為準,
閉包函式=名稱空間與作用域+函式嵌套+函式物件
核心點:名字的查找關系是以函式定義階段為準
(1)什么是【閉包函式】
函式被當做資料處理時,始終以自帶的作用域為準,若內嵌函式包含對外部函式作用域(而非全域作用域)中變數的參考,那么該’內嵌函式’就是閉包函式,簡稱閉包(closures),
"閉"函式指的該函式是內嵌函式
"包"函式指的該函式包含對外層函式作用域名字的參考(不是對全域作用域)
因而無論在何處呼叫閉包函式,使用的仍然是包裹在其外層的變數,
x=1 def outer(): x=2 def inner(): print(x) return inner func=outer() func() # 結果為2
可以通過函式的closure屬性,查看到閉包函式所包裹的外部變數,
>>> func.__closure__ (<cell at 0x10212af78: int object at 0x10028cca0>,) >>> func.__closure__[0].cell_contents 2
(2) 如何定義閉包函式
1)閉包函式:名稱空間與作用域的應用+函式嵌套
def f1(): x = 33333333333333333333 def f2(): print(x) f2() x=11111 def bar(): x=444444 f1() def foo(): x=2222 bar() foo() 輸出結果: 33333333333333333333
2)閉包函式:函式物件
def f1(): x = 33333333333333333333 def f2(): print('函式f2:',x) return f2 f=f1() # print(f) # x=4444 # f() def foo(): x=5555 f() foo() 輸出結果: 函式f2: 33333333333333333333
(3)為何要有閉包函式——閉包函式的應用
兩種為函式體傳參的方式:
方式一:直接把函式體需要的引數定義成形參
def f2(x): print(x) f2(1) f2(2) f2(3)
方式二:將值包給函式
def f1(x): # x=3 x=3 def f2(): print(x) return f2 x=f1(3) print(x) x()
又有好大一顆栗子:
import requests # 需要事先下載函式模板 傳參的方案一: def get(url): response=requests.get(url) print(len(response.text)) get('https://www.baidu.com') get('https://www.cnblogs.com/linhaifeng') get('https://zhuanlan.zhihu.com/p/109056932') 傳參的方案二: def outter(url): # url='https://www.baidu.com' def get(): response=requests.get(url) print(len(response.text)) return get baidu=outter('https://www.baidu.com') baidu() cnblogs=outter('https://www.cnblogs.com/linhaifeng') cnblogs() zhihu=outter('https://zhuanlan.zhihu.com/p/109056932') zhihu()
閉包函式的這種特性有時又稱為惰性計算,使用將值包給函式的方式,在下一篇博客介紹的裝飾器中也將大有用處,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/168993.html
標籤:Python
上一篇:7.機器學習之線性回歸演算法
