首页 > 其他分享 >函数(三)

函数(三)

时间:2022-10-11 20:33:05浏览次数:40  
标签:函数 res func time print def

函数(三)

global与nonlocal

1.global的用法

1.当不使用global时
	number = 89
    def index():
        
    	number = 34

    index()
    print(number)  # 89
        		
	
2.使用了global
	number = 89
    def index():
        global number
        number = 34
        
	index()
    print(number)  # 34
        
   """
      局部名称空间直接修改全局名称空间中的数据
   """

2.nonlocal的用法

1.当不使用nonlocal时
	def index():
        name = 'kiki'
        def inner():
        
            name = 'kimi'
        inner()
        print(name)  # kiki
    index()
	

2.当使用了nonlocal
    def index():
        name = 'kiki'
        def inner():
            nonlocal name
            name = 'kimi'
        inner()
        print(name)  # kimi
    index()

    """
    内层局部名称空间修改外层局部名称空间中的数据
    """

函数名的多种用法

​ 函数名其实绑定的也是一块内存地址,只不过该地址里面存在的不是数据值,而是一段代码,函数名加括号就会找到代码并执行。函数对象指的是可以被当作‘数据’来处理,具体可分为四个方面的使用

1.可以当作变量名赋值

    def index():
        pass

    res = index
    res()   # res() == index()
    print(res)  # <function index at 0x00000213D09461F0>

2.可以当做函数的参数

    def index():
        print('今天是10月11号')
    def func(a):
        print(a)  # a=index  <function index at 0x000002CCA40E61F0>
        a()  # a()==index()   直接调用index()  输出 ‘今天是10月11号’
    func(index)

3.可以当作函数的返回值

1.返回值返回第一个函数名

    def index():
        print('天气晴')

    def func():
        print('适合出门')
        return index

    res = func()   # 第一步看赋值的右边,调用func()函数输出‘适合出门’,返回index函数名给res
    print(res)  # 打印出index的函数名的内存地址  <function index at 0x0000028E8C7361F0>
    res()  # res() == index()   直接调用index()函数,输出‘天气晴’

2.返回值返回第二个函数名
    def index():
        print('天气晴')

        def func():
            print('适合出门')
        return func

    res = index()   # 第一步看赋值的右边,调用index()函数输出‘天气晴’,然后到return返回func
    print(res)  # 打印出func的函数名内存地址  <function index.<locals>.func at 0x000002876A56A4C0>
    res()  # res() == func()   直接调用func()函数,输出‘适合出门’

4.可以当作容器类型(可以存放多个数据的数据类型)的数据

​ 1.第一种方式----基础版


    def register():
        print('注册功能')

    def login():
        print('登录功能')

    def withdraw():
        print('提现功能')

    def transfer():
        print('转账功能')

    def shopping():
        print('购物功能')


    while True:
        print("""
        1.注册功能
        2.登录功能
        3.提现功能
        4.转账功能
        5.购物功能
        """)
        choice = input('please input your choice>>>:').strip()
        if choice == '1':
            register()
        elif choice == '2':
            login()
        elif choice == '3':
            withdraw()
        elif choice == '4':
            transfer()
        elif choice == '5':
            shopping()
        else:
            print('查无编号!!!!')
        
     

​ 2.第二种方式-----升级版

    def register():
        print('注册功能')

    def login():
        print('登录功能')

    def withdraw():
        print('提现功能')

    def transfer():
        print('转账功能')

    def shopping():
        print('购物功能')

    demo_dict = {
        '1':register,
        '2':login,
        '3':withdraw,
        '4':transfer,
        '5':shopping
    }


    while True:
        print("""
        1.注册功能
        2.登录功能
        3.提现功能
        4.转账功能
        5.购物功能
        """)
        choice = input('please input your choice>>>:').strip()
        if choice in demo_dict:
            # demo_dict.get(choice)()
            name = demo_dict.get(choice)
            name()
        else:
            print('查无编号')

闭包函数

定义在函数内部的函数,并且用到了外部函数名称空间中的名字

​ 1.定义在函数内部

