1.有名函数
print('aaa')
print('aaa')
def run(x,y):
print(x)
print(y)
print(x,y)
return x,y
run(1,2)
2.匿名函数
定义:没有名字的函数
仅仅用于临时使用一次的场景,没有重复使用的需要
语法 lambda空格+参数+冒号+函数体代码(表达式或者函数)
# 匿名函数的定义
# print(lambda x,y:x+y)
# 调用直接内存地址加括号 (它虽然没有名字)+括号可以调用
# 返回值省略了return
# 表达式
print((lambda x,y:x+y)(1,2))
# 函数
(lambda x,y:x+y)(1,2)
# 把内存地址赋值给一个变量没有意义
# 匿名函数的精髓就是没有名字,为其绑定名字是没有意义的
# f = lambda x,y:x+y
# print(f(1,2))
# 匿名函数与内置函数结合使用
# max min sorted
salarice = {
'xialuo':30000,
'xishi':20000,
'zhangxi':10000
}
# 我们要比较的是薪资 求薪资最高的那个人名:比较的是value但结果取得是key
# 默认比较key值 返回也是key值
# print(max(salarice)) #错误
# 这个哈数需要获得字典的value 这样才会比较value
def fun(n):
return salarice[n]
# 比较fun的返回值 也就是salarice的value的值 但是还是返回key,max的返回值是key
print(max(salarice,key = fun))
print(max(salarice,key = lambda n:salarice[n]))
# 最小值
print(min(salarice,key = lambda n:salarice[n]))
# 我们要比较的是薪资,返回的是人名
# 薪资反序
print(sorted(salarice,key = lambda n:salarice[n],reverse = True))
# 薪资正序
print(sorted(salarice,key = lambda n:salarice[n],reverse = False))
3.递归函数
1.什么是递归函数
函数的递归调用是函数嵌套调用的一种特殊形式,在调用一个函数的过程中又直接或间接地调用该函数本身,称之为函数的递归调用
递归死循环是没有意义的
递归调用必须有连个明确的阶段:
1.回溯:一次次递归调用下去,说白了就是一个重复的过程
但需要注意的是每一次重复问题的规模都应该有所减少
知道逼近一个最终的结果,即回溯阶段一定要有一个明确的结束条件
2.递推:往回一层一层推算出结果
例1
def foo(n):
print('from foo',n)
foo(n+1)
foo(0)
例2
# 第五个人的年龄为第四个人加两岁
'''
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18
'''
# 第几个人定义成n
'''
age(n) = age(n-1) + 2 # n > 1
age(n) = 18 # m = 1
'''
# 递归调用就是一个重复的过程,但是每一次重复的规模都应该有所减少
# 并且应该满足某种条件的情况下结束重复,开始进入递推阶段
def age(n):
if n == 1:
return 18
if n > 1:
return age(n-1) + 2
print(age(5))
例3
# 把里面的数字取出来
L = [1,[2,[3,[4,[5,[6,[7,[8,[9]]]]]]]]]
# 循环需要考虑次数
for n in L:
if type(n) is not list:
print(n)
else:
for n in n:
if type(n) is not list:
print(n)
else:
# print('列表式%s'%n)
for n in n:
if type(n) is not list:
print(n)
else:
# print('列表式%s' % n)
for n in n:
if type(n) is not list:
print(n)
else:
# print('列表式%s' % n)
for n in n:
if type(n) is not list:
print(n)
else:
# print('列表式%s' % n)
for n in n:
if type(n) is not list:
print(n)
else:
# print('列表式%s' % n)
for n in n:
if type(n) is not list:
print(n)
else:
# print('列表式%s' % n)
for n in n:
if type(n) is not list:
print(n)
else:
# print('列表式%s' % n)
for n in n:
if type(n) is not list:
print(n)
else:
# print('列表式%s' % n)
pass
def search(L):
for n in L:
if type(n) is not list:
print(n)
else:
search(n)
## 递归是函数的定义里面嵌套函数的调用
## 递归与循环的区别:
# 循环每一次都要判断,需要考虑很多次
# 递归只需要明确结束条件就行,按照规律进行重复调用,不需要考虑次数
4.闭包函数
# 1.函数的定义阶段:****
# 只检测函数的语法 不执行函数体代码
# def 函数名+括号+冒号
# 缩进+体代码
# 2.函数调用阶段:******
# 函数的调用:函数名+括号
# 1.先找到名字 (找到工厂位置)
# 2.根据名字调用代码 (加了括号执行工厂进行加工)
#
def factory():
'''
这个注释是告诉别人功能的
这是一个工厂
:return:
'''
print('正在制造手机') #代码相当于员工和机器
print('正在制造手机') #代码相当于员工和机器
print('正在制造手机') #代码相当于员工和机器
print('正在制造手机') #代码相当于员工和机器
print('正在制造手机') #代码相当于员工和机器
# name = 'zhanxi'
# print(id(factory))
#1.先找到名字 (找到工厂位置)
# print(factory)
factory()
# # 闭包
# # 闭是指该函数是一个内部函数
# # 包是指该内部的函数名字在外部被引用
def outer(): # 没有调用outer(),但是创造了outer这个函数
# 1.只检测函数体的语法(工厂合不合格),不执行函数体代码(不使用工厂)
print('外面的函数正在运行')
def inter():
print('里面的函数正在执行')
# 3.返回inter函数的内存地址 想象成inter工厂的一把钥匙,由outer的物流return
return inter
# 2.执行了outer这个函数体代码,inter定义了但没有执行
inter = outer() # 4.得到了里面的inter钥匙,取名字inter
# # inter工厂的钥匙 加开关()
# # 5.里面的inter钥匙加括号运行inter这个函数
inter()
# outer()() #这种写法也可以,但不推荐 不规范
# 为函数体传值的方式一:参数
def func(x,y):
print(x+y)
# 每次都是传入相同的参数
func(3,2)
func(3,2)
func(3,2)
func(3,2)
# 为函数体传值的方式二:闭包
def outer(x,y):
def func():
print(x+y)
return func
# 每次都是传入同样的参数
func1 = outer(3,2) # 把配料渗透到包子肉func函数地址里面去了
print(func1)
func1()
func1()
func1()
func1()
5.装饰器
# 装饰器就是一个特殊的闭包函数
# 1.什么是装饰器(就是一个函数,只不过这个函数不是给自己使用的,是给其他函数添加功能的)
# 器指的是工具,而程序中的函数就是具备某一功能的工具
# 装饰指的是为被装饰器对象添加额外功能
# 2.为什么要用装饰器
# 软件的维护应该遵循开放封闭的原则
# 开放封闭原则这的是:
# 软件一旦上线运行后对修改源代码是封闭的,对扩展功能是开放的
# 这就用到了装饰器
# 装饰器的实现必须遵循两大原则:
# 1.不修改被装饰对形象的源代码(人的原来的性格,生活方式)
# 2.不修改被装饰对象的调用方式(人的原来的外貌,名字)
# 错误---违反第一条
def run():
print('跑步')
print('健身')
run()
# 错误---违反第二条
def fitness():
print('健身')
run()
def run():
print('跑步')
fitness()
# 示例1
name = 'zhangxi'
def run(name):
print('==========')
print('我是%s'%name)
print('==========')
print(run)
run(name)
# 1.定义了decorate,检测decorate语法 new_func没有定义
def decorate(func): #func等下我们要传入run
print(func)
def new_func(name): #run(name) 的name
print('这是装饰器前面的代码')
func(name)
print('这个装饰函数后面的代码')
return new_func
# 2.1 定义了new_func(name)函数 2.2 返回了new_func的内存地址 2.3传入了一个run函数名作为decorate函数参数
run = decorate(run)
print(run)
run(name)
# 用到的知识点
# 1.传参 函数名传参 细节
# 2.new_func里面这个函数的参数 是被装饰函数的参数
# 3.return mew_func 里面的这个函数
# 4.run_time(for1)的返回值是for1这个名字 但实际上是new_func函数名
# 示例二 测试for循环从1加到9000000的时间
from datetime import datetime
#当前时间
print(datetime.now())
#时间装饰器
n = 9000000
def run_time(func): # 装饰谁就传谁 func是for1 这是一个用来计算程序执行时间的装饰器
def new_func(n): # for1(n)的n
# 运行装饰的代码
start_time = datetime.now()
print('开始时间%s'% start_time)
func(n)
end_time = datetime.now()
print('结束时间%s'% end_time)
time1 = end_time - start_time
print('花费时间%s'% time1)
return new_func
# 1.定义了new_func(n)函数 2.返回了new_func内存地址 3.传入了一个for1函数名 4.返回值new_func函数名
# for1 = run_time(for1)
# print(for1)
# 被装饰的函数放装饰器后面
# 装饰器定义好直接用@ + 装饰器名字 就可以给被装饰函数进行装饰
@run_time
# 底层
def for1(n):
sum1 = 0
for i in range(1,n+1):
sum1 += 1
print(sum1)
for1(n)
@run_time
def shopping():
for i in range(11111111):
pass
print('shopping')
shopping(1)
6.练习
写一个登录装饰器对一个函数进行装饰,要求输入账号和密码才能运行该函数
def run():
print(‘开始执行函数’)
def new_func(func):
def wrappedfun(username, passwd):
if username == 'root' and passwd == '123456789':
print('通过认证')
return func()
else:
print('用户名或密码错误')
return
return wrappedfun
@new_func
def run():
print('开始执行函数')
run('root','123456789')