首页 > 编程语言 >python第十三课---

python第十三课---

时间:2022-10-12 18:36:21浏览次数:45  
标签:index return 第十三 python --- func time print def

昨日内容回顾

  • global与nonlocal关键字

    global
    	用于局部名称空间修改全局名称空间中的名字绑定关系
    nonlocal
    	用于局部名称空间修改外层局部名称空间中的名字绑定关系
    
  • 函数名的多种用法

    1.函数名可以当做变量名被赋值
    	def index():
            print('from index')
    	res = index
        
    2.函数名可以当做函数的实参
    	def func(a):
            print(a)
     	func(123)  # a = 123
     	func(index)  # a = index
        
    3.函数名可以当做函数的返回值
    	def foo():
    		def inner():
                print('from inner')
           return inner
    	res = foo()  # res = inner
     
    4.函数名还可以当做容器类型的数据值
    	func_dict = {'1':index,'2':func}
    
  • 闭包函数

    1.定义在函数内部的函数
    2.使用了外部函数名称空间中的名字
    def inner(name):
        print(name)
    
        
    def outer(name):  # name = 'jason'
        def inner():
            print(name)
        return inner
    res = outer('jason')  # res = inner
    res()  # inner()
    
  • 装饰器前戏

    1.不改变被装饰对象源代码
    2.不改变被装饰对象调用方式
    给被装饰对象添加新的功能
    
    时间相关操作
    	import time
    	time.time()
    	time.sleep()  	
    
  • 装饰器推导流程

    1.统计函数的执行时间
    	def index():
            print('from index')
     	start_time = time.time()
    	index()
     	print(time.time() - start_time)
    2.由于index函数可能需要在很多地方执行 代码反复编写不好 考虑封装成函数
    	def get_time():
            start_time = time.time()
            index()
            print(time.time() - start_time)
    3.上述代码只能统计index函数的执行时间 局限性太强 应该让该名字动起来
    	def get_time(xxx):
            start_time = time.time()
            xxx()
            print(time.time() - start_time)
    4.上述直接封装形参传值不写 所以只能考虑闭包函数	
    	def outer(xxx):
            def get_time(a):
                start_time = time.time()
                xxx(、、、、、、、、、、、、)
                print(time.time() - start_time)
            return get_time
    	res = outer(index)  # res = get_time 
      	index = outer(index)  # index = get_time
     	index()
    5.上述装饰器只能装饰无参函数兼容性不好
    	def func(a):
            print('from func', a)
     	func(123)  # 正确
      	func = outer(func)
     	func(123)  # 报错
     	推导可得被装饰的函数需要几个参数get_time就应该加几个参数
    	def outer(xxx):
            def get_time(*args, **kwargs):
                start_time = time.time()
                xxx(*args, **kwargs)
                print(time.time() - start_time)
            return get_time
    6.被装饰对象返回值无法获取
    	def outer(xxx):
            def get_time(*args, **kwargs):
                start_time = time.time()
                ret = xxx(*args, **kwargs)
                print(time.time() - start_time)
                return ret
            return get_time
    	func = outer(func)
     	res = func(123)
    
  • 装饰器模板

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

    @outer  # register = outer(register)
    def register():
        pass
    @outer  # login = outer(login)
    def login():
        pass
    
    register()
    login()
    """
    自动将紧挨着语法糖下面的名字当做参数传递给@后面的函数并调用
    """
    

今日内容概要

  • 作业讲解
  • 多层语法糖问题
  • 有参装饰器
  • 装饰器修复技术
  • 递归函数
  • 算法之二分法

今日内容详细

作业讲解

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

# 定义一个变量记录用户的登录状态
is_login = False


def login_auth(func_name):
    def inner(*args, **kwargs):
        global is_login
        # 先判断全局名称空间中的变量名is_login绑定的值是否为True
        if is_login:
            res = func_name(*args, **kwargs)
            return res
        username = input('username>>>:').strip()
        password = input('password>>>:').strip()
        if username == 'jason' and password == '123':
            # 将全局名称空间中记录用户登录状态的数据值该为True
            is_login = True
            res = func_name(*args, **kwargs)
            return res
        else:
            print('用户名或密码错误无法执行函数')
    return inner


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


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


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


register()
login()
shopping()

多层语法糖

def outter1(func1):
    print('加载了outter1')
    def wrapper1(*args, **kwargs):
        print('执行了wrapper1')
        res1 = func1(*args, **kwargs)
        return res1
    return wrapper1

def outter2(func2):
    print('加载了outter2')
    def wrapper2(*args, **kwargs):
        print('执行了wrapper2')
        res2 = func2(*args, **kwargs)
        return res2
    return wrapper2

def outter3(func3):
    print('加载了outter3')
    def wrapper3(*args, **kwargs):
        print('执行了wrapper3')
        res3 = func3(*args, **kwargs)
        return res3
    return wrapper3


@outter1
@outter2
@outter3
def index():
    print('from index')
    
"""
多层语法糖 加载顺序由下往上
每次执行之后如果上面还有语法糖 则直接将返回值函数名传给上面的语法糖
如果上面没有语法糖了 则变形 index = outter1(wrapper2)
"""

有参装饰器

# 校验用户是否登录装饰器
def outer(mode):
    def login_auth(func_name):
        def inner(*args, **kwargs):
            username = input('username>>>:').strip()
            password = input('password>>>:').strip()
            if mode == '1':
                print('数据直接写死')
            elif mode == '2':
                print('数据来源于文本文件')
            elif mode == '3':
                print('数据来源于字典')
            elif mode == '4':
                print('数据来源于MySQL')
        return inner
    return login_auth
