python3装饰器作用_python3 装饰器原理以及应用小案例

目录

一、什么是装饰器

装饰器是python中一个很重要的概念,简单来说:从字面意思来讲,就是装饰,强化,对你的函数进行功能是的扩充,并且无需修改被修饰函数的代码,起到装饰、补充的作用

要了解装饰器,我们先了解下什么是闭包函数

闭包函数:在嵌套函数中,如果内部函数对外部函数的变量进行了引用并且返回内部函数,那么内部函数就是闭包函数

我们看一个闭包函数的简单案例,来理解闭包

#定义了func的外部函数,中有c局部变量

def func(a,b):

c = 10

def inner_func():#内部函数inner对外部函数变量c做了引用

s = a + b + c

print(s)

print(locals()) #产看本地的变量

return inner_func #外部函数返回的是一个内部函数

x = func(3,6) #内层函数返回值,用x接收

x() #x的值等于 x =inner_func,是一个函数,所以可以调用

闭包注意点:

1、内部函数可以访问外部函数的不可变变量,但是如果要修改不可变变量,则要加关键字nonlocal进行声明

2、内部函数和外部函数中的变量代码是平级的

3、内部函数只是做了声明,外部函数代码中要进行调用,才会执行内部函数代码

4、内部函数修改全局变量的不可变变量,要加global关键字进行声明

闭包应用小案例:计数器

def counter():

i = 0

def inner_func():

nonlocal i

i +=1

print("执行第{}次".format(i))

return inner_func

x = counter()

x()

x()

x()

二、装饰器的特点

1、函数作为参数

2、要有闭包的特点

装饰器的基本结构案例:

#定义装饰器,对房子进行装饰

def decorate(func): #传输参数hourse为函数

a = 100

def wrapper(): #定义内部函数,并调用func

func()

print("开始装饰毛坯房")

print("开始了{}地板".format(a))

print("开始刷漆")

return wrapper

@decorate #hourse是被装饰的函数,(在@下面就是被装饰的函数) decoreate就是装饰器

#简单定义一个毛坯房

def hourse():

print("这个是一个毛坯房")

hourse()

我们来简单梳理下上面的执行加载过程:

1、hourse 是被装饰的函数

2、decorate是装饰器

3、开始执行decorate,然后decorate返回值赋值给hourse

我们通过案例来验证下上面的结论:

def decorate(func):

a = 100

print("开始进行装饰")

def wrapper(*args,**kwargs):

func(*args,**kwargs)

print("一共铺砖{}块".format(a))

print("开始进行刷漆")

print("开始进行家具布置")

print("装饰完成")

print(wrapper,1)

return wrapper

@decorate

def hourse():

print("这是一个毛坯房")

print(hourse)

上面代码执行结果:

开始进行装饰

装饰完成

.wrapper at 0x0000022D01A70EA0> 1

.wrapper at 0x0000022D01A70EA0>

注意观察,得出如下

1、当我们去装饰hourse时,没有进行调用,只是打印hourse,你观察函数的内存地址,和指向的就是wrapper内部函数的地址

2、执行顺序。

2.1 执行decorate函数

2.2 加载wrapper,注意只是加载,但是没有执行

2.3 hourse作为实参传入到decorate中,并decorate的返回值赋值个hourse

当我们把  print(hourse)  改为调用 hourse():得到的结果是:

开始进行装饰

装饰完成

.wrapper at 0x0000023E47BF0EA0> 1

这是一个毛坯房

一共铺砖100块

开始进行刷漆

开始进行家具布置

进一步说明了我们上面的结论

我们进一步来说明,当我们被装饰的函数有参数,并且装饰器也有参数的情形:

def outer(a):

def decorate(func):

def wrapper(*args,**kwargs):

func(*args,**kwargs)

print("---->开始第{}块铺地板".format(a))

return wrapper

return decorate

@outer(a=10)

def house(ti):

print("房子到期日期是{}".format(ti))

house('6月10日')

当三层函数嵌套(装饰器有参数):

1、outer函数最外层,用来接收装饰器的参数

2、decorate第二层,用来接收被装饰的函数func

3、最内层函数,用来接收被装饰的函数的实参,因为我们不确定实参个数,所以通常是使用*args 和**kwargs来进行接收实参

最后,我们来看一个应用的实际案例:

场景:当我们没有登录到淘宝,可以查看商品信息,但是添加到购物车时,就会提示让你登录,或者你访问淘票票进行查看电影,当你点击电影查看票务详情,就会提示让你登录,我们就看看这段使用装饰器该怎么实现

代码如下:

import time

is_login = False

def login():

username = input("请输入用户名:")

password = input("请输入用户密码:")

if username == 'admin' and password == '123456':

return True

else:

return False

#添加装饰器

def decorater(func):

def wrapper(*args,**kwargs):

global is_login

if is_login:

func(*args,**kwargs)

else:

print("用户没有登录,请登录")

is_login = login()

return wrapper

@decorater

def pay(n):

print("正在支付中.....")

time.sleep(2)

print("支付完成,一共支付了{}元".format(n))

pay(3000)

pay(800)

完结总结:装饰器是一个重要模块,后续再flask或Drango中会有很多应用,这里做个详细的复盘笔记,加深自己印象

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值