本章内容概要

1. 多层装饰器

2. 有参装饰器

3. 递归函数

4. 算法(二分法)

本章内容详解

1. 多层装饰器

1.1 什么是多层装饰器

多层装饰器是从下往上依次执行,需要注意的是,被装饰的函数名所指代的函数是一直被装饰器中的内层函数所取代。

1.2 语法糖的功能

会自动将下面紧挨着的函数名当做参数传递给@符号2后面的函数名(加括号调用)

1.3 代码讲解

def outter1(func1):  # 13.func1 = wrapper2函数名
print('加载了outter1') # 14.第三个打印
def wrapper1(*args, **kwargs):
print('执行了wrapper1')
res1 = func1(*args, **kwargs)
return res1
return wrapper1 # 15.返回wrapper1 def outter2(func2): # 9.func2 = wrapper3函数名
print('加载了outter2') # 10.第二个打印
def wrapper2(*args, **kwargs):
print('执行了wrapper2')
res2 = func2(*args, **kwargs)
return res2
return wrapper2 # 11.返回wrapper2 def outter3(func3): # 4.func3 = 真正的index函数
print('加载了outter3') # 5.第一个打印
def wrapper3(*args, **kwargs):
print('执行了wrapper3')
res3 = func3(*args, **kwargs)
return res3
return wrapper3 # 6.返回wrapper3 @outter1 # 12.index = outter1(wrapper2) 调用outter1 把 outter2参数传进去 上面没有语法糖 最后用被装饰的函数一样的名字接受函数
@outter2 # 8.wrapper2 = outter2(wrapper3) 调用outter2 把 outter3参数传进去
@outter3 # 7.wrapper3 = outter3(真正的index函数名) 传给@outter2
# 1.如果上面没有其他语法糖了同名的函数名赋值一下index = = outter3(把真正的index函数名传进去),
# 2.如果语法糖叠加在一起的话,只有到最后一步才会使用和真正装饰的和函数名一样的名字去赋值,如果不到最后一步)
# 3.函数名加括号执行优先级最高 先执行outter3
def index():
print('from index')
index()
# 多层语法糖解读顺序是先看语法糖有几个,然后再由下往上去看,遇到最后一个才会使用相同的变量名传给装饰器函数使用
# 语法糖三:wrapper3 = outter3(index),加载了outter3
# 语法糖二:wrapper2 = outter2(wrapper3),加载了outter2
# 语法糖一;index = outter1(wrapper2),加载了outter1
# 执行顺序就是:wrapper1>>>>>wrapper2>>>>>wrapper3
# 加载outer3>>>加载outer2>>>加载outer1>>>index()>>>运行wrapper1函数体代码>>>然后再执行outer2函数体代码>>>然后再执行wrapper3的函数体代码

2. 有参装饰器

2.1 什么是有参装饰器

是为装饰器提供多样功能选择的实现提供的,实现原理是三层闭包

2.2 代码讲解

初始代码

def login_auth(func_name):
def inner(*args, **kwargs):
username = input('username>>>:').strip()
password = input('password>>>:').strip()
if username == 'jason' and password == '123':
res = func_name(*args, **kwargs)
return res
else:
print('用户权限不够 无法调用函数')
return inner

实现:在装饰器内部可以切换多种数据来源 ,如 列表 ,字典 ,文档

def outer(condition,type_user):
def login_auth(func_name): # 这里不能再填写其他形参
def inner(*args, **kwargs): # 这里不能再填写非被装饰对象所需的参数
username = input('username>>>:').strip()
password = input('password>>>:').strip()
# 应该根据用户的需求执行不同的代码
if type_user =='jason':print('VIP')
if condition == '列表':
print('使用列表作为数据来源 比对用户数据')
elif condition == '字典':
print('使用字典作为数据来源 比对用户数据')
elif condition == '文件':
print('使用文件作为数据来源 比对用户数据')
else:
print('去你妹的 我目前只有上面几种方式')
return inner
return login_auth
@outer('列表','jason')
def index():
print('from index')
index()

3. 递归函数

3.1 什么是递归函数

编程语言中,函数直接或间接调用函数本身,则该函数称为递归函数。

3.2 代码讲解 递归调用:直接调用

def index():
print('from index')
index() index()

有返回值

也会报错,调用Python对象时超过最大递归深度

3.3 代码讲解 递归调用:间接调用

# 递归调用:间接调用
def index():
print('from index')
func() def func():
print('from func')
index() func()

有返回值

也会报错,调用Python对象时超过最大递归深度

3.4 python 中允许函数最大递归调用的次数

1. 官方给出的限制是1000 用代码去验证可能会有些许偏差(997 998...)

count = 0  # count = 1
def index():
print('from index')
global count
count += 1 # count = count + 1
print(count)
index()
index()

2. python 解释器获取递归最大次数

import sys
print(sys.getrecursionlimit()) # 1000 获取递归最大次数