'''当装饰器中需要额外的参数时>>>:有参装饰器'''

"""
函数名加括号执行优先级最高 有参装饰器的情况 
    先看函数名加括号的执行
    然后再是语法糖的操作
"""
# @outer('1')
def index():
    print('from index')
index()

# @outer('2')
def func():
    print('from func')
func()

装饰器模板

# 最常用的无参装饰器
# def outer(func_name):
#     def inner(*args, **kwargs):
#         res = func_name(*args, **kwargs)
#         return res
#     return inner
# @outer
# def index():
#     pass

# 不常用的有参装饰器
# def outer_plus(mode):
#     def outer(func_name):
#         def inner(*args, **kwargs):
#             res = func_name(*args, **kwargs)
#             return res
#         return inner
#     return outer
# @outer_plus('MySQL')
# def func():
#     pass

装饰器修复技术

# def index():
#     """index函数 非常的牛"""
#     pass
# help(index)
# help(len)
from functools import wraps
def outer(func_name):
    @wraps(func_name)  # 仅仅是为了让装饰器的效果更加逼真 平时可以不写
    def inner(*args, **kwargs):
        """我是inner 我擅长让人蒙蔽"""
        res = func_name(*args, **kwargs)
        return res
    return inner

@outer
def func():
    """我是真正的func 我很强大 我很牛 我很聪明"""
    pass


# help(func)
# print(func)
func()

递归函数

1.函数的递归调用
	函数直接或者间接的调用了函数自身
 	 # 直接调用
    # def index():
    #     print('from index')
    #     index()
    # index()
    # 间接
    # def index():
    #     print('from index')
    #     func()
    #
    # def func():
    #     print('from func')
    #     index()
    #
    # func()
    '''最大递归深度:python解释器添加的安全措施'''
    # count = 0
    # def index():
    #     global count
    #     count += 1
    #     print(count)
    #     index()
    # index()
    '''官网提供的最大递归深度为1000 我们在测试的时候可能会出现996 997 998'''
    
2.递归函数
	1.直接或者间接调用自己
 	2.每次调用都必须比上一次简单 并且需要有一个明确的结束条件
		递推:一层层往下
  		回溯:基于明确的结果一层层往上
 	 """
    get_age(5) = get_age(4) + 2
    get_age(4) = get_age(3) + 2
    get_age(3) = get_age(2) + 2
    get_age(2) = get_age(1) + 2
    get_age(1) = 18
    """
    def get_age(n):
        if n == 1:
            return 18
        return get_age(n-1) + 2
    res = get_age(5)
    print(res)

作业

1.利用递归函数依次打印列表中每一个数据值
	l1 = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]
2.整理今日内容及博客
3.利用有参装饰器编写多种用户登录校验策略

标签:index,return,第十三,python,---,func,time,print,def
From: https://www.cnblogs.com/tengyifan888/p/16785532.html

相关文章

  • python基础--简单数据类型预览
    为了适应更多的使用场景,将数据划分为多种类型,每种类型都有各自的特点和使用场景,帮助计算机高效的处理和展示数据。(比如数字用于数学运算、字符串用于信息传递、页面文字展......
  • CSP-S模拟18
    再次模拟退役,最近心态又双叒叕有点炸。。。。实力确实也真不行A.最长反链猜结论,从大到小能选就选,然后打表发现能选与不能选有明显的分界,于是直接二分答案然后因为判断......
  • 150-《大数据架构师》Flink StreamTask 的逻辑执行和数据流转_ev
              超时时间策略          为了环境复用       ......
  • Python 为什么能支持任意的真值判断?
    Python在涉及​​真值判断​​​(​​TruthValueTesting​​)时,语法很简便。比如,在判断某个对象是否不为None时,或者判断容器对象是否不为空时,并不需要显示地写出判断条件......
  • Python 为什么要在 18 年前引入布尔类型?且与 C、C++ 和 Java 都不同?
    花下猫语:在上一篇《​​Python为什么能支持任意的真值判断?​​》文章中,我们分析了Python在真值判断时的底层实现,可以看出Python在对待布尔值时,采用了比较宽泛的态度。......
  • Python 为什么会有个奇怪的“...”对象?
    在写上一篇《​​Python为什么要有pass语句?​​》时,我想到一种特别的写法,很多人会把它当成pass语句的替代。在文章发布后,果然有三条留言提及了它。所谓特别的写法就是......
  • 【机器学习实战学习笔记】之 2 k-近邻算法
    本学习笔记参考书目《机器学习实战》第二章。本章所有本书对应代码及数据集下载请点击(​​下载链接​​)。本文中博主自己写的代码如有需要,请点击(​​下载链接​​)。目录​​......
  • Java中fail-fast与fail-safe机制
    fail-fast快速失败一个线程在读取集合种的数据时,另外一个线程在修改集合会导致fail-fastArrayListHashMap具备此机制Map<Integer,String>map=newHash......
  • Python 哈希函数
    1.hashlib模块实现了许多不同安全散列和消息摘要算法的通用接口。包括FIPS安全哈希算法SHA1,SHA224,SHA256,SHA384和SHA512以及RSA的MD5算法。如果您需要adler32或crc32哈......
  • Python定时任务框架APScheduler
    原文:https://blog.csdn.net/kobepaul123/article/details/123616575在日常工作中,如果想要简化工作流程实现办公自动化,那么几乎有大半的功能模块都需要使用定时任务,例如定......