Python全栈学习Day12 生成器 装饰器进阶

昨日内容复习

装饰器:

原则:开放封闭原则
作用:在不改变原函数的调用方式的情况下,在函数的前后添加功能
装饰器的本质:闭包函数

def wrapper(f):
    def inner(*args, **kwargs):
        print('在被装饰函数之前做的事')
        ret = f(*args, **kwargs)
        print('在被装饰函数之后做的事')
        return ret
    return inner

@wrapper
def holiday(day):
    print('全体放假%s天'%day)
    return 'ok'


res = holiday(3)
print(res)

作业讲解

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

FLAG = False  # 刚开始没有登录,是False状态
def login(func):
    def inner(*args, **kwargs):
        global FLAG
        ''' 登入程序 '''
        if FLAG:
            ret = func(*args, **kwargs)
            return ret
        else:
            usernanme = input('username:')
            password = input('password:')
            if usernanme == 'mashengde' and password == '123456':
                FLAG = True
                ret = func(*args, **kwargs)
            else:
                print('账号密码错误!')
            return ret
    return inner


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


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


shoplist_add()
shoplist_del()

第二题:编写装饰器,为多个函数加上记录调用功能,要求梅调用函数都将被调用的函数名称写入文件

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_del()
shoplist_del()

进阶作业:

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

from urllib.request import urlopen


def get(url):
   html_code = urlopen(url).read()
   return html_code


ret = get('http://www.baidu.com')
print(ret)

第二题:为题目1编写装饰器,实现缓存网页内容的功能,具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就先从文件中读取网页内容,否则就去下载

import os
from urllib.request import urlopen


def cache(func):
    def inner(*args, **kwargs):
        if os.path.getsize('log'):
            with open('log', 'rb') as f:
                return f.read()
        ret = func(*args, **kwargs)
        with open('log', 'wb')as f:
            f.write(b'*************'+ret)
        return ret
    return inner


@cache
def get(url):
   html_code = urlopen(url).read()
   return html_code


ret = get('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)

今日内容

生成器

本质:迭代器
生成器函数:
函数中有yiled关键字函数就是生成器函数,且不能和return共用,需要卸载函数内部
例子 ;

def generator():
    print(1)
    yield 'a'  # 只要有yield就是生成器函数


ret = generator()
print(ret)

在这里插入图片描述
生成器函数执行后会形成生成器作为返回值

def generator():
    print(1)
    yield 'a'  # 只要有yield就是生成器函数


ret = generator()
print(ret)
print(ret.__next__())

在这里插入图片描述
yiled不会结束,但每一次往下执行需要一次—next—

def generator():
    print(1)
    yield 'a'
    print(2)
    yield 'b'


ret = generator()
print(ret)
print(ret.__next__())
print(ret.__next__())

在这里插入图片描述
for循环执行

def generator():
    print(1)
    yield 'a'
    print(2)
    yield 'b'


ret = generator()
for i in ret:
    print(i)

监听器小例子

def tail(filename):
    f = open(filename, encoding='utf-8')
    while True:
        line = f.readline()
        if line:
            yield line.strip()


g = tail('你好')
for i in g:
    print(i) 

装饰器进阶

带参数的装饰器(三层装饰器)

    import time
    FLAG = True
    
    
    def out(flag):
        def timer(func):
            def inner(*args, **kwargs):
                if flag:
                    start = time.time()
                    ret = func(*args, **kwargs)
                    end = time.time()
                    print(end - start)
                    return ret
                else:
                    ret = func(*args, **kwargs)
                    return ret
            return inner
        return timer
    
    
    @out(FLAG)
    def wahah():
        time.sleep(0.1)
        print('hellp')
    
    
    @out(FLAG)
    def erguotou():
        time.sleep(0.1)
        print('hahahah')
    
    
    wahah()
    erguotou()
**多个装饰器装饰一个函数**
def wrapper1(func):
    def inner1():
        print('1,before')
        func()
        print('1,after')
    return inner1


def wrapper2(func):
    def inner2():
        print('2,before')
        func()
        print('2,after')
    return inner2


@wrapper1
@wrapper2
def f():
    print('in f')


f()

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值