3.21python学习笔记

多层装饰器

#当需要对函数添加多个功能时,一个装饰器无法完成,就需要用到多层装饰器
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')
#装饰器的执行时从上往下的顺序执行,结构性从下往上

有参装饰器

#相当于把整个装饰器 看成一个闭包函授,给它又包了一个函数来传递参数
def outer(source_data):    
    def outter1(func1):
        if source_data == '1':
            print('加载了outter1')
        def wrapper1(*args, **kwargs):
            print('执行了wrapper1')
            res1 = func1(*args, **kwargs)
            return res1
        return wrapper1
@outer('1')
def index():
    print('from index')

递归函数

  #递归就是在函数内部调用自己的函数被称之为递归。
实例说明
1. 例1:
计算阶乘  n! = 1 * 2 * 3 * ... * n, 用函数fact(n)表示, 可以看出:
fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n,
所以, fact(n)可以表示为n * fact(n-1), 只有n = 1时需要特殊处理.
于是, fact(n)用递归的方式写出来就是:
def fact(n):
if n == 1:
	return 1
return n * fact(n - 1)

print(fact(5))      # 输出结果: 120
print(fact(1))      # 输出结果: 1
"""
函数的递归不应该是无限循环的过程 真正的递归函数应该要满足两个要求
    1.每次递归 复杂度必须降低(下一次递归要比上一次递归解答)
        大白话 越往下递归应该离解决问题的答案越近
    2.必须要有明确的结束条件
"""

算法之二分法

# 什么是算法?
	算法其实就是解决问题的有效方法
  	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 < l1[middle_index]:
        # 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写一些算法
    二分法 快排 插入 冒泡 堆排序
        上述知识面试之前临时抱佛脚即可 平时无需过多研究
"""
posted @ 2022-03-21 21:47  槐序八  阅读(32)  评论(0)    收藏  举报