3. 自定义递归递归最大次数

import sys
sys.setrecursionlimit(1500) # 自定义最大次数
print(sys.getrecursionlimit())

3.4 递归函数真正的应用场景

1. 递归函数真正的应用场景

递推:一层层往下寻找答案

回溯:根据已知条件推导最终结果

2. 递归函数
   1.每次调用的时候都必须要比上一次简单!
   2.并且递归函数最终都必须要有一个明确的结束条件!

3. 讲解  **空列表自动结束

l1 = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]]
# 循环打印出列表中所有的数字
# 1.for循环l1里面所有的数据值
# 2.判断当前数据值是否是数字 如果是则打印
# 3.如果不是则继续for循环里面所有数据值
# 4.判断当前数据值是否是数字 如果是则打印
# 5.如果不是则继续for循环里面所有数据值
# 6.判断当前数据值是否是数字 如果是则打印 def get_num(l1):
for i in l1:
if isinstance(i,int):
print(i)
else:
get_num(i)
get_num(l1)

4. 算法(二分法)

4.1 什么是算法  算法就是解决问题的方法

算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间,空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。

二分法 快拍 插入 堆排 链表 双向链表 约瑟夫问题

4.2 什么是二分法

二分法是所有算法里面最简单的算法,是一种非常高效的算法,它常常用于计算机的查找过程中

4.3 二分法场景应用代码讲解

在列表l1中,找到999,该列表无限长,简洁的取少部分

l1 = [11, 23, 32, 45, 65, 78, 90, 123, 432, 467, 567, 687, 765, 876, 999, 1131, 1232]

def get_num(l1, target_num):
# 添加递归函数的结束条件
if len(l1) == 0:
print('不好意思 找不到')
return
# 1.先获取数据集中间那个数
middle_index = len(l1) // 2
middle_value = l1[middle_index]
# 2.判断中间的数据值与目标数据值孰大孰小
if target_num > middle_value:
# 3.说明要查找的数在数据集右半边 如何截取右半边
right_l1 = l1[middle_index + 1:]
# 3.1.获取右半边中间那个数
# 3.2.与目标数据值对比
# 3.3.根据大小切割数据集
# 经过分析得知 应该使用递归函数
print(right_l1)
get_num(right_l1, target_num)
elif target_num < middle_value:
# 4.说明要查找的数在数据集左半边 如何截取左半边
left_l1 = l1[:middle_index]
# 4.1.获取左半边中间那个数
# 4.2.与目标数据值对比
# 4.3.根据大小切割数据集
# 经过分析得知 应该使用递归函数
print(left_l1)
get_num(left_l1, target_num)
else:
print('找到了', target_num) get_num(l1, 999)

4.4 二分法的缺陷

1. 数据集必须是有序的

2. 查找的数如果在开头或者结尾 那么二分法效率更低(for 循环)

作业

1.尝试编写有参函数将多种用户验证方式整合到其中

直接获取用户数据比对
数据来源于列表 数据来源于文件

2.尝试编写递归函数

推导指定某个人的正确年龄
eg: A B C D E 已知E是18 求A是多少

l1 = ['A', 'B', 'C', 'D', 'E']
index = 0
def get_age():
global index
if l1[index] == 'E':
return 18
else:
index += 1
age = get_age() - 1
return age
age = get_age()
print(age)

3.自行查阅资料 提前收集常见算法快排 插入 冒泡等

3.1 快排

快排 全名 快速排序算法
快速排序(QuickSort)是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1962年提出。

它的基本思想是:
1. 从要排序的数据中取一个数为“基准数”。
2. 通过一趟排序将要排序的数据分割成独立的两部分,其中左边的数据都比“基准数”小,右边的数据都比“基准数”大。
3. 然后再按步骤2对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
该思想可以概括为:挖坑填数 + 分治法。分治法(分而治之)

3.2 插入

插入算法是一种排序算法

在运用插入算法时一般将数据分为两组,有序组和无序组,并且将数据的第一个元素默认为有序组,将无序组的元素一个一个按照某种排列方式插入到有序组中。

3.3 冒泡

冒泡算法是一种经典的排序算法,冒泡,顾名思义就是轻(小)的往上冒,重(大)的往下沉,也称鸡尾酒算法

解析首先我们需要确立两层嵌套for循环,第一层for循环主要控制总体循环的趟数,第二层for循环主要是比对相邻的两个数,运用CAS(比较并替换)的思路将每一趟的第二层for循环执行完成