​ 2.用到外部函数名称空间中的名字

    def demo():
        name = 'kiki'
        def inner():
            print(name)
    """   第二个函数里name用到了第一个函数name,称为闭包函数    """

闭包函数实际应用:是另外一种给函数体代码传参的方式

方式1:给函数体代码传参(代码里面缺什么变量名形参里面就补什么变量名)

    def stu_class(name,age):
        print(f"""
        姓名:{name}
        年龄:{age}
        """)
    stu_class('kimi',18)
    
    """ 这种方式,输入一次参数就打印出的结果只有一个"""

方式2:闭包函数

    def stu_class(name,age):
        # name = 'kiki'
        # age = 18
        def register():
            print(f"""
            姓名:{name}
            年龄:{age}
            """)
        return register
    res = stu_class('kiki',18)
    res()
    res()
    res = stu_class('kimi',20)
    res()
    res()

    """ 这种可以连续输出好几个信息"""
    对比信息图如下

解析步骤如下:

image

对比信息图如下

image

装饰器

​ 引入

​ 软件的设计应该遵循开放封闭原则,即是对扩展是开放的,而对修改时封闭的,软件包含的所有功能的源代码以及调用方式,都应该避免修改,否则一旦改错,则极有可能产生连锁反应,最终导致程序崩溃。对于新上线的软件,我们可能要对客户的新需求或者变化,对程序提供扩展的可能性,这就用到了装饰器

装饰器简介

1.概念

​ 在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能

2.本质

​ 并不是一门新的技术,而是由函数参数、名称空间、函数名多种用法、闭包函数组合到一起的结果

3.口诀

​ 对修改封闭、对扩展开放

4.储备知识

​ 时间相关操作

    import time
    # print(time,time())  #  时间戳(距离1970-01-01 00:00:00所经历的秒数)

    time.sleep(2)
    print('五点就到饭点了')


    count = 0
    # 循环之前先获取时间戳
    start_time = time.time()
    while count<1000:
        print('赏心悦目')
        count += 10
    end_time = time.time()
    print('循环消耗的时间:',end_time - start_time)

5.应用场景

​ 用于有切面需求的场景,比如插入日志、性能测试、事务处理、缓存、权限校验等应用场景

装饰器推导过程

    import time

    def func():
        time.sleep(3)
        print('花花')
    def home():
        time.sleep(1)
        print('润玥')

  
"""  1.直接在调用func函数的前后添加代码     """

    start_time = time.time()
    func()  # 花花
    end_time = time.time()
    print('函数func的执行时间为>>:',end_time - start_time)  # 函数func的执行时间为>>: 3.01410174369812


""" 2.func调用的地方较多,代码不可能反复拷贝>>>>:相同的代码需要在不同的位置反复执行>>>:函数"""
    def get_time():
        start_time = time.time()
        func()
        end_time = time.time()
        print('函数func的执行时间为>>:', end_time - start_time)   # 函数func的执行时间为>>: 3.0112600326538086
    get_time()


""" 3.函数体代码写死了,只能统计func()的执行时间,如何才能做到统计更多的函数运行时间,直接传参变换统计的函数"""
    def get_time(xxx):
        start_time = time.time()
        xxx()
        end_time = time.time()
        print('函数func的执行时间为>>:', end_time - start_time)
    get_time(func)
    get_time(home)


"""4.虽然实现了一定的兼容性,但是并不符合装饰器的特征,第一种转参不写,只能考虑闭包"""
    def get_time(xxx):
        # xxx = index
        def outer():
            start_time = time.time()
            xxx()
            end_time = time.time()
            print('函数func的执行时间为>>:', end_time - start_time)
        return outer

    res = get_time(func)
    res()
    res1 = get_time(home)
    res1()


""" 5.调用方式还是不对,如何变形>>>:变量名赋值绑定(***********)"""
    def outer(xxx):
        def get_time():
            start_time = time.time()
            xxx()
            end_time = time.time()
        return get_time

    res = outer(func)  # 赋值符号的左边是一个变量名,可以随意命名
    res1 =outer(func)
    kiki = outer(func)
    func =outer(func)
    home = outer(home)
    home()


