Python:十、装饰器、函数递归、栈和队列

一、装饰器【重点】

  • 装饰器定义:在代码运行期间,在不修改原函数的基础上,可以动态增加函数功能的方式,被称为装饰器(Decorator)。
  • 优点:在团队开发中,如果两个或者两个以上的程序员会用到相同的功能,但是功能又有细微的差别,采用装饰器:相互不影响,代码简化。
1.1 创建装饰器
  • 语法:

    def outer(fun):
    	def inner():
    		fun()
    	return inner
    outer(fun)
    
1.2 装饰器的使用
1.2.1 简单装饰器
  • outer外部函数就被称为装饰器!

    1.简单的装饰器
    def test():
    	print("拼搏到无能为力,坚持到感动自己")
    
    a.书写闭包
    b.给外部函数设置参数,fun表示的是原函数
    def outer(fun):
    	def inner():
        	d.给原函数增加功能
        	print("hello")
    
        	c.调用原函数
        	fun()
    	return inner
    
    e.使用闭包
    f = outer(test)   #f = inner
    f()   #inner()
    
1.2.2 有参数的装饰器
  • 当原函数有参数,装饰器的作用是为了操作原函数中的参数,给inner设置参数。

    def wrapper(fun):
        def inner(num):
         #增加新功能:过滤负数
            if num < 0:
                num = 0
         #调用原函数
            fun(num)  #age = num
        return inner
    
    #将wrapper装饰器应用在了getAge函数上,
    # @wrapper        # 等价于:getAge= wrapper(getAge)
    def getAge(age):
        print(age)
    
    getAge(10)
    getAge(-5)
    
1.2.3 不定长参数的装饰器
  • 当同一个装饰器作用于不同函数的时候,这些函数的参数的个数是不相同的。

    def wrapper(fun):
    	def inner(*args):
        	print("hello")
    		fun(*args)   #a = args[0]   b = args[1]
    	return inner
    @wrapper
    def fun1(a,b):
    	print(a + b)		---> 30
    @wrapper
    def fun2(a,b,c,d):
    	print(a,b,c,d)		---> 1 2 3 4
    fun1(10,20)   
    fun2(1,2,3,4)
    
  • 通用装饰器

    def outer(fn):
        def inner(*args,**kwargs):
            print("before")
            res = fn(*args,**kwargs)
            print("after")
            return res
        return inner
    @outer
    def eat():
        print("吃饭")
    @outer
    def sing(song):
        print("哈哈唱:", song)
        return "一般"
    eat()
    res = sing("大碗宽面")
    print(res)
    
1.2.4 多个装饰器作用于同一个函数
  • 多个装饰器作用于同一个函数的时候,从第一个装饰器开始,从上往下依次执行,但是,原函数只会被执行一次。

    def outer(f):
        def inner():
            print("before")
            f()
            print("after")
        return inner
    def outer1(f):
        def inner():
            print("befor1")
            f()
            print("aftor1")
        return inner
    @outer
    @outer1
    def sing():
        print("唱歌")
    sing()
    
    结果:
    before
    befor1
    唱歌
    aftor1
    after
    
1.3 总结
  1. 增加的功能可以写在原函数调用的前面或者后面;
  2. 当原函数有参数,装饰器的作用是为了操作原函数中的参数,给inner设置参数;
  3. 当使用@简化时,在同一个文件中,装饰器必须出现的原函数的前面;
  4. 多个装饰器作用于同一个函数的时候,从第一个装饰器开始,从上往下依次执行,原函数只会被执行一次。

二、函数递归【重点】

  • 递归函数定义:一个会调用自身的函数(在一个函数的内部,自己调用自己)。

  • 递归调用:递归中包含了一种隐式的循环,他会重复指定某段代码(函数体),但这种循环不需要条件控制。

  • 解决思路:
    1、找公式,如:fn(n)=n*fn(n-1)
    2、找到相邻两次循环之间的关系
    3、找临界值,如:n=1,f(1)=1
    4、一定要相信函数能实现。

  • 优点:简化代码,逻辑清晰。

  • 注意:以后在实际项目中尽量少用递归,如果隐式循环的次数太多,会导致内存泄漏(栈溢出)。

2.1 案例
  • 案例一:求第n个斐波那契数
    ---------------------1 2 3 4 5 6 7 8 9 10 11.。。。
    斐波那契数列:1,1,2,3,5,8,13,21,34,55,89…

    解决问题:报一个数,输出数列中对应的数

    规律:
    a.第一个位置和第二个位置上数是固定的,都是1
    b.第n个位置上的数:第 n - 1 的数 + 第 n - 2 的数

    r1 = func1(1) ------>1
    r2 = func1(2) ------>1
    r3 = fun1(3) ------>func1(1) + func1(2)----->1 + 1 = 2
    r4 = fun1(4)------->fun1(3) + fun1(2) ----->func1(1) + func1(2) + fun1(2) ---->1 + 1 + 1 = 3
    r5 = fun1(5) ----->fun1(4) + fun1(3) ----->fun1(3) + fun1(2) + func1(1) + func1(2)—>func1(1) + func1(2) ++ fun1(2) + func1(1) + func1(2)—>5

    rn = fun1(n) ----->fun1(n- 1) + fun1(n - 2)
    “”"

    def func1(num):
     #临界值
    	if num == 1 or num == 2:
        	return 1
    	else:
         	#print("~~~~",num)
        	result = func1(num- 1) + func1(num - 2)    #result = func1(1) + func1(2)  --->1 + 1 =2
        	return result
    print(func1(10))
    
  • 案例二:使用递归计算1~某个数之间的和
    “”"
    add(1) = 1 :临界值
    add(2) = add(1) + 2
    add(3) = add(2) + 3 ---->add(1) + 2 + 3 = 1 + 2 + 3
    add(4) = add(3) + 4---->add(2) + 3 + 4 ---->add(1) + 2 + 3 + 4---->1 + 2 + 3 + 4

    add(n) = add(n - 1) + n
    “”"

    def add(num):
    	if num == 1:
        	return 1
    	else:
        	return add(num - 1) + num
    print(add(100))
    

三、栈和队列【了解】

用于存储数据的线性表
栈:在表的一端进行插入和删除
队列:在表的一端进行插入,在表的另一端进行数据的删除

3.1 栈(Stack)
  • 栈:一种数据结构。开口向上的容器:先进后出,后进先出。用列表实现栈。

    stack = []
    # 入栈
    stack.append('a')
    print(stack)
    stack.append('b')
    print(stack)
    stack.append('c')
    print(stack)
    stack.append('d')
    print(stack)
    # 出栈
    stack.pop()
    print(stack)
    stack.pop()
    print(stack)
    stack.pop()
    print(stack)
    stack.pop()
    print(stack)
    
3.2 队列(queue)
  • 队列:水平放置的水管,先进先出,后进后出。

  • 队列格式:deque([1, 2, 3, 4])

    队列必须先调用collections:import collections。再用collections创建队列。

    #队列
    # from collections import deque
    import collections
    #创建队列
    queue = collections.deque()
    print(queue)
    # 入队列
    queue.append('a')
    print(queue)
    queue.append('b')
    print(queue)
    queue.append('c')
    print(queue)
    queue.append('d')
    print(queue)
    # 出序列
    queue.popleft() # 从左边删
    print(queue)
    queue.popleft()
    print(queue)
    queue.popleft()
    print(queue)
    queue.popleft()
    print(queue)
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值