首页 > 其他分享 >函数与装饰器

函数与装饰器

时间:2022-10-11 21:00:06浏览次数:33  
标签:index 函数 func time print 装饰 def

目录

global与nonlocal

1 global关键字:
在函数中,如果想给全局变量赋值,则需要用关键字global声明。
eg:
money = 666
def index():
    global money
    money = 123
index()
print(money)#123
2 nonlocal关键字:
nonlocal只能在封装函数中使用,在外部函数先进行声明,在内部函数进行nonlocal声明
def index():
    name = 'jason'
    def inner():
        nonlocal name
        name = 'kevin'
    inner()
    print(name)
index()

函数名的多种用法

函数名其实绑定的也是一块内存地址 只不过该地址里面存放的不是数据值而是一段代码 函数名加括号就会找到该代码并执行.
1.函数名可以当作变量名赋值
def index():pass
res = index
res()
2函数名可以当作函数的参数
def index():
    print('from index')
def func(a):
    print(a)
    a()
func(index)
3函数名可以当作函数返回值
def index():
    print('from index')
def func():
    print('from func')
    return index
res = func()
print(res)
res()
4函数名可以当做容器类型(可以存放多个数据的数据类型)的数据。
def reginster():
    print('注册功能')
def login():
    print('登录功能')
def withdraw():
    print('提现功能')
def transfer():
    print('转账功能')
def shopping():
    print('购物功能')
#定义功能编号与功能的对应关系
fun_dict={
    '1':reginster,
    '2':login,
    '3': withdraw,
    '4': transfer,
    '5': shopping
}
while 1:
    print("""
        1.注册功能
        2.登录功能
        3.提现功能
        4.转账功能
        5.购物功能
    """)
    choice =input('>>>:').strip()
    if choice in fun_dict:
        fun_name=fun_dict.get(choice)
        fun_name()
    else:
        print('功能编号不存在')

函数闭包

基于函数对象的概念,可以将函数返回到任意位置去调用,但作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关。 
定义在函数内部的函数 并且用到了外部函数名称空间中的名字
	1.定义在函数内容
	2.用到外部函数名称空间中的名字
def index():
    name = 'jason'
    def inner():
        print(name)
两种为函数体传值的方式,一种是直接将值以参数的形式传入,另外一种就是将值包给函数.
方式1:
def register(name,age):
    print(f"""
    姓名:{name}
    年龄:{age}
    """)
register('jason', 18)
register(name='jason', age=18)
方式2:
def outer(name, age):
    # name = 'jason'
    # age = 18
    def register():
        print(f"""
           姓名:{name}
           年龄:{age}
           """)
    return register
res = outer('jason', 18)
res()
res = outer('kevin', 28)
res()

装饰器简介

1.概念
装饰器就是在不修改被装饰器对象源代码以及调用方式的前提下为被装饰对象添加新功能。
2本质
装饰器指的定义一个函数,该函数是用来为其他函数添加额外的功能.就是拓展原来函数功能的一种函数
3口诀
	对修改封闭 对扩展开放
4操作
时间相关操作
import time
print(time.time())#1665478515.6596327时间戳:距离1970-01-01 00:00:00所经历的秒数
time.sleep(3)
print('123321')
count = 0
start_time=time.time()
while count<500:
    print('qqqq')
    count += 1
end_time =time.time()
print('循环消耗的时间:', end_time - start_time)

装饰器推导流程

1直接在调用index函数后面添加后代
import time
def index():
    time.sleep(3)
    print('from index')
def home():
    time.sleep(1)
    print('from home')
start_time = time.time()
index()
end_time = time.time()
print('函数index的执行时间为>>>:', end_time-start_time)
2index调用的地方较多 代码不可能反复拷贝>>>:相同的代码需要在不同的位置反复执行>>>:函数
import time
def index():
    time.sleep(3)
    print('from index')
def home():
    time.sleep(1)
    print('from home')
