一 函数对象
函数对象指的是函数可以被当做’数据’来处理,具体可以分为四个方面的使用
1.1 函数可以被引用
1
2
3
4
5
6
|
>>> def add(x,y): ... return x + y ... >>> func = add >>> func( 1 , 2 ) 3 |
1.2 函数可以作为容器类型的元素
1
2
3
4
5
|
>>> dic = { 'add' :add, 'max' : max } >>> dic { 'add' : <function add at 0x100661e18 >, 'max' : <built - in function max >} >>> dic[ 'add' ]( 1 , 2 ) 3 |
1.3 函数可以作为参数传入另外一个函数
1
2
3
4
5
|
>>> def foo(x,y,func): ... return func(x,y) ... >>> foo( 1 , 2 ,add) 3 |
1.4 函数的返回值可以是一个函数
1
2
3
4
5
6
|
>>> def bar(): ... return add ... >>> func = bar() >>> func( 1 , 2 ) 3 |
二 闭包函数
2.1 闭与包
基于函数对象的概念,可以将函数返回到任意位置去调用,但作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
x = 1 def f1(): def f2(): print (x) return f2 def f3(): x = 3 f2 = f1() #调用f1()返回函数f2 f2() #需要按照函数定义时的作用关系去执行,与调用位置无关 f3() #结果为1 |
也就是说函数被当做数据处理时,始终以自带的作用域为准。若内嵌函数包含对外部函数作用域(而非全局作用域)中变量的引用,那么该’内嵌函数’就是闭包函数,简称闭包(Closures)
1
2
3
4
5
6
7
8
9
|
x = 1 def outer(): x = 2 def inner(): print (x) return inner func = outer() func() # 结果为2 |
可以通过函数的__closure__属性,查看到闭包函数所包裹的外部变量
1
2
3
4
|
>>> func.__closure__ (<cell at 0x10212af78 : int object at 0x10028cca0 >,) >>> func.__closure__[ 0 ].cell_contents 2 |
“闭”代表函数是内部的,“包”代表函数外’包裹’着对外层作用域的引用。因而无论在何处调用闭包函数,使用的仍然是包裹在其外层的变量。
2.2 闭包的用途
目前为止,我们得到了两种为函数体传值的方式,一种是直接将值以参数的形式传入,另外一种就是将值包给函数
1
2
3
4
5
6
7
8
9
10
11
|
import requests #方式一: def get(url): return requests.get(url).text #方式二: def page(url): def get(): return requests.get(url).text return get |
提示:requests模块是用来模拟浏览器向网站发送请求并将页面内容下载到本地,需要事先安装:pip3 install requests
对比两种方式,方式一在下载同一页面时需要重复传入url,而方式二只需要传一次值,就会得到一个包含指定url的闭包函数,以后调用该闭包函数无需再传url
1
2
3
4
5
6
7
8
9
10
11
12
|
# 方式一下载同一页面 get( 'https://www.python.org' ) get( 'https://www.python.org' ) get( 'https://www.python.org' ) …… # 方式二下载同一页面 python = page( 'https://www.python.org' ) python() python() python() …… |
闭包函数的这种特性有时又称为惰性计算。使用将值包给函数的方式,在接下来的装饰器中也将大有用处
到此这篇关于Python函数对象与闭包介绍的文章就介绍到这了,更多相关Python函数对象与闭包内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://www.cnblogs.com/Dominic-Ji/articles/15960134.html