装饰器 面试题错误点

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分)
#类递归思想 #栈的思想
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万以内最⼤的斐波那契数,并求出他 是第几个斐波那契数。

 

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

 

 

 

posted @ 2017-09-01 17:35  选择远方,风雨兼程。  阅读(349)  评论(0编辑  收藏  举报