函数之闭包函数和装饰器

闭包函数和装饰器

一、闭包函数

1.什么是闭包函数?

字面意思:闭:封闭,包:包裹;闭包函数就是函数嵌套,函数对象,名称空间与作用域的结合体

  • 闭包函数必须在函数内部定义

  • 闭包函数可以引用外层函数的名字

2.闭包函数怎么用

闭包函数是为了装饰器做准备

def outer(num2):
   num2 = 100
   def inner():      # inner就是闭包函数
       print(num2)   # 如果局部找不到变量名,再从全局找
   return inner      # 返回inner

func = outer("num2")   # 本质是将inner函数名(函数地址)赋值给func
func()    # 调用inner函数
举例:
# 直接传值

import requests


# 调用爬虫包
def spider_func(url):
   response = requests.get(url)
   # 接受网址的返回值
   if response.status_code == 200:
       # 判断http的状态码是不是200
       print(len(response.text))
       # print(response.text)


url = 'https://www.taobao.com/'
spider_func(url)

# 通过闭包函数传值

import requests


def spider_outer(url):
   def spider_inner():
       response = requests.get(url)
       print(len(response.text))

   return spider_inner    


url = 'https://www.taobao.com/'

spider_func = spider_outer(url)    # 本质是spider_inner这个函数的函数地址

spider_func()

二、装饰器

1.什么是装饰器?

字面意思就是修饰的工具,就是一种具有添加新功能能力的函数

装饰器必须遵循"开放封闭原则"

开放:对函数功能的添加是开放的, 意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况

封闭:对函数功能的修改是封闭的, 意味着对象一旦设计完成,就可以独立完成其工作,而不要对其进行修改

2.为什么要使用装饰器?

可以解决代码冗余问题,提高代码的可扩展性

3.怎么使用装饰器

可以通过闭包函数来实现装饰器

注意:使用装饰器要注意两点

不修改被装饰对象的源代码

不修改被装饰对象的调用方式


def download_movie(name):
   '''模拟电影下载'''
   print(f"电影{name}开始下载...")
   time.sleep(3)
   print(f"电影{name}下载完成...")
   return f'tank与{name}'


# 添加统计时间的装饰器
def time_out(func):
   def time_inner(*args, **kwargs):  # 可以接受任何输入的值
       start_time = time.time()  # 收集开始时间
       res = func(*args, **kwargs)  # 接受源代码输入的任意值并收集返回值
       end_time = time.time()  # 收集结束时间
       print(f'总时间{end_time - start_time}')  # 计算时间并打印
       return res

   return time_inner  # 返回到闭包函数


download_movie = time_out(download_movie)     # 将download_movie赋值给func
download_movie('辛德勒的名单')

注意:

# 装饰器模版
def warpper(func):
   
   def warpper_inner(*args, **kwargs):  # 可以接收原函数传入的任意值
       
       res = func(*args, **kwargs)    # 同样
       
       return res    # 将原函数的返回时原封不动的返回去
       
   return warpper_inner     # 调用闭包函数


def func1():
   pass

func1 = warpper(func1)
func1()    # 本质运行的程序的是warpper_inner()

4.装饰器的语法糖(@)

装饰器的语法糖,是属于装饰器的。@: 装饰器的语法糖
# 注意: 在使用装饰器语法糖时,装饰器必须定义在被装饰对象之上。
# 添加统计时间的装饰器
def time_out(func):
   def time_inner(*args, **kwargs):  # 可以接受任何输入的值
       start_time = time.time()  # 收集开始时间
       res = func(*args, **kwargs)  # 接受源代码输入的任意值并收集返回值
       end_time = time.time()  # 收集结束时间
       print(f'总时间{end_time - start_time}')  # 计算时间并打印
       return res

   return time_inner  # 返回到闭包函数


@time_out     # 调用语法糖,  注意装饰器在原函数之前

def download_movie(name):
   '''模拟电影下载'''
   print(f"电影{name}开始下载...")
   time.sleep(3)
   print(f"电影{name}下载完成...")
   return f'tank与{name}'

download_movie('辛德勒的名单')    # 运行函数

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/jiangxianseng/p/11844360.html
今日推荐