# 函数的引用 - 如果是可变类型,则不同的指向相同的内存空间的变量,操作完成后会保存.如果是不可变类型的话则修改不会保存.
a = 1
b = a
print(b) # 1
print(id(a)) # 2288401187056 内存地址
print(id(b)) # 2288401187056 内存地址
a += 2
print(b) # 1
print(id(a)) # 2288401187088 内存地址
print(id(b)) # 2288401187056 内存地址
list1 = [1, 2]
list2 = list1
print(list2) # [1, 2]
print(id(list1)) # 1974503320064
print(id(list2)) # 1974503320064
list1.append(3)
print(list2) # [1, 2, 3]
print(id(list1)) # 1974503320064
print(id(list2)) # 1974503320064
# 函数嵌套:如果外部函数内嵌套另一个内部函数,会牵扯到变量作用域的问题.一般遵循的查找顺序是:内层函数->外层函数->全局->系统定义 # 如果内部函数要修改外部函数定义的变量则需要关键字 nonlocal 变量名 来引进这个变量 # 如果全局变量想要在函数中进行修改的话则需要使用关键字 global 变量名 # 闭包:如果一个内部函数引用了外部函数作用域中的变量,并被外部函数返回,那么这个内部函数就被成为闭包(closure)
def outer(n):
num = n
def inner():
count = num + 1
return count
return inner
print(outer(2)())
# 装饰器 decorator @decorator表示调用decorator()方法,但不会执行内部函数 如果执行被@decorator标识的方法才会调用其内部函数 # 装饰器有点类似于spring boot的aop. 在满足程序开闭原则的前提下,如果需要对程序内部进行功能添加,则需要使用装饰器 # 装饰器执行顺序 -> 程序运行到@decorator时,会将下方被修饰的方法一起传入,下面例子相当于decorator(house) 将内部函数wrapper加载进内存后返回,将wrapper函数赋值给horse函数 # 装饰器功能: 引入日志 函数执行时间统计 执行函数前预备处理 执行函数后清理功能 权限校验等场景 缓存
def decorator(func):
print('装饰器1')
def wrapper():
func()
print('装修队装修!')
print('装饰器2')
return wrapper
@decorator # decorator(house)
def house():
print('新家毛坯房!')
house()
print('---------------')
# 有参数的装饰器1: # 如果是原函数是带有参数的话,定义的修饰器是需要传参的,就在装饰器的内部函数中.因为传的参数不知道会有几个,所以我们用可变参数来承接.
def factory(func):
def wrapper(*args):
func(args)
print('装修队装修!')
return wrapper
@factory
def factory(address):
print(f'新工厂毛坯房,地址在{address}')
factory('山西大同')
print('---------------')
# 有参数的装饰器2: # 如果原函数带有参数并且还有关键字参数,则装饰器的内部函数还需要定义**kwargs来装包关键字参数
def school(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print(args, kwargs) # ('山西太原',) {'name': 'xx中心'}
print('装修队装修!')
return wrapper
@school
def school(address, name='育才中学'):
print(f'新学校毛坯房,地址在{address},名字是{name}')
school('山西太原', name='xx中心') # 关键字传参的话需要**kwargs接收并且以字典形式表现
print('---------------')
# 有返回值的装饰器: # 如果原函数存在返回值的话,那么修饰器的内部函数也需要有返回值
def return_decorator(func):
def wrapper(*args, **kwargs):
r = func(*args, **kwargs)
# 返回原函数的返回值
return r
return wrapper
@return_decorator
def print_num(num):
return num
print(print_num(1000)) # 通过装饰器也可以接收返回值
print('---------------')
# 如果装饰器也有参数的话呢,需要在外部再调用一层. # 流程:当程序读到@check_time(35)时,带着play_game()进入check_time(time)方法 # 第一层:check_time(time)运行:内存中读取check_play(func)方法,返回check_play # 第二层:check_play方法并没有反出去,而是在第二层调用这个方法 check_play(play_game) 并返回wrapper内部函数 # 第三层:相当于将wrapper函数赋值给play_game函数,最后执行的就是wrapper函数
def check_time(time):
def check_play(func):
def wrapper(*args, **kwargs):
if time < 30:
func()
else:
print('不符合规则,不能打游戏!')
return wrapper
return check_play
@check_time(35)
def play_game():
print('打游戏去喽')
play_game() # 不符合规则,不能打游戏!
print('---------------')
# 递归实现1-10的累加和
def get_sum(i):
if i == 10:
# 当符合条件后,这个return会返回给最后调用他的函数,就是get_sum(9)的返回值
return 10
else:
return i + get_sum(i + 1)
r = get_sum(1)
print(r)
print('---------------')
# 匿名函数 格式:lambda 参数列表: 返回值函数体表达式
r = lambda x, y: x + y
print(r(1, 2))
# 匿名函数 应用场合:匿名函数可以作为参数传递
def test_2(x, y, func):
print(f'x={x}')
print(f'y={y}')
print(func(x, y))
test_2(1, 2, lambda x, y: x + y)
# 系统高阶函数:max(args, key) min(args, key) sorted(iterable, key, reverse)
# filter(func, iterable) map(func, iterables) reduce()
# 高阶函数: 一个函数的参数是另一个函数
list_1 = [('bob', 25), ('lcy', 22), ('vob', 19), ('cd', 29), ('wdf', 20)]
# 通过key根据得到的匿名函数返回值进行排序 根据年龄排序('cd', 29)
print(max(list_1, key=lambda x: x[1]))
# 通过key根据得到的匿名函数返回值进行排序 根据年龄排序('vob', 19)
print(min(list_1, key=lambda x: x[1]))
# 通过key 匿名函数 根据年龄大小进行排序[('vob', 19), ('wdf', 20), ('lcy', 22), ('bob', 25), ('cd', 29)]
s_list = sorted(list_1, key=lambda x: x[1]) # 返回一个新列表
print(s_list)
# 如果function返回值为true则返回一个迭代器,生成该函数的可迭代对象(item)。如果function为None,则返回为true的项。
f = filter(lambda x: x[1] > 20, list_1)
print(f) #
print(list(f)) # [('bob', 25), ('lcy', 22), ('cd', 29)] 返回list中符合条件的元素
# map 创建一个迭代器,该迭代器使用的实参计算函数 将列表中每一项符合条件的元素都执行相应操作
m = map(lambda x: x[1] + 1, list_1)
print(m) #