python之路——12

王二学习python的笔记以及记录,如有雷同,那也没事,欢迎交流,wx:wyb199594

复习

    1.装饰器
开发原则:开放封闭原则
作用:不改变原函数的调用方式,为函数前后扩展功能
本质:闭包函数
from functools import wraps
def wrapper(f):
@wraps(f)
def inner(*args, **kwargs):
增加功能语句
ret = f(*args, **kwargs)
return ret
return inner
@wrapper

学习内容

装饰器进阶
1.functool.wraps
2.带参数的装饰器
* 接收聚合;传递打散
多个装饰器装饰同一个函数

代码区

1. 装饰器

def outer(*args):
    print(args)
    print(*args)

    def inner(*args):
        print('inner', args)
    inner(*args)


outer(1, 2, 3, 4)   # (* 接收聚合;传递打散)

2.带参数的装饰器

from functools import wraps
import time
flag = False
def timer_out(flag):
    def wrapper(f):
        @wraps(f)
        def inner(*args, **kwargs):
            if flag:
                start = time.time()
                ret = f(*args, **kwargs)
                end = time.time()
                print(end - start)
                return ret
            else:
                ret = f(*args, **kwargs)
                return ret
        return inner
    return wrapper

@timer_out(flag)
def wahaha():
    time.sleep(0.01)
    print('娃哈哈')

# wahaha = wrapper(wahaha)

wahaha()
print(wahaha.__name__)

3.多个装饰器装饰一个函数

def wrapper1(func):   #  func-----f
    def inner1():
        print('wrapper1_before')
        func()
        print('wrapper1_after')
    return inner1

def wrapper2(func):   # inner1
    def inner2():
        print('wrapper_2_before')
        func()
        print('wrapper2_after')
    return inner2

@wrapper2  # f = wrapper2(f)   f----inner2
@wrapper1  # f = wrapper1(f)   f----inner1
def f():
    print('in f')

f()

4.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),# 要求登录成功一次,后续的函数都无需再输入用户名和密码

 

Flag = True
c = 1

def outer(flag):
    def wrapper(f):
        def inner(*args, **kwargs):
            global c
            li = []
            with open('log', 'r', encoding='utf-8') as f1:
                for line in f1:
                    li.append(line)
            li[0] = li[0].strip()
            if flag and c:
                user_acc = input('请输入账号')
                user_ans = input('请输入密码')
                if user_acc == li[0] and user_ans == li[1]:
                    print('认证成功,执行函数')
                    ret = f(*args, **kwargs)
                    c = 0
                    return ret
                else:
                    print('认证失败,返回')
            else:
                ret = f(*args, **kwargs)
                return ret
        return inner
    return wrapper
@outer(Flag)
def wahaha():
    print('娃哈哈函数体')
@outer(Flag)
def qqxing():
    print('QQ星函数体')

wahaha()
qqxing()
'''
# 老师答案
'''
FLAG = False
def login(func):
    def inner(*args,**kwargs):
        global FLAG
        """登录程序"""
        if FLAG:
            ret = func(*args, **kwargs)  # func是被装饰的函数
            return ret
        else:
            username = input('username : ')
            password = input('password : ')
            if username == 'boss_gold' and password == '22222':
                FLAG = True
                ret = func(*args,**kwargs)      #func是被装饰的函数
                return ret
            else:
                print('登录失败')
    return inner

@login
def shoplist_add():
    print('增加一件物品')

@login
def shoplist_del():
    print('删除一件物品')

shoplist_add()
shoplist_del()
View Code

5.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件

'''
from functools import wraps
def wrapper(f):
    @wraps(f)
    def inner(*args,**kwargs):
        li = []
        ret = f(*args,**kwargs)
        with open('log1','r',encoding='utf-8') as f1, open('log1.bak','w',encoding='utf-8') as f2:
            for line in f1:
                li.append(line)
            li.append(inner.__name__)
            f2.writelines(li)
        import os
        os.remove('log1')
        os.rename('log1.bak', 'log1')
        return ret
    return inner
@wrapper
def wahaha():
    print('娃哈哈函数体')
@wrapper
def qqxing():
    print('QQ星函数体')

wahaha()
qqxing()
'''
# 老师答案
'''
# def log(func):
#     def inner(*args,**kwargs):
#         with open('log','a',encoding='utf-8') as f:
#             f.write(func.__name__+'\n')
#         ret = func(*args,**kwargs)
#         return ret
#     return inner
#
# @log
# def shoplist_add():
#     print('增加一件物品')
#
# @log
# def shoplist_del():
#     print('删除一件物品')

# shoplist_add()
# shoplist_del()
# shoplist_del()
# shoplist_del()
# shoplist_del()
# shoplist_del()
'''
View Code

6.# 进阶作业(选做):

# 1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
# 2.为题目1编写装饰器,实现缓存网页内容的功能:
# 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
import os
from urllib.request import urlopen
def cache(func):
    def inner(*args, **kwargs):
        if os.path.getsize('web_cache'):
            with open('web_cache','rb') as f:
                return f.read()
        ret = func(*args, **kwargs)
        with open('web_cache','wb') as f:
            f.write(b'********' + ret)
        return ret
    return inner

@cache
def get(url):
    code = urlopen(url).read()
    return code
ret = get('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)

 

 
posted @ 2019-03-26 14:26  王二被占用  阅读(191)  评论(0)    收藏  举报