热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

有参装饰器与递归函数

本章内容多层语法糖内部本质有参装饰器递归函数算法之二分法多层语法糖内部本质语法糖会将紧挨着的被装饰对象的名字当做参数自动传入装饰器函数中#示例:#判断七句print的执行顺序def

本章内容

  • 多层语法糖内部本质

  • 有参装饰器

  • 递归函数

  • 算法之二分法


多层语法糖内部本质

"""语法糖会将紧挨着的被装饰对象的名字当做参数自动传入装饰器函数中"""
# 示例:
#判断七句print的执行顺序
def func1(func_name):
print('执行func1')
def inner(*args, **kwargs):
print('输出func1')
res = func_name(*args, **kwargs)
return res
return inner
def func2(func_name):
print('执行func2')
def inner(*args, **kwargs):
print('输出func2')
res = func_name(*args, **kwargs)
return res
return inner
def func3(func_name):
print('执行func3')
def inner(*args, **kwargs):
print('输出func3')
res = func_name(*args, **kwargs)
return res
return inner
@func1
@func2
@func3 # index = func3(index)
def index():
return '这是原函数'
res = index()
print(res)

image-20220321164128154


有参装饰器

def outer(source_data):
def login_auth(func_name): # 不能动 只能接收一个被装饰对象名字
def inner(*args, **kwargs): # 不能动 是专门用来给被装饰的对象传参的
username = input('username>>>:').strip()
password = input('password>>>:').strip()
# 校验用户数据 数据的来源可以有很多 比如全局字典 全局列表 文本文件 数据库
# 数据的来源不同 处理方式就不同 对应的代码编写就不一样
# 分支结构处理 然后根据不同的参数提示 匹配不同的流程
if source_data == '1':
print('使用字典的方式处理数据')
elif source_data == '2':
print('使用列表的方式处理数据')
elif source_data == '3':
print('使用文件操作处理数据')
else:
print('其他操作情况')
res = func_name(*args, **kwargs)
return res
return inner
return login_auth
"""
函数名加括号 执行优先级最高
@outer('3')
左侧是语法糖结构 右侧是函数名加括号结构
先执行函数调用 outer('3') 返回值是login_auth
在执行语法糖结构 @login_auth
发现最后还是一个普通的装饰器
有参装饰器目的仅仅是给装饰器传递额外的参数
装饰器最多就三层嵌套
并且三层嵌套的结构使用频率不高(最多是使用别人写好的有参装饰器)
from functools import wraps
@wraps(func_name)
"""
@outer('3')
def index():
print('from index')

image-20220321170644942


递归函数

# 本质:递归函数也称为函数的递归
函数在运行过程中直接或者间接的调用了自身

# 基本演示
# 直接调用自己
# def index():
# print('from index')
# index()
# index()
"""
maximum recursion depth exceeded while calling a Python object
最大递归深度超出限制了 python解释器自带的应急机制
在有些编程语言中 甚至没有遇警机制 代码执行真的一致到计算机崩溃为止
"""
# 间接调用自己
# def index():
# print('from index')
# func()
# def func():
# print('from func')
# index()
# func()
"""
maximum recursion depth exceeded while calling a Python object
这对python最大递归深度
回答997 998 1000都可以
官方给出的是1000
"""
# import sys
# print(sys.getrecursionlimit()) # 获取默认的最大递归深度 # 1000
# sys.setrecursionlimit(2000) # 还可以修改最大递归深度
# count = 1
# def index():
# print('from index')
# global count
# print(count)
# count += 1
# index()
# index()
"""
函数的递归不应该是无限循环的过程 真正的递归函数应该要满足两个要求
1.每次递归 复杂度必须降低(下一次递归要比上一次递归解答)
大白话 越往下递归应该离解决问题的答案越近
2.必须要有明确的结束条件
"""

# 诠释
"""
需求:我想知道我们班坐在第一排的某个学生年龄
过程:
我问他多大了 他调皮不告诉我 说比后面那个同学大两岁
后面的说比他后面的大两岁
...
问到最后你一排 终于开口说 18岁
...
知道最后一排的年级回推就可以知道第一排的年级
名词:
递推:一层层往下问
回溯:根据结果推结论
"""
# 如何编写代码完成
# 目标人物的年龄 = 后一排年龄 + 2
# 后一排年龄 = 后后一排年龄 + 2
# 后后一排年龄 = 后后后一排年龄 + 2
# 后后后后一排年龄 = 18
# 将求问年龄变成函数
# age(5) = age(4) + 2
# age(4) = age(3) + 2
# age(3) = age(2) + 2
# age(2) = age(1) + 2
# age(1) = 18
# 封装函数
def get_age(n):
if n == 1:
return 18 # 有明确的结束条件
return get_age(n-1) + 2
print(get_age(4))
'''千万不要想复杂了 就记嵌套图即可 有结果就是由内而外一层层拨开'''

image-20220321170744079


算法之二分法

# 什么是算法?
算法其实就是解决问题的有效方法
eg:比如打开易拉罐的问题
方法1:使用金属撬棍
方法2:直接手扣
方法3:一阳指戳
...
"""
算法比较偏向于学术研究 很枯燥 并且产出很少
甚至只有非常大的互联网公司才会有算法部分
算法工程师薪资待遇很高 但是产出很少
有时候甚至几年都没有任何的成果 有点类似于研究所!!!
"""
# 算法之二分法
二分法是算法里面最入门的一个 主要是感受算法的魅力所在
# Author:Jason
"""二分法使用有前提: 数据集必须有先后顺序(升序 降序)"""
l1 = [13,21,35,46,52,67,76,87,99,123,213,321,432,564,612]
# 查找一个数 123
"""
二分法原理
获取数据集中间的元素 比对大小
如果中间的元素大于目标数据 那么保留数据集的左边一半
如果中间的元素小于目标数据 那么保留数据集的右边一半
然后针对剩下的数据集再二分
如果中间的元素大于目标数据 那么保留数据集的左边一半
如果中间的元素小于目标数据 那么保留数据集的右边一半
...
"""
def get_target(l1,target_num):
# 最后需要考虑找不到的情况 l1不可能无限制二分
if len(l1) == 0:
print('不好意思 真的没有 找不到')
return
# 1.获取中间元素的索引值(只能是整数)
middle_index = len(l1) // 2
# 2.判断中间索引对应的数据与目标数据的大小
if target_num > l1[middle_index]:
# 3.保留数据集右侧
l1_left = l1[middle_index+1:]
# 3.1.对右侧继续二分 重复执行相同代码 并且复杂度降低
print(l1_left)
get_target(l1_left,target_num)
elif target_num # 4.保留数据集左侧
l1_right = l1[:middle_index]
print(l1_right)
# 4.1.对右侧继续二分 重复执行相同代码 并且复杂度降低
get_target(l1_right,target_num)
else:
print('找到了',target_num)
# get_target(l1,432)
# get_target(l1,22)
get_target(l1,13)
"""
二分法的缺陷
1.如果要找的元素就在数据集的开头 二分更加复杂
2.数据集必须有顺序
目前没有最完美的算法 都有相应的限制条件
"""
"""
以后面试的时候 可能会让你手用python写一些算法
二分法 快排 插入 冒泡 堆排序
上述知识面试之前临时抱佛脚即可 平时无需过多研究
"""

image-20220321171347705



推荐阅读
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
author-avatar
爱飞扬无限_316
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有