装饰器 面试题错误点
1.装饰器作业讲解
编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码.
dic = {} reult = True #设置全局变量reult = True def renzheng(func): def inner(*args,**kwargs): global reult #内部函数修改全局变量需要global关键字 with open('文件.txt',encoding='utf-8') as obj: for i in obj: li = i.strip().split('|') dic[li[0]] = li[1] while True: if reult: #第一次登陆后把reult的值改为False,就进不来这里,不需要再次验证 urename = input('请输入用户名') password = input('请输入密码') if urename in dic and dic.get(urename) == password: print('登陆成功') reult = False #如果登陆成功修改全局变量reult if not reult: #登录过之后reult变为False, notFalse为True,进到这里执行调用的函数 ret = func(*args,**kwargs) return ret return inner @renzheng def welcome(name): print('欢迎%s'%name) welcome('周军豪') @renzheng def add(num1,num2): return num1+ num2 a = add(2,5) print(a)
2.面试题
1.有1个数据结构data如下所示,请编写1个函数从该结构数据中返回由指定的字段和对应的值组成的字
典。如果指定字段不存在,则跳过该字段。fields:由"|"连接的以"fld"开头的字符串,如:fld2|fld3|fld7|fld19(10分)
#类递归思想 #栈的思想
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
result = {} lis = [1, ] #假设列表最后一个值是1 def select(data,fields): li = fields.split("|") while data != 1: #如果lis弹出的值不是最后一个就继续循环 for i in data: if i in li: result[i] = data[i] if type(data[i]) == dict: #如果key的值是一个字典 lis.append(data[i]) #把这个字典加入到lis类表中 data = lis.pop() #每次弹出一个列表重新赋值给data 然后再次进入for循环筛查 return result print(select(data,"fld2|fld3|fld7|fld19"))
2. x in range(6) 是合法的布尔表达式
3. 3 > 2 >2 值是False
4.已知x=43,ch=‘A’,y = 1,则表达式(x>=y and ch<‘b’ and y)的值是 答: 1
5.字符串可以比较大小 按ascii码比较 小写比大写大
6.、0x56 < 56结果为True 0x56是十六进制
7.复数的实部和虚部可以是整数
8. == 和 is 的区别:
==是判断值, is是判断值和内存地址 身份运算
9.集合判断交集 intersection() 判断差集difference()
10.斐波那契数列1,2,3,5,8,13,21.....根据这样的规律,编程求出400万以内最⼤的斐波那契数,并求出他 是第几个斐波那契数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
li = [1,1] while True: li.append(li[-1] + li[-2]) if li[-1] > 4000000: print(li[-2]) #最后一个数大于四百万但是已经加到列表,所以取倒数第二个 break #求长度 len(li) - 1
11. update()是用一个字典更新另一个字典,有相同的键则更新值
dicta = {"a":1,"b":2,"c":3,"d":4,"f":"hello"}
dictb = {"b":3,"d":5,"e":7,"m":9,"k":"world"}
要求写2段代码,实现两个字典的相加,
不同的key对应的值保留,相同的key对应的值相加后保 留,如果是字符串就拼接,如上例得到结果为: dictc = {"a":1,"b":5,"c":3,"d":9,"e":7,"m":9,"f":"hello","k":"world"}
for k in dica:
if k in dicb:
dicb[k] = dica[k] + dicb[k] #如果在,修改dicb中key的值
dica.update(dicb) #update()是用一个字典更新一个字典,重复的key覆盖掉原来的值
print(dica)
3.带参数的装饰器
THE = False #设置一个全局变量用来开关装饰器 def log(flag): #在原函数外面再加一层,在下面返回内部函数,加一个参数flag def wrapper(func): def inner(*args,**kwargs): if flag: 这里要判断 print('call : %s'%func.__name__) ret = func(*args,**kwargs) return ret return inner return wrapper @log(THE) #加参数,全局变量 #wrapper = log(FlAG) --> @wrapper --> qqxing = wrapper(qqxing) = inner def qqxing(): print('qqxing') qqxing() #inner()
4.嵌套装饰器
套娃一样,先调用的装饰器在最外层
def wrapper1(func): def inner1(): print('wrapper1 ,before func') func() #f print('wrapper1 ,after func') return inner1 def wrapper2(func): def inner2(): print('wrapper2 ,before func') func() #inner1 print('wrapper2 ,after func') return inner2 @wrapper2 #f = wrapper2(wrapper1(f)) --> f = wrapper2(inner1) --> f = inner2 @wrapper1 def f(): print('in f') f() #inner2() # wrapper2 ,before func # wrapper1 ,before func # in f # wrapper1 ,after func # wrapper2 ,after func
既然选择了远方,便是风雨兼程...