def get_time():
    start_time = time.time()
    index()
    end_time = time.time()
    print('函数index的执行时间为>>>:', end_time - start_time)
get_time()
3..函数体代码写死了 只能统计index的执行时间 如何才能做到统计更多的函数运行时间 直接传参变换统计的函数
import time
def index():
    time.sleep(3)
    print('from index')
def home():
    time.sleep(1)
    print('from home')
def get_time(xxx):
    start_time = time.time()
    xxx()
    end_time = time.time()
    print('函数的执行时间为>>>:', end_time - start_time)
get_time(index)
get_time(home)
4.虽然实现了一定的兼容性 但是并不符合装饰器的特征  第一种传参不写 只能考虑闭包
import time
def index():
    time.sleep(3)
    print('from index')
def home():
    time.sleep(1)
    print('from home')
def outer(xxx):
    xxx = index
    def get_time():
        start_time = time.time()
        xxx()
        end_time = time.time()
        print('函数的执行时间为>>>:', end_time - start_time)
    return get_time
res = outer(index)
res()
res1 = outer(home)
res1()
5.调用方式还是不对 如何变形>>>:变量名赋值绑定
import time
def index():
    time.sleep(3)
    print('from index')
def home():
    time.sleep(1)
    print('from home')
def outer(xxx):
    def get_time():
        start_time = time.time()
        xxx()
        end_time = time.time()
        print('函数的执行时间为>>>:', end_time - start_time)
    return get_time
res = outer(index)  # 赋值符号的左边是一个变量名 可以随意命名
res1 = outer(index)
res2 = outer(index)
jason = outer(index)
index = outer(index)
index()
home = outer(home)
home()
6.上述装饰器只能装饰无参函数 兼容性太差
import time
def func(a):
    time.sleep(0.1)
    print('from func', a)

def func1(a,b):
    time.sleep(0.2)
    print('from func1', a, b)

def func2():
    time.sleep(0.3)
    print('from func2')
func(123)
def outer(xxx):
    def get_time(a, b):
        start_time = time.time()
        xxx(a, b)
        end_time = time.time()
        print('函数的执行时间为>>>:', end_time - start_time)
    return get_time
func1 = outer(func1)
func1(1, 2)
func = outer(func)
func(1)
func2 = outer(func2)
func2()
7.被装饰的函数不知道有没有参数以及有几个参数 如何兼容
import time
def func(a):
    time.sleep(0.1)
    print('from func', a)
def func1(a,b):
    time.sleep(0.2)
    print('from func1', a, b)
def outer(xxx):
    def get_time(*args, **kwargs):  # get_time(1,2,3)  args=(1,2,3)
        start_time = time.time()
        xxx(*args, **kwargs)  # xxx(*(1,2,3))    xxx(1,2,3)
        end_time = time.time()
        print('函数的执行时间为>>>:', end_time - start_time)
    return get_time
func = outer(func)
func(123)
func1 = outer(func1)
func1(1, 2)
8.如果被装饰的函数有返回值
import time
def func(a):
    time.sleep(0.1)
    print('from func', a)
    return 'func'
def func1(a,b):
    time.sleep(0.2)
    print('from func1', a, b)
    return 'func1'
def outer(xxx):
    def get_time(*args, **kwargs):
        start_time = time.time()
        res = xxx(*args, **kwargs)
        end_time = time.time()
        print('函数的执行时间为>>>:', end_time - start_time)
        return res
    return get_time
func = outer(func)
res = func(123)
print(res)       

装饰器模板

在特定条件下为某些函数再不改动函数体的时候为函数新添加一些功能,这就是装饰器
# 务必掌握 
def outer(func):
    def inner(*args, **kwargs):
        # 执行被装饰对象之前可以做的额外操作
        res = func(*args, **kwargs)
        # 执行被装饰对象之后可以做的额外操作
        return res
    return inner

装饰器语法糖

\@是一个装饰器,针对函数,起调用传参的作用。
有修饰和被修饰的区别,作为一个装饰器,用来修饰紧跟着的函数(可以是另一个装饰器,也可以是函数定义)。
def outer(func_name):
    def inner(*args, **kwargs):
        print('执行被装饰对象之前可以做的额外操作')
        res = func_name(*args, **kwargs)
        print('执行被装饰对象之后可以做的额外操作')
        return res
    return inner
"""
语法糖会自动将下面紧挨着的函数名当做第一个参数自动传给@函数调用
"""
@outer  # func = outer(func)
def func():
    print('from func')
    return 'func'
@outer  # index = outer(index)
def index():
    print('from index')
    return 'index'
func()
index()

作业

'''编写一个用户认证装饰器
  函数:register login transfer withdraw 
  基本要求
   	 执行每个函数的时候必须先校验身份 eg: jason 123
  拔高练习(有点难度)
   	 执行被装饰的函数 只要有一次认证成功 那么后续的校验都通过
  提示:全局变量 记录当前用户是否认证'''

a=1
def outer(func):
    def inner(*args,**kwargs):
        global a
        while a:
            name=input('name')
            pwd=input('pwd')
            if name=='jason'and pwd=='123':
                a=0
                res=func(*args,**kwargs)
                return res
            else:
                print('cuowu')
        else:
            res= func(*args,**kwargs)
            return res
    return inner

@outer
def register():
    print('from register')
@outer
def login():
    print('from login')
@outer
def transfer():
    print('from transfer')
@outer
def withdraw():
    print('from withdraw')





register()
login()
transfer()
withdraw()

标签:index,函数,func,time,print,装饰,def
From: https://www.cnblogs.com/bnmm/p/16782549.html

相关文章

  • 函数对象与闭包函数与装饰器
    目录一.global与nonlocal二.函数名的多种用法1.可以当做变量名赋值2.可以当做函数的参数3.可以当做函数的返回值4.可以当做容器类型的数据三.闭包函数四.装饰器1.装饰器简......
  • python基础之闭包函数与装饰器
    python基础之闭包函数与装饰器目录一、global与nonlocal二、函数名的多种用法1.可以当变量名2.可以当函数的参数3.可以当函数的返回值三、闭包函数1.闭包函数的实际应用四......
  • 装饰器
    1.global与nonlocal1.global:局部名称空间修改全局名称空间的数据n=100defindex():globalnn=999index()print(n)#9992.nonlocal:内层局部名......
  • C语言-函数
    1:函数的概念函数是一个命名了的代码块,我们通过调用函数执行相应的代码,函数可以有0个或者多个参数,而且会产生一个结果对于我的总结:我觉得函数可以说是一个能够实现一定功......
  • python重点之装饰器
    global与nonlocal函数名的多种用法闭包函数装饰器简介无参装饰器有参装饰器装饰器模板装饰器语法糖今日详细内容global与nonlocalmoney=666defind......
  • 函数(三)
    函数(三)global与nonlocal1.global的用法1.当不使用global时 number=89defindex(): number=34index()print(number)#89......
  • 装饰器、global与nonlocal
    目录global与nonlocal函数名的多种用法闭包函数装饰器简介装饰器推导流程装饰器模版装饰器语法糖作业global与nonlocalglobalmoney=666defindex():globalmone......
  • python进阶之路11 闭包函数 装饰器
    函数名的多种用法函数名其实绑定的也是一块内存地址只不过该地址里面存放的不是数据值而是一段代码函数名加括号就会找到该代码并执行1.可以当作变量名赋值defindex......
  • 函数名的用法,闭包函数与装饰器
    函数的多种用法与装饰器global与nonlocal1.global用在局部名称空间直接修改全局名称空间中的数据x=111deffunc():globalx#修改全局名称空间x值x=2......
  • hive窗口函数极速入门
    1over()窗口函数1.1语法结构分析函数over(partitionby列名orderby列名rowsbetween开始位置and结束位置)1.2over中的三个函数具体含义orderby:排序的意......