• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
KK筑梦人
博客园    首页    新随笔    联系   管理    订阅  订阅

生成器部分回顾、装饰器、装饰器预演、装饰器实现、加返回值、加参数、加验证功能、带参数验证功能(少用) 第十天 2018.10.24

生成器部分回顾

装饰器、装饰器预演、装饰器实现、加返回值、加参数

装饰器加验证功能、带参数验证功能

生成器部分回顾:

Pythonic:保证代码可读性的前提下,尽可能缩短代码行数

#解压方式11对应
#应用于某种场景
a,b,c='hel'
#多一报错少一报错
[0,2,3,6,5,1,8,7,4]
a,*d,c=l
a=1,c=4,*d=[中间所有]
#交换值
a=1,b=2
a,b=b,a

for循环可以直接遍历生成器函数

def test():
    for i in range(4):
        yield i
t=test()

for i in t:
    print(i)
t1=(i for i in t)     #---->t1为生成器
print(list(t1))
list() #为空 ---->t1为生成器遍历t,t已经被上面遍历过了,生成器只能被遍历一次

t1=(i for i in t)     #---->t1只是一个生成器,生成器只能执行一次
t2=(i for i in t1)    #---->t1为生成器里面的东西
print(list(t1))       #遍历t1,t1中的值已经被取空
print(list(t2))       #为空,遍历t1时为遍历空列表

装饰器:本质就是函数,功能是:为其他函数添加附加功能

原则:不修改被修饰函数的源代码;不修改被修饰函数的调用方式

函数加个计算函数执行时间功能

函数源代码和调用方式被修改后,有可能会影响该函数和其他函数之间的执行关系,造成原本功能出问题

import time
def cal(l):
    start_time=time.time()     #函数开始执行时间
    res=0
    for i in l:
        time.sleep(0.1)
        res+=i               #计算累加range(100)的结果  
    stop_time = time.time()  #函数结束执行时间
    print('函数的运行时间是%s' %(stop_time-start_time))
    return res               #获得函数的返回值

print(cal(range(100)))       #该函数是计算累加,打印cal()函数的返回值

装饰器预演

import time                                 #装饰器核心---->风湿理论---->函数即变量
def timmer(func):                           #函数即变量---->把待装饰器修饰的函数当成一个变量
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print("函数的执行时间为%s"%(stop_time-start_time))
        return res
    return wrapper

@timmer                     #装饰器---->个人理解为:给待装饰函数增加一个功能
#cal=timmer(cal)            #装饰器作为一个整体函数在变量(待装饰函数)执行后,自身不会变化
                            #被执行过得变量(待装饰函数)自身也不会发生改变,即被装饰函数自身不变且自身调用方式不变
def cal(l):            #原函数功能为计算某个可迭代对象的和
    res=0
    for i in l:
        time.sleep(0.5)
        res+=i         #可以计算整数类型---->列表,元组,集合
    return res

res=cal(range(10))
print(res)

  

装饰器的知识储备

装饰器=高阶函数+函数嵌套+闭包

高阶函数:函数接收的参数是一个函数名或者函数的返回值是一个函数名

修改了函数的调用方式

接收的参数是一个函数名

import time
def foo():
    time.sleep(3)
    print('你好啊林师傅')

def test(func):
    # print(func)    #---->foo()的内存地址
    start_time=time.time()
    func()           #运行foo函数func形参传递的是foo函数
    stop_time = time.time()
    print('函数运行时间是  %s' % (stop_time-start_time))
# foo()     #----->本来foo函数调用方式
test(foo)   #----->现在foo函数调用方式,通过test函数调用

同时满足两个高阶函数的条件

def foo():
    print('from the foo')
def test(func):
    return func

res=test(foo)   #test()的运行结果,test的返回值是foo函数
# print(res)    #res是foo函数的内存地址
res()           

foo=test(foo)   #test()的运行结果,test的返回值是foo函数
# # print(foo)  #foo是foo函数的内存地址
foo()           #不改变函数的调用方式,不修改源代码

#不修改foo源代码
#不修改foo调用方式

  

import time
def foo():
    time.sleep(3)
    print('来自foo')

