1.装饰器II
在装饰器 I 中,装饰器应用之一,可以在遵循开放封闭的原则的前提下,加入新功能。但这种添加方法不完善,即:装饰多个函数,必须 “分类讨论”,无法汇总,不具备耦合性。
一个装饰器装饰多个函数(存在参数的装饰器):增强代码的耦合性。
-
带参数的装饰器基本形式:
def outer(n): def middle(x): def inner(*args,**kwargs): …… 调用 n a = x(*args,**kwargs) return a retrun inner return middle @outer("实参") def func(): pass func()
-
Example:
def wrapper_out(n): def wrapper(f): def inner(*args, **kwargs): if n == 'qq': username = input('请输入用户名:').strip() password = input('请输入密码:').strip() with open('qq', encoding='utf-8') as f1: for line in f1: user, pwd = line.strip().split('|') if username == user and password == pwd: print('登陆成功') ret = f(*args, **kwargs) return ret return False elif n == 'tiktok': username = input('请输入用户名:').strip() password = input('请输入密码:').strip() with open('tiktok', encoding='utf-8') as f1: for line in f1: user, pwd = line.strip().split('|') if username == user and password == pwd: print('登陆成功') ret = f(*args, **kwargs) return ret return False username = input('请输入用户名:').strip() password = input('请输入密码:').strip() with open(n, encoding='utf-8') as f1: for line in f1: user, pwd = line.strip().split('|') if username == user and password == pwd: print('登陆成功') ret = f(*args, **kwargs) return ret return False return inner return wrapper @wrapper_out('qq') def qq(): print('成功访问qq') qq() @wrapper_out('tiktok') def tiktok(): print('成功访问抖音') tiktok()
- 可以通过例子看到,通过将装饰器额外套一层含有形参的函数,可实现对一些重复代码的聚合效果。完成这个额外效果的中间变量,就是形参 n。
- @最外层函数名("实参") 是在装饰器 I 中, @最外层函数名 的拓展。它代表:
- 被装饰函数 = 最外层函数名(被装饰函数),此时,当得到调用被装饰函数命令时,@~进行了转译,此时执行的是中层函数,并且此时,实现了传参。
- 继续按照这个思路走,剩余的步骤便与 “标准模式” 相同。
但是,这个思路还是有其自己的弊端,就是遇到每个被装饰的函数,都要写一层 @~,根据这一点,说明代码的耦合性无法做到最极致。
- 递归,在一般情况下,相当于无限 while 循环。但操作系统存在内存保护机制,存在最大递归次数。官方默认最大递归次数为:1000 次。
- 设立保护机制的原因在于,每次调用函数,都会在内存开辟新的空间,而原空间由于函数没有执行完,没有被释放。
- 原则上,递归的次数应不多余 100 次,为了效率,与时间复杂度。
一般能用递归解决的问题,用 if 与 while 都可以搞定,使用递归在某些时候有奇效。
-