• Python开发基础 day6 装饰器


    (一)闭包函数

    闭包函数:函数内部定义函数,成为内部函数,
    该内部函数包含对外部作用域,而不是对全局作用域名字的引用
    那么该内部函数成为闭包函数

    # name='alex'
    # def func():
    # name='egon'
    # def bar():
    # print(name)
    # return bar
    #
    #
    # b=func()
    # print(b)
    # name='hahahahahahahahahahahahahahahhahahah'
    
    
     
    
     
    
    # def foo():
    # name='ssssssssssssssssssssssssssssssssssssssss'
    # b()
    #
    # foo()
    
     
    
    
    # name='alex'
    # def func():
    # name='egon'
    # def bar():
    # print(name)
    # return bar
    #
    # f=func()
    
     
    
     
    
    # name='alex'
    # def func():
    # name='egon'
    # x=1000000000000000000000
    # def bar():
    # print(name)
    # print(x)
    # a=1
    # b=2
    # return bar
    # #
    # f=func()
    #
    # # print(f.__closure__[0].cell_contents)
    # print(f.__closure__[1].cell_contents)
    
    
    # name='alex'
    # def func():
    # name='egon'
    # x=1000000000000000000000
    # def bar():
    # print(name)
    # print(x)
    # a=1
    # b=2
    # print(bar.__closure__)
    
    # func()

    闭包函数:1 内部函数 2 包含对外部作用域而非全局作用域的引用
    闭包函数的特点:
     自带作用域
     延迟计算

    # name='alex'
    # def func():
    # def bar():
    # print(name)
    # return bar
    #
    # f=func()
    # print(f.__closure__)
    #
    # f()
    
    #
    #
    # money=1000
    # def tell_ino(name):
    # print('%s have money %s' %(name,money))
    #
    # tell_ino('egon')
    #
    # def f1():
    # money=10
    # tell_ino('egon')
    #
    # f1()
    
    #
    # money=1000
    # def f1():
    # money=10
    # def tell_ino(name):
    # print('%s have money %s' %(name,money))
    # tell_ino('egon')
    #
    # f1()
    
     
    
    
    #包一层
    def wrapper():
    money=1000
    def tell_info():
    print('egon have money %s' %(money))
    return tell_info
    
    tell_info=wrapper()
    
    def foo():
    money=100
    tell_info()
    
    # foo()
    
    
    #包两层
    
    # def aaa():
    # name='egon'
    # def wrapper():
    # money=1000
    # def tell_info():
    # print('egon have money %s' %(money))
    # print('my namn is %s' %name)
    # return tell_info
    # return wrapper
    #
    # w=aaa()
    # tell_info=w()
    # print(tell_info.__closure__[0].cell_contents)
    # print(tell_info.__closure__[1].cell_contents)


    '''
    报错NameError: name 'money' is not defined

    原因:
    函数的作用域关系在函数定义阶段就已经固定,与调用位置无关
    无论函数在何处调用,都需要回到定义阶段去找对应的作用域关系
    此例:虽然tell_info('egon')是在foo内调用并且引用money,但仍需要回到定义
    tell_info的阶段去找作用域关系,而定义时tell_info引用的money就是全局的money
    如果全局不存在则抛出异常NameError

    '''


    #定义闭包函数的基本形式


    # def 外部函数名():
    # 内部函数需要的变量
    # def 内部函数():
    # 引用外部变量
    # return 内部函数

    # def deco():
    # x=1
    # def wrapper():
    # print(x)
    #
    # return wrapper
    #
    # wrapper=deco()
    #
    # print(wrapper)
    
     
    
     
    
    # def wrapper():
    # print(x)
    # print(y)
    
    # def deco1():
    # y=2
    # def deco():
    # x=1
    # def wrapper():
    # print(x)
    # print(y)
    #
    # return wrapper
    # return deco
    #
    #
    #
    # deco=deco1()
    #
    # wrapper=deco()
    #
    #
    #
    #
    #
    # wrapper()
    
    
    from urllib.request import urlopen
    
    # print(urlopen('http://www.xiaohua100.cn/').read())
    # print(urlopen('https://www.python.org').read())
    
    # def get(url):
    # return urlopen(url).read()
    #
    #
    # print(get('http://www.xiaohua100.cn/'))
    
    def index(url):
    # url='http://www.xiaohua100.cn/'
    def get():
    return urlopen(url).read()
    return get
    
    
    xiaohua=index('http://www.xiaohua100.cn/')
    
     
    
    python=index('https://www.python.org')
    
    
    baidu=index('http://www.baidu.com')
    
    
    print(python())

    (二)装饰器

    '''
    一:开放封闭原则,对扩展是开放的,对修改是封闭的

    二:装饰器,装饰器本质可以任意可调用对象,被装饰的对象也可以是任意
    可调用对象,
    装饰器的功能是:
    在不修改被装饰对象源代码以及调用方式的前提下为期添加新功能

    原则:
    1.不修改源代码
    2.不修改调用方法
    目标:添加新功能

     

    '''

    # import time
    # import random
    # #装饰器
    # def timmer(func):
    # # func=index
    # def wrapper():
    # start_time = time.time()
    # func() #index()
    # stop_time=time.time()
    # print('run time is %s' %(stop_time-start_time))
    # return wrapper
    # #被装饰函数
    # def index():
    # time.sleep(random.randrange(1,5))
    # print('welecome to index page')
    #
    # def home():
    # time.sleep(random.randrange(1,3))
    # print('welecome to HOME page')
    #
    # index=timmer(index) #index=wrapper
    # home=timmer(home)
    #
    # index() #wrapper()
    # home()
    
     
    
    #装饰器的语法:在被装饰对象的正上方的单独一行,@装饰器名字
    # import time
    # import random
    # #装饰器
    # def timmer(func):
    # def wrapper():
    # start_time = time.time()
    # func()
    # stop_time=time.time()
    # print('run time is %s' %(stop_time-start_time))
    # return wrapper
    # #被装饰函数
    # @timmer #index=timmer(index)
    # def index():
    # time.sleep(random.randrange(1,5))
    # print('welecome to index page')
    # # @timmer #home=timmer(home)
    # # def home():
    # # time.sleep(random.randrange(1,3))
    # # print('welecome to HOME page')
    #
    # index() #wrapper()
    # # home()
    
     
    
    #加多个装饰器
    import time
    import random
    #装饰器
    def timmer(func):
    def wrapper():
    start_time = time.time()
    func()
    stop_time=time.time()
    print('run time is %s' %(stop_time-start_time))
    return wrapper
    def auth(func):
    def deco():
    name=input('name: ')
    password=input('password: ')
    if name == 'egon' and password == '123':
    print('login successful')
    func() #wrapper()
    else:
    print('login err')
    return deco
    
    #被装饰函数
    @auth #index=auth(wrapper) #index=deco #index=auth(wrapper) #index=deco
    @timmer #index=timmer(index) #index=wrapper
    def index():
    # time.sleep(random.randrange(1,5))
    time.sleep(3)
    print('welecome to index page')
    
    
    def home():
    time.sleep(random.randrange(1,3))
    print('welecome to HOME page')
    
    # index() #deco()
    # home()
    
     
    
     
    
     
    
    
    #装饰器修订
    import time
    import random
    #装饰器
    def timmer(func):
    def wrapper(*args,**kwargs):
    start_time = time.time()
    res=func(*args,**kwargs)
    stop_time=time.time()
    print('run time is %s' %(stop_time-start_time))
    return res
    return wrapper
    #被装饰函数
    
    @timmer
    def index():
    time.sleep(random.randrange(1,5))
    print('welecome to index page')
    @timmer
    def home(name):
    time.sleep(random.randrange(1,3))
    print('welecome to %s HOME page' %name)
    return 123123123123123123123123123123123123123123
    
    
    index()
    
     
    
     
    
     
    
     
    
    
    res1=index()
    print('index return %s' %res1)
    res2=home('egon') #wraper()
    print('home return %s' %res2)

    编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
    # 注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式

    # user_dic={
    # 'egon':'123',
    # 'alex':'alex3714',
    # 'wupeiqi':'wu13',
    # 'yuanhao':'123123'
    # }
    
    # with open('db.txt','w',encoding='utf-8') as f:
    # f.write(str(user_dic))
    
    #
    # with open('db.txt','r',encoding='utf-8') as f:
    # res=f.read()
    # # print(res,type(res))
    # user_dic=eval(res)
    #
    # print(user_dic,type(user_dic))
    
    # db_path=r'C:UsersAdministratorPycharmProjectspython5期day8db.txt'
    #
    # login_dic={
    # 'user':None,
    # 'status':False,
    # }
    #
    #
    # def auth(func):
    # def wrapper(*args,**kwargs):
    # if login_dic['user'] and login_dic['status']:
    # res = func(*args, **kwargs)
    # return res
    #
    # name=input('your name: ')
    # password=input('your password: ')
    # with open(db_path,'r',encoding='utf-8') as f:
    # user_dic=eval(f.read())
    #
    # if name in user_dic and password == user_dic[name]:
    # print('login ok')
    # login_dic['user']=name
    # login_dic['status']=True
    # res=func(*args,**kwargs)
    # return res
    # else:
    # print('login err')
    #
    # return wrapper
    #
    #
    # @auth #auth(index)
    # def index():
    # print('welecome to index')
    #
    # @auth
    # def home(name):
    # print('welecome %s to home page' %name)
    #
    #
    # index()
    #
    # home('egon')
    
     
    
     
    
     
    
    # dic={'x':1}
    # l=[1,2,3]
    # salary=1000
    # def foo():
    # # print(dic)
    # dic['x']=2
    # dic['y']=3
    # l.append(4)
    # global salary
    # salary=0
    # foo()
    # print(dic)
    # print(l)
    # print(salary)

    '''
    五:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
    '''

    from urllib.request import urlopen
    import os
    
    cache_path=r'C:UsersAdministratorPycharmProjectspython5期day8cache.txt'
    def make_cache(func):
    def wrapper(*args,**kwargs):
    if os.path.getsize(cache_path):
    #有缓存
    print('33[45m=========>有缓存33[0m')
    with open(cache_path,'rb') as f:
    res=f.read()
    
    else:
    res=func(*args,**kwargs) #下载
    with open(cache_path,'wb') as f: #制作缓存
    f.write(res)
    
    return res
    
    return wrapper
    
    @make_cache
    def get(url):
    return urlopen(url).read()
    
    
    # print('================>first')
    # print(get('https://www.python.org'))
    # print('================>second')
    # print(get('https://www.python.org'))
    # print('================>third')
    # print(get('https://www.python.org'))


    #缓存多个不同网站的内容:
    #思路:hash每个url,用得到的值做成文件名,一个网站一个文件名,
    # 然后每次根据传进来的url进行hash得到的结果去寻找文件

    #
    # s='hello 123'
    # print(hash(s))
    # s='hello 123'
    # print(hash(s))
    
     
    
     
    
     
    
    #
    # def f1():
    # print('from f1')
    #
    #
    # def f2():
    # print('from f2')
    #
    # def f3():
    # print('from f3')
    #
    # func_dic={
    # 'f1':f1,
    # 'f2':f2,
    # 'f3':f3
    # }
    #
    # while True:
    # cmd=input('>>:').strip()
    # if cmd in func_dic:
    # func_dic[cmd]()
    
     
    
    func_dic={}
    
    def deco(key):
    def deco2(func):
    func_dic[key]=func
    return deco2
    
    @deco('f1')
    def f1():
    print('from f1')
    
    @deco('f2')
    def f2():
    print('from f2')
    @deco('f3')
    def f3():
    print('from f3')
    
    
    print(func_dic)
    
    while True:
    cmd=input('>>:').strip()
    if cmd in func_dic:
    func_dic[cmd]()
  • 相关阅读:
    json_decode 转数组
    json_encode转义中文问题
    ECshop后台新功能权限添加
    mysql中int、bigint、smallint 和 tinyint的区别与长度的含义
    mysql数据库表设计小数类型
    mysql group_concat用法
    PHP socket通信之UDP
    本地tp项目上传服务器报runtime/cache错误
    mysql 命令一套
    linux 9 -- 交互式使用Bash Shell
  • 原文地址:https://www.cnblogs.com/bsxq/p/7009099.html
Copyright © 2020-2023  润新知