#多运行一次   
def timer(func):
    start_time=time.time()
    func()                  #运行一次传入函数,从而计算运行一次所需的时间
    stop_time = time.time()
    print('函数运行时间是  %s' % (stop_time-start_time))
    return func             #返回值为传入函数
foo=timer(foo)              #给原foo函数增加功能,增加的功能为timer()函数的函数体
                            #但是timer函数中会调用一次foo函数
foo()                       #不改变函数的调用方式---->调用foo函数
#变成执行foo函数---->执行timer函数(内会单独执行一次foo函数)
#因此foo函数调用方式没改变却会被多调用一次

#没有修改被修饰函数的源代码,也没有修改被修饰函数的调用方式,但是也没有为被修饰函数添加新功能
def timer(func):
    start_time=time.time()
    return func               #函数返回值后面的语句不会被执行
    stop_time = time.time()   #未执行
    print('函数运行时间是  %s' % (stop_time-start_time))   #未执行

foo=timer(foo)
foo()

嵌套函数:函数内部重新定义了另一个函数

print(locals())----->打印当前层的局部变量

func()的局部变量有seven、outer函数的地址(风湿理论--->函数即变量)

def father(auth_type):
    # print('from father %s' %name)
    def son():
        # name='.....'
        # print('我的..是%s' %name)            #此层没有auth_type则向上找
        def grandson():
            print('我的...是%s' %auth_type)  #此层没有auth_type则向上找
        grandson()
    # print(locals())
    son()
# father('....')
father('filedb')
#每层函数相当于一个包,里层需要的局部变量本包里找不到向上找,上一层找不到继续向上找,以此类推;
#闭---->封装;封装变量  
#grandson封装的变量:name  son封装的变量:grandson   father封装的变量:son、name
#grandson找变量,先找自己包里。son找变量,先在自己包里找,找不到去上一层father包里找

装饰器实现  

import time
def timmer(func):  # func=test
    def wrapper():
        # print(func)
        start_time = time.time()
        func()  # 就是在运行test() --->跳回timmer,然后执行test()函数
        stop_time = time.time()
        print('运行时间是%s' % (stop_time - start_time))

    return wrapper    #返回test()--->test()收到了wrapper函数的地址

@timmer  # test=timmer(test) timmer--->装饰器
         #执行函数timmer,将test()传入形参运行,timmer函数执行的结果是wrapper函数的地址
         #test收到了wrapper函数的地址
def test():
    time.sleep(3)
    print('test函数运行完毕')

test()  #运行wrapper函数

# 用res改变了函数的调用方式---->原来用test()直接调用
# res=timmer(test)  #返回的是wrapper的地址
# res()  #执行的是wrapper()

# test=timmer(test)  #返回的是wrapper的地址
# test()  #执行的是wrapper()

#  @timmer  就相当于 test=timmer(test)
#  @+装饰器名

加返回值

def timmer(func):  # func=test
    def wrapper():
        # print(func)
        start_time = time.time()
        res=func()   # 就是在运行test()并将test函数返回值赋值给res
        stop_time = time.time()
        print('运行时间是%s' % (stop_time - start_time))
        return res  #返回值为res是test函数的返回值;此返回值为wrapper函数的返回值
                    #用wrapper函数的返回值接收test函数的返回值
    return wrapper  #此返回值为timmer函数的返回值

@timmer  # test=timmer(test) timmer--->装饰器
def test():
    time.sleep(3)
    print('test函数运行完毕')
    return '这是test的返回值'
res=test()       #res为test函数的返回值,此处test()为wrapper函数的地址
print(res)

 加参数:

import time
def timmer(func): #func=test1
    def wrapper(*args,**kwargs): #test('linhaifeng',age=18)  args=('linhaifeng')  kwargs={'age':18}
        start_time=time.time()
        res=func(*args,**kwargs) #就是在运行test()         func(*('linhaifeng'),**{'age':18})
                                 #func()即test(),实参根据闭包向上一级找即wrapper函数的实参
        stop_time = time.time()
        print('运行时间是%s' %(stop_time-start_time))
        return res          #为wrapper函数的返回值,此处是构造器所增加函数的传递
    return wrapper

@timmer #test=timmer(test)
def test(name,age):
    time.sleep(3)
    print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age))
    return '这是test的返回值'

