函数作为返回值、闭包函数、装饰器day11
今日学习总结:
一、函数作为返回值
ps:print 仅仅是打印在控制台,return是将return后面的部分作为返回值,作为函数的输出。可以用变量接走继续使用该返回值做其他事情。
返回函数
def test3(): print("hello") return test3 #test3是个地址,返回给函数test3() .注意test3() 也是一个地址,因为test3是个地址给了test3() z=test3() z() #调用函数
def test3(): print("in the test3") return 'test3' #表示返回一个字符串值“test3”返回给函数 test3() z=test3() #把字符串值'rest3' 赋给变量z print(z) #这时就不需要在()了,要想有结果必须要打印
def test2(): print("in the test2")#指定返回 return 55 def test4(): print("in the test4")#返回函数 return test2() #表示把test2()返回给test4() a=test4() #表示执行test4()函数,把test2()给a print(a) 结果: in the test4 in the test2 55
二、闭包函数(重要)
“闭包”,就是在构造函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层函数体中的临时变量
1.封闭、包裹。闭包函数必须在函数内部定义
2.作用:闭包函数可以引用外层函数的名字
3.闭包函数是函数嵌套、函数对象、名称空间与作用域的结合,必须返回函数
4.函数内部可以直接读取全局变量,在函数外部自然无法读取函数内的局部变量。
那怎么样才能 从外部读取到内部变量?
如何从外部读取局部变量?
出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。
答;那就是在函数的内部,再定义一个函数。
例子:无参数闭包函数
def outer(): number = 100 def inner(): #在这里inner是闭包 print(number) return inner #将inner地址返回给函数outer() func = outer() #将outer() 它表示地址赋值给func func() #调用函数 def outer(): number = 100 def inner(): #在这里inner是闭包 print(number) return inner #将inner地址返回给函数outer() outer()() #将outer()是地址 后面加()表示调用outer()函数
例子:有参数闭包函数
def outer(number): def inner(): print(number) return inner func = outer(12) # 表示调用函数outer 返回inter的地址 .然后赋值给变量func func() # 表示调用函数
例子:用有参数闭包函数 爬取某个网站,打印获取数据的长度
import requests #导入发送请求包 def spider_outer(url): def spider_inner(): response = requests.get(url) #requests的含的get方法 if response.status_code == 200: #.status_code 表示 状态码。 状态码200 表示发送请求成功 print(len(response.text)) return spider_inner r=spider_outer('https://www.cnblogs.com/xiaoyuanqujing/') r()
4.闭包函数的应用:为了装饰器作准备
5.闭包函数的作用:从外部读取局部变量
def f1(): number = 100 def f2(): #在这里f2是闭包 print(number) return f2 #将f2地址返回给函数f1() func = f1() #将f1() 它表示地址赋值给func func() #调用函数
在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们就可以在f1外部读取它的内部变量了.
三、装饰器
不修改被装饰对象的源代码
不修改被装饰对象的调用方式
被装饰对象: ---> 需要添加功能 函数
装饰器: ---> 被装饰对象添加的新功能的 函数
1.定义:在不修改装饰对象源代码与调用方式的前提下,添加新的功能
遵循的原则:开放封闭。
开放:对现有功能的扩展开放
封闭:已实现的功能代码块不能被修改
2.装饰器的作用:
统计时间
登录认证
3.为什么使用装饰器:
可以解决代码冗余问题,提高代码的可扩展性。
4.编写装饰器
例子1:被装饰对象:无参数,有返回值
import time def download_movie(): print('开始下载电影...') time.sleep(3) print('电影下载成功...') return '小泽.mp4' def time_record(func): # func <-- download_movie def inner(): start_time = time.time() res = func() end_time = time.time() print(f'消耗时间: {end_time - start_time}') return res print(inner()) return inner #表示把 inner的地址返回给time_record()函数 time_record(download_movie)() #time_record(download_movie)表示接受inner的地址,后面的()表示调用函数
import time def download_movie(): print('开始下载电影...') time.sleep(3) print('电影下载成功...') return '小泽.mp4' def time_record(func): # func <-- download_movie def inner(): start_time = time.time() res = func() end_time = time.time() print(f'消耗时间: {end_time - start_time}') return res print(inner()) return inner #表示把 inner的地址返回给time_record()函数 # time_record(download_movie)() #time_record(download_movie)表示接受inner的地址,后面的()表示调用函数 download_movie=time_record(download_movie) download_movie()
例子2:被装饰对象:有参数,有返回值
import time def download_movie(url): print(f'{url}中的电影开始下载了...') time.sleep(3) print('电影下载成功...') return '小泽.mp4' def time_record(func): def inner(url): start_time = time.time() res = func(url) # 这里func()中的参数是从inner中拿的 end_time = time.time() print(f'消耗时间: {end_time - start_time}') return res return inner t = time_record(download_movie) # time_record(download_movie) 表示给time_record()函数传download_movie实参
t('https://www.cnblogs.com/xiaoyuanqujing/')
例子3: 被装饰对象,需要接收多个参数
import time def download_movie(*args, **kwargs): print('电影开始下载了...') time.sleep(3) print('电影下载成功...') return '小泽.mp4' def time_record(func): def inner(*args, **kwargs): # *args, **kwargs接收所有参数 start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print(f'消耗时间: {end_time - start_time}') return res return inner download_movie = time_record(download_movie) download_movie(url1='https://www.baidu.com', url2='url2', url3='url3')
四、
@: 装饰器的语法糖
@wrapper
注意: 在使用装饰器语法糖时,装饰器必须定义在被装饰对象之上。
五、装饰器模板
def wrapper(func): def inner(*args, **kwargs): # 添加新功能 res = func(*args, **kwargs)
#添加新功能 return resreturn inner def func1(): pass func1 = wrapper(func1) func1() # inner(
。

浙公网安备 33010602011771号