【python基础】第19回 多层,有参装饰器 递归 二分法的更多相关文章

  1. python函数之闭包函数与无参装饰器

    一.global与nonlocal #global x = 1 def f1(): global x # 声明此处是全部变量x x = 2 print(x) f1() # 调用f1后,修改了全局变量x ...

  2. python基础知识7——迭代器,生成器,装饰器

    迭代器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器 ...

  3. python基础语法8 叠加装饰器,有参装饰器,wraps补充,迭代器

    叠加装饰器: 叠加装饰器 - 每一个新的功能都应该写一个新的装饰器 - 否则会导致,代码冗余,结构不清晰,可扩展性差 在同一个被装饰对象中,添加多个装饰器,并执行. @装饰1 @装饰2 @装饰3 de ...

  4. Python函数07/有参装饰器/多个装饰器装饰一个函数

    Python函数07/有参装饰器/多个装饰器装饰一个函数 目录 Python函数07/有参装饰器/多个装饰器装饰一个函数 内容大纲 1.有参装饰器 2.多个装饰器装饰一个函数 3.今日总结 3.今日练 ...

  5. python语法糖之有参装饰器、无参装饰器

    python的装饰器简单来说就是函数的一种形式,是为了扩展原来的函数功能而设计的. 装饰器的特别之处在于它的返回值也是一个函数,可以在不改变原有函数代码的基础上添加新的功能 # 先定义一个函数及引用# ...

  6. python 有参装饰器与迭代器

    1.有参装饰器 模板: def auth(x): def deco(func): def timmer(*args,**kwargs ): res = func(*args,**kwargs ) re ...

  7. python 带参与不带参装饰器的使用与流程分析/什么是装饰器/装饰器使用注意事项

    一.什么是装饰器 装饰器是用来给函数动态的添加功能的一种技术,属于一种语法糖.通俗一点讲就是:在不会影响原有函数的功能基础上,在原有函数的执行过程中额外的添加上另外一段处理逻辑 二.装饰器功能实现的技 ...

  8. Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发

    本节大纲 迭代器&生成器 装饰器  基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...

  9. Python:有参装饰器与多个装饰器装饰一个函数

    有参装饰器 def timmerout(flag1): #flag1 =flag def timmer(f): def inner(*args,**kwargs): if flag1: start_t ...

随机推荐

  1. 【大话云原生】煮饺子与docker、kubernetes之间的关系

    云原生的概念最近非常火爆,企业落地云原生的愿望也越发强烈.看过很多关于云原生的文章,要么云山雾罩,要么曲高和寡. 所以笔者就有了写<大话云原生>系列文章的想法,期望用最通俗.简单的语言说明 ...

  2. react 可拖拽改变位置和大小的弹窗

    一 目标 最近,项目上需要一个可以弹出一个可以移动位置和改变大小的窗口,来显示一下对当前页面的一个辅助内容 二 思路 1.之前写过一个antd modal的可移动弹窗但是毕竟不如自己写的更定制化,比如 ...

  3. 睡前聊一聊"spring bean 生命周期"

    spring bean 生命周期=实属初销+2个常见接口+3个Aware型接口+2个生命周期接口 实属初销:spring bean生命周期只有四个阶段,即实例化->属性赋值->初始化-&g ...

  4. rabbitmq 安装延时队列插件rabbitmq-delayed-message-exchange

    1.下载rabbitmq-delayed-message-exchange(注意版本对应) 链接:https://github.com/rabbitmq/rabbitmq-delayed-messag ...

  5. GO语言学习——切片二

    使用make()函数构造切片 格式: make([]T, size, cap) 其中: T:切片的元素类型 size:切片中元素的数量 cap:切片的容量 切片的本质 切片的本质就是对底层数组的封装, ...

  6. Ajax学习笔记demo

    AJAX学习 AJAX简介: 全称:Asynchronous JavaScript and XML (JavaScript执行异步网络请求(JS和XML)),通过AJAX可以在浏览器向服务器发送异步请 ...

  7. 实战 | Linux根分区扩容

    一个执着于技术的公众号 一个执着于技术的公众号 前言 Linux系统作为服务器操作系统,经常遇到一个问题就是服务器分区磁盘空间不足需要扩容的情况.本文以linux系统最常见的发行版centos7系统为 ...

  8. 掌握AI学习路上核心理论知识,你绝对不能错过这份最全资料包

    人工智能成为当下科技发展的代表之一,持续受到了不少追捧,不管你是否是这一专业的学生或者职场人,学习并掌握一项新潮技能总是不会被同龄人淘汰的.我曾经问过别人.也被别人问过关于学习人工智能(AI)最好的方 ...

  9. 面试官问:浏览器输入 URL 回车之后发生了什么?

    一个执着于技术的公众号 前言 这个问题已经是老生常谈了,更是经常被作为面试的压轴题出现,网上也有很多文章,但最近闲的无聊,然后就自己做了一篇笔记,感觉比之前理解更透彻了. 注意:本文的步骤是建立在,请 ...

  10. Java安全之SnakeYaml反序列化分析

    Java安全之SnakeYaml反序列化分析 目录 Java安全之SnakeYaml反序列化分析 写在前面 SnakeYaml简介 SnakeYaml序列化与反序列化 常用方法 序列化 反序列化 Sn ...