@timmer
def test1(name,age,gender):
    time.sleep(1)
    print('test1函数运行完毕,名字是【%s】 年龄是【%s】 性别【%s】' %(name,age,gender))
    return '这是test1的返回值'

# res=test('linhaifeng',age=18)  #就是在运行wrapper
# # print(res)
# test1('alex',18,'male')
test('ALEX',15)
test1('alex',18,'male')


#可以把wrapper函数中的res=和return res返回值都删除。程序执行结果无变化
#只有赋值--->空类型;空类型不需要返回值;所以上面的res赋值只是得到test()函数里面的打印
#上面之所以出现返回值是因为打印了原函数返回值,并不是空类型

加个验证功能的装饰器:  

user_list=[
    {'name':'alex','passwd':'123'},
    {'name':'linhaifeng','passwd':'123'},
    {'name':'wupeiqi','passwd':'123'},
    {'name':'yuanhao','passwd':'123'},
]
current_dic={'username':None,'login':False}   #判断是否登录,以及登录状态;登录后才可以执行index()等3个函数

def auth_func(func):
    def wrapper(*args,**kwargs):
        if current_dic['username'] and current_dic['login']:   #如果用户名以及登录状态都True,则...
            res = func(*args, **kwargs)     #执行func函数
            return res                     #使res有存在的意义,wrapper函数的返回值为res
                             #登录成功密码正确后后俩函数不用执行wrapper函数下面另外的操作
        username=input('用户名:').strip()    #strip()去空格
        passwd=input('密码:').strip()
        for user_dic in user_list:         #遍历列表,判断用户是否为列表中注册过的人以及密码是否正确
            if username == user_dic['name'] and passwd == user_dic['passwd']:     #如果用户名在列表中且密码也在列表中
                current_dic['username']=username      #改变判断是否登录字典中的两项
                current_dic['login']=True             #改变全局变量current_dic中的,所以if中局部变量调用改变后的全局变量
                res = func(*args, **kwargs)
                return res
        else:
            print('用户名或者密码错误')

    return wrapper

@auth_func
def index():
    print('欢迎来到京东主页')

@auth_func
def home(name):
    print('欢迎回家%s' %name)

@auth_func
def shopping_car(name):
    print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))

print('before-->',current_dic)  #执行index函数前,判断登录状态及密码字典里的内容
index()
print('after--->',current_dic)  #执行index函数后,判断登录状态及密码字典里的内容
home('❤')
shopping_car('您')

带参数验证功能的装饰器(比较少用):  

user_list=[
    {'name':'alex','passwd':'123'},
    {'name':'linhaifeng','passwd':'123'},
    {'name':'wupeiqi','passwd':'123'},
    {'name':'yuanhao','passwd':'123'},
]
current_dic={'username':None,'login':False}

def auth(auth_type='filedb'):
    def auth_func(func):
        def wrapper(*args,**kwargs):
            print('认证类型是',auth_type)
            if auth_type == 'filedb':
                if current_dic['username'] and current_dic['login']:
                    res = func(*args, **kwargs)
                    return res
                username=input('用户名:').strip()
                passwd=input('密码:').strip()
                for user_dic in user_list:
                    if username == user_dic['name'] and passwd == user_dic['passwd']:
                        current_dic['username']=username
                        current_dic['login']=True
                        res = func(*args, **kwargs)
                        return res
                else:
                    print('用户名或者密码错误')
            elif auth_type == 'ldap':
                print('鬼才特么会玩')
                res = func(*args, **kwargs)
                return res
            else:
                print('鬼才知道你用的什么认证方式')
                res = func(*args, **kwargs)
                return res

        return wrapper
    return auth_func

@auth(auth_type='filedb') 
     #auth_func=auth(auth_type='filedb')-->@auth_func 附加了一个auth_type  --->index=auth_func(index)
def index():
    print('欢迎来到京东主页')

@auth(auth_type='ldap')
def home(name):
    print('欢迎回家%s' %name)
#
@auth(auth_type='sssssss')
def shopping_car(name):
    print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))

# print('before-->',current_dic)
# index()
# print('after--->',current_dic)
# home('❤')
shopping_car('您')

  

 

 

 

 

 

 

  

posted @ 2018-10-24 20:11  KK筑梦人  阅读(137)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3