1.案例
代码演示:
def test(): print("你好啊!") # test() # 需求: 给上面的函数test增加一个功能, 输出 我很好 # 第一种方式: 修改了原来的函数 ''' def test(): print("你好啊!") print("我很好") test() # 第二种方式: 定义一个新函数,在新函数中调用原函数,然后追加功能 def test1(): test() print("我很好") test1() '''
在代码运行期间,可以动态增加函数功能的方式,被称为装饰器【Decorator】 通过闭包函数实现
也就是说,在不修改原函数的基础上,给原函数增加功能
好处:在团队开发中,如果两个或者两个以上的程序员会用到相同的功能,但是功能又有细微的差别,采用装饰器:相互不影响,代码简化
2.使用
2.1简单装饰器
代码演示:
# 原函数 def test(): print("你好啊!") # 需求: 给上面的函数test增加一个功能, 输出 我很好 # 第三种方式: 通过装饰器的方式给函数追加功能 装饰器使用闭包实现 ''' 闭包函数: 1.函数嵌套函数 2.内部函数使用外部函数的变量 3.外部函数中返回内部函数 ''' #a.书写闭包函数 此处的outer函数就是装饰器函数 def outer(fn): #b. fn表示形参, 实际调用的时候传递的是原函数的名字 def inner(): fn() #c.调用原函数 #d. 给原函数添加功能, 注意:添加的功能可以写在原函数的上面也可以写在原函数的下面 print("我很好") return inner print("添加装饰器之前:",test,__name__) #<function test at 0x00000223ED1DC268> test = outer(test) print("添加装饰器之后:",test,__name__) # <function outer.<locals>.inner at 0x00000223ED793510> test() 总结: 1.在装饰器中,给原函数添加的功能,可以写在原函数的上面,也可以写在原函数的下面 2.outer 函数就是我们的装饰器函数
2.2系统的简写
代码演示:
#a.书写闭包函数 此处的outer函数就是装饰器函数 def outer(fn): #b. fn表示形参, 实际调用的时候传递的是原函数的名字 def inner(): fn() #c.调用原函数 #d. 给原函数添加功能, 注意:添加的功能可以写在原函数的上面也可以写在原函数的下面 print("我很好") return inner # test = outer(test) # 装饰器的简写方式 @ + 装饰器名称 @outer # 等价于 =====>test = outer(test) def test(): print("你好啊!") test() ''' 注意: 1.在使用装饰器的简写方式的时候,原函数必须在装饰器函数的下面 2.outer就是装饰器函数. @outer等价于 test = outer(test) '''
2.3不定长参数的装饰器(通用装饰器)
代码演示:
# 同一个装饰器装饰多个函数 def jisuan(fn): def inner(*args): print("数学运算的结果是:",end=" ") fn(*args) return inner @jisuan def add(a,b): print(a+b) add(12,34) @jisuan def cha(a,b,c): print(a-b-c) cha(100,23,26)
2.4带返回值的装饰器
def outer(fn): def inner(): print("我的爱好是:",end = " ") return fn() # fn() ===> swim() ===> "i like swimming(这句话返回到了第4行) return inner @outer def swim(): return "i like swimming!" love = swim() print(love)
2.5 多个装饰器作用同一个函数
# 多个装饰器作用域一个函数 def outer1(fn): def inner(): print("~~~~~~~1111") fn() return inner def outer2(fn): def inner(): print("~~~~~~~2222") fn() return inner # 原函数 @outer2 @outer1 def show(): print("今晚我的好基友从广州过来了,好开心!....") show() ''' 当多个装饰器修饰一个函数的时候,装饰器从上往下依次执行. 并且原函数只执行一次. '''
1.概念
1.概念
递归函数:一个会调用自身的函数【在一个函数的内部,自己调用自己】
递归调用
递归中包含了一种隐式的循环,他会重复指定某段代码【函数体】,但这种循环不需要条件控制
使用递归解决问题思路:
a.找到一个临界条件【临界值】
b.找到相邻两次循环之间的关系
c.一般情况下,会找到一个规律【公式】
2.使用
代码演示:
# 函数自己调用自己就是递归 # 需求:通过递归的方式,封装一个函数,计算 n! (n是传入的数字) # 5! ===> 5*4*3*2*1==>5 * 4! # 4! ===> 4*3*2*1 ===>4 * 3! # 3! ===> 3*2*1====> 3 * 2! # 2! ===> 2*1 ===> 2 * 1! # 1! ===> 1 #总结如下: # n! = n * (n-1)! ''' a.找到一个临界值(临界条件) 1! = 1 b.找到两个循环之间的关系 c.总结规律: n! = n * (n-1)! ''' def digui(n): if n == 1: return 1 return n * digui(n-1) print(digui(6)) # 通过递归封装一个函数,传入一个数字m,得到第m个斐波那契数列 # 1 1 2 3 5 8 13 21 34 55 89 def fn(m): if m < 3: return 1 return fn(m-1) + fn(m-2) print(fn(8))
注意:以后在实际项目中尽量少用递归,如果隐式循环的次数太多,会导致内存泄漏【栈溢出】 python默认的递归次数限制为1000次左右.以免耗尽计算机的内存.
优点:简化代码,逻辑清晰
用于存储数据的线性表
栈:在表的一端进行插入和删除
队列:在表的一端进行插入,在表的另一端进行数据的删除
1.栈
Stack
开口向上的容器:先进后出,后进先出
代码演示:
#栈 #list底层维护了一个栈的线性表 myStack = [] #插入数据 #数据入栈 (压栈) myStack.append(1) print(myStack) myStack.append(2) print(myStack) myStack.append(3) print(myStack) myStack.append(4) print(myStack) #[1,2,3,4] print("============") #出栈 myStack.pop() print(myStack) myStack.pop() print(myStack) myStack.pop() print(myStack) myStack.pop() print(myStack)
2.队列
queue
水平放置的水管:先进先出,后进后出
代码演示:
#队列 queque import collections #数据结构的集合 queue = collections.deque([11,22,33,44]) print(queue) #入队 (存储数据) queue.append(55) print(queue) queue.append(66) print(queue) queue.append(77) print(queue) #出队(获取数据) queue.popleft() print(queue) queue.popleft() print(queue) queue.popleft() print(queue) queue.popleft() print(queue)