"""6.上述装饰器只能装饰无参函数,兼容性太差"""
    def func1(a):
        time.sleep(1)
        print('艾玖', a)

    def func2(a, b):
        time.sleep(2)
        print('福宝', a, b)

    def func3():
        time.sleep(3)
        print('和叶')

    func1(123) #  艾玖 123
    def outer(xxx):
        def get_time(a, b):
            start_time = time.time()
            xxx(a, b)
            end_time = time.time()
            print('函数func的执行时间为>>:', end_time - start_time)
        return  get_time

    func2 = outer(func2)
    func2(120,119)  # 福宝 120 119
    func1 = outer(func1)
    func1(120)  # 艾玖 123
    func3 = outer(func3)
    func3()  # get_time() missing 2 required positional arguments: 'a' and 'b'


"""7.被装饰的函数不知道有没有参数以及几个参数,如何兼容"""
    def func1(a):
        time.sleep(1)
        print('艾玖', a)

    def func2(a, b):
        time.sleep(2)
        print('福宝', a, b)

    def outer(xxx):
        def get_time(*args,**kwargs):
            start_time = time.time()
            xxx(*args,**kwargs)
            end_time = time.time()
            print('函数的执行时间为>>>:',end_time - start_time)
        return get_time

    func1 = outer(func1)
    func1(120)  # 艾玖 120

    func2 = outer(func2)
    func2(120,119)  # 福宝 120 119



"""8.如果被装饰的函数有返回值"""

    def func1(a):
        time.sleep(1)
        print('艾玖', a)
        return 'func1'

    def func2(a, b):
        time.sleep(2)
        print('福宝', a, b)
        return 'func2'

    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

    func1 = outer(func1)
    res = func1(120)  # 艾玖 120
    print(res)  # func1

    func2 = outer(func2)
    res = func2(119, 120)  # 福宝 119 120
    print(res)    # func2


解读步骤如图
image

装饰器模板

重点掌握:

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

装饰器语法糖

"""装饰器语法糖,语法糖会自动将下面紧挨着的函数当作第一个参数自动传给@函数调用"""
    def outer(func):
        def inner(*args,**kwargs):
            print('执行被装饰对象之前可以做的额外操作')
            res = func(*args,**kwargs)
            print('执行被装饰对象之后可以做的额外的操作')
            return res
        return inner

    @outer
    def func():
        print('和叶')
        return 'func'

    @outer
    def func1():
        print('和花')
        return 'func1'

    func()
    func1()

作业

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

标签:函数,res,func,time,print,def
From: https://www.cnblogs.com/zhanglanhua/p/16782457.html

相关文章

  • 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:排序的意......
  • 函数装饰器
    global与nonlocalmoney=666defindex():globalmoneymoney=123index()print(money)"""局部名称空间直接修改全局名称空间中的数据"""defindex(......
  • wordpress 开发相关函数
    首页判断is_home()is_front_page()当你的首页不是默认的index.php的时候,而是在后台指定了一个page页面。这种情况下is_home()会失效,也就是说这样子的情况下就不能再用is......
  • 函数名的多种用法及装饰器
    目录global与nonlocal函数名的多种用法闭包函数装饰器简介装饰器推导流程装饰器模板装饰器语法糖作业global与nonlocalmoney=666defindex():globalmoneym......
  • mysql 时间函数
    时间格式转换标准时间格式:2017-05-1211:41:55--字符串转换为日期函数:str_to_date(str,format)SELECTSTR_TO_DATE('06.05.201719:40:30','%m.%d.%Y%H:%i:%s');--......
  • Phoenix不支持having函数的情况(举例)
     同一sql语句,在mysql可以查询成功,查询出最大“平均值”,以及对应的sno;在Phoenix会报错,提示sno不属于聚和函数也不在groupby里面,aggregatemaynotcontainscolumnsnot......
  • qt 容器 函数指针
    private:typedefvoid(MainWindow::*pfunc)();QHash<QString,pfunc>func_map_enter;voidMainWindow::init_qmap(void){func_map_enter.insert("page_n......
  • python中items()函数作用
    参考链接:https://www.runoob.com/python3/python3-att-dictionary-items.htmlhttps://blog.csdn.net/weixin_43505418/article/details/115407835......