首页 > 编程语言 >python装饰器初级

python装饰器初级

时间:2022-10-11 21:58:31浏览次数:50  
标签:函数 python res 初级 func time print 装饰 def

global与nonlocal

1.global的作用:
可以在局部空间里直接就该全局名称工具中的数据
代码展示:
name = 'moon'       #设置了一个全局变量
def fucn():
    name = 'god'    #设置了一个局部变量
fucn()              #执行函数
print(name)        # moon 因为局部变量只在局部有作用,所以没有更改全局变量name

def fucn():        
    global name      # 使用了global方法,可以在局部空间直接修改全局空间命名
    name = 'god'
fucn()
print(name)       # god  因为global方法,在函数代码体执行时更改了全局变量


2.nonlocal的作用:
可以是内部局部空间修改外层局部空间变量数据

def fucn():       # 1 定义一个函数fucn
    age = 18      # 3 定义变量age = 18
    def fucn2():  # 4 定义一个函数fucn2
        age = 20  # 6 执行函数 age=20 (局部命名仅限fucn2函数中)
    fucn2()       # 5 调用函数fucn2 
    print(age)    # 7 打印 fucn函数体内age  #18 
fucn()           # 2 调用函数fucn代码体

def fucn():
    age = 18
    def fucn2():
        nonlocal age  #使用nonlocal方法,可以更改外层局部空间数据
        age = 20      # 更改了函数fucn中的数据
    fucn2()
    print(age)       # 20  
fucn()

函数名的多种用法

函数名其实也是类似一个变量名,只是一个名字和一个内存地址的链接,该地址内存放的不是数据值而是一端代码,当使用函数名后面加上()时 则会通过这个名字找到这段代码并执行
1.函数名可以用来给变量名赋值
def func():
  name = 'moon'
res = func     # 把函数名func绑定的内存地址 赋予了变量名 res
res()
print(res)

2.可以当做函数的实参
def func():
    print('moon')
def func2(func):    
    print('god')  #god
    print(func)  # 打印函数 func的绑定地址
func2(func)  #把函数名func作为实参传入 func2函数里

3.可以当做函数的返回值
def func()
    print('func')
def func1()
    print('func1')
    return func   #此函数体代码立刻运行完毕,返回 func变量名的内存地址
res = func1()  #func1返回值 func的地址 赋值给 res
print(res)  # func函数的绑定地址
res()   #func  调用res等于调用func


4.函数名也可以当做是容器类型,可以放在字典中
def register():
   	print('注册功能')
def login():
   	print('登录功能')
func_dict = {'1':register,'2':login}    # 函数名被当做字典的值来处理
choice = input('请选择要执行的功能>>>')
if choice in func_dict  
   func_dict.get(choice)()    # 如果用户输入的在功能字典中
   #则调取 功能字典中键对应的值的函数地址 ()并运行
 else:
   print('功能不存在')

闭包函数

1,什么是闭包函数?
在函数体内部的函数,并且用到了外部函数名称空间中的名字
需要满足,定义在函数体内   并且 用到了外部函数名称空间中的名字

代码展示:
def func():
  a = 1
  b = 2
  def func2():
    print(a+b)  #定义在函数体内   并且 用到了外部函数名称空间中的名字
  func2()
func() # 3

2,闭包函数实际应用
 给另外一种函数体代码传参的方式
2.1方式1:代码里面缺什么变量名形参里面就补什么变量名
  def func(a,b):
  a = a
  b = b
  def func2():
    print(a+b)  #定义在函数体内   并且 用到了外部函数名称空间中的名字
  func2()
func(1,2) # 3
func(1,2)
func(1,2)

2.2闭包函数传参
def func(a, b):  # 执行1  先定义一个函数
    def func2():  
        print(a + b)
    return func2   # 执行3 被调用看返回值 返回值是func2 
res = func(2,3)   # 执行2  先看右边 调用函数  func2被赋值给res
res()  #5     执行res 等于执行 func2  所以等于5
res()  #5
res = func(3,3)  
res()  #6
res()  #6 

装饰器简介

1,装饰器的概念
在!不改变被装饰对象的源代码!和!调用方式!的情况下给被装饰的对象添加新的功能
2.本质
是由 函数参数 加上 名称空间 函数名多种用法 闭包函数技术的组合产生的
3.口诀
  对修改封闭 对扩展开发
4,装饰器的推导流程
import time
def index():
    time.sleep(3)
    print('from index')
def home():
    time.sleep(1)
    print('from home')
--------现在如果我们想在 index函数体代码前后添加代码-------
start_time = time.time()
index()
end_time = time.time()
print('函数index的执行时间为>>>:', end_time-start_time)
--------现在如果这段代码需要在不同地方反复使用 我们再把他们包装成函数-------
def get_time():
   start_time = time.time()
   index()
   end_time = time.time()
   print('函数index的执行时间为>>>:', end_time-start_time)
get_time()

--------现在如果这段代码需要在不同地方反复使用 并且是不同的函数体-------
def get_time(xxx): #设置一个形参
   start_time = time.time()
   xxx()   #这样就可以根据不同传参 这里的函数也会更改
   end_time = time.time()
   print('函数index的执行时间为>>>:', end_time-start_time)
get_time(index)
get_time('其他实参') # 这样也就可以实现 同样的功能对不同的实参是实施

------------更加完善一点,加上闭包函数的功能---------------
def outer(xxx):
	def get_time():
     start_time = time.time()
     xxx()   #这里的xxx其实就是对应形参的xxx 因为局部空间没有这个就会在外层找
     end_time = time.time()
     print('函数index的执行时间为>>>:', end_time-start_time)
  return get_time
res = outer(index)  # 这里就是用res来接受这个闭包变量名(index) 的返回值
# 先执行outer函数体,实参为index函数,这个函数体返回值为 get_time函数,所以现在
#  res = get_time  实参为 index
res() 

------------更加完善一点,如果传递的函数本身还有形参---------------
import time
def index(a):
  	print(a)
    time.sleep(3)
    print('from index')
def home(a,b):
    time.sleep(1)
    print('from home')

def outer(xxx):  #形参被传入实参 被装饰函数
	def get_time(a):
     start_time = time.time()
     xxx(a)    #局部空间没有,向外找,找到了 是index 但是这个函数需要有传参 他的传参哪里找。可以通过get_time的形参去获取,
     end_time = time.time()
     print('函数index的执行时间为>>>:', end_time-start_time)
  return get_time
res = outer(index)  # 给被装饰函数outer传参 index 然后returun了 get_time 给了 res
res(a)    # res传参等于 给get_time传参  为什么要给get_time传参 因为内部函数体index需要参数。
#所以这个代码就成功运行了

------------更加完美,被装饰函数不确认有多少传参---------------

def outer(xxx):  #形参被传入实参 被装饰函数
	def get_time(*regs,**wregs): # 更加完善,这里可以接受任意的数据
     start_time = time.time()
     xxx(*regs,**wregs)     #也是可以接收任意的数据
     end_time = time.time()
     print('函数index的执行时间为>>>:', end_time-start_time)
  return get_time
res = outer(index)  
res(a,2,2,3,2)  


------------被装饰函数如果有返回值---------------

import time
def index(*args):
    print(args)
    time.sleep(2)
    print('from index')
    return '我是index'
def moon(a,b):
    time.sleep(1)
    print('from MOON')
    return '我是moon'
def outer(xxx):
    def get_time(*args,**kwargs):
        start_time = time.time()
        res = xxx(*args,**kwargs)  #这里使用了res来接受这个函数体的返回值
        end_time = time.time()
        print('函数index的执行时间为>>>:', end_time - start_time)
        return res   #这里证明get_time代码运行接受返回值为 res
    return get_time


res = outer(moon) 
print(res(123,222)) #成功运行


装饰器固定模板

def 装饰器函数名(被装饰函数名):
  def inner(*args,**kwargs):
    #执行被装饰对象 之前可以做的额外操作
    res = 被装饰函数名(*args,**kwargs)
    #执行被装饰对象之后可以做的额外操作
    return res
  return inner

装饰器语法糖

def outer(func_name):
  def inner(*args,**kwargs):
    #执行被装饰对象 之前可以做的额外操作
    res = func_name(*args,**kwargs)
    #执行被装饰对象之后可以做的额外操作
    return res
  return inner

@outer      # 这个代表  func = outer(func)
def func():
  print('im func')
  return 'func'

#注意一定要紧挨被装饰的函数, 会自动已被装饰函数名 来接收装饰后的结果

标签:函数,python,res,初级,func,time,print,装饰,def
From: https://www.cnblogs.com/moongodnnn/p/16782716.html

相关文章

  • (Python)email 邮件发送
    """1.发送邮件的几个步骤:1)与邮件服务器建立会话连接2)指定用户的登录3)发送邮件2.一个标准邮件包含:1)邮件头:标题;收件人、发送人、抄送cc、密送bcc......
  • 装饰器推导
    importtimedefindex():time.sleep(3)print('fromindex')defhome():time.sleep(1)print('fromhome')'''1.直接在调用index函数的前后添加代......
  • 闭包函数与装饰器
    昨日内容回顾函数的参数位置参数 分为位置形参和位置实参,位置形参与实参数量要一致,使用关键字传参可改变赋值顺序。默认参数 函数定义阶段赋有默认值的参数,传参时可不......
  • 【python】ERA5逐小时降水数据计算逐日降水
    自用简单方法参考代码:ERA5:Howtocalculatedailytotalprecipitation-CopernicusKnowledgeBase-ECMWFConfluenceWiki1、先从官网(ERA5-Landhour......
  • 函数之装饰器
    global与nonlocal1.局部名称空间直接修改全局名称空间中的数据money=123defindex():globalmoneymoney=222index()print(money)2.内层局部名称空间修......
  • 函数(三)——闭包函数与装饰器
    一、函数名的多种用法函数名其实绑定的是一块内存地址,只不过该地址里面存放的不是数据值而是一段代码,函数名加括号就会找到该代码并执行。1. 可以当做变量名赋值defi......
  • 函数剩余内容/函数装饰器
    目录今日内容概要1.global与nonlocal用法2.函数名的多种用法3.闭包函数4.装饰器介绍5.装饰器原理推导过程6.装饰器模板7.装饰器语法糖练习题及答案今日内容概要global和......
  • 闭包函数与装饰器
    今日内容总结global与nonlocalmoney=666defindex():globalmoneymoney=123index()print(money)"""局部名称空间直接修改全局空间中的数据"""......
  • Python之斐波那契数列的实现
    1.斐波那契数列的概念斐波那契数列(Fibonaccisequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(LeonardoFibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这......
  • 函数装饰器
    目录内容概要内容详解global与nonlocal函数名的多种用法闭包函数装饰器简历装饰器推导流程装饰器模板装饰器语法糖内容概要global与nonlocal函数名的多种用法闭包......