day20 装饰器补充

Python之路,Day8 = Python基础8

装饰器
from functools imoort wraps # 保留原函数所有信息,比如:用__doc__查看注释的时候,显示原来的注释
def func01(func):
  @wraps(func) # 用__doc__查看注释的时候,显示原来的注释
  def wrapper(*args, **kwargs):
    print(‘func01---------------------01‘)
    res = func(*args, **kwargs)
    print(‘func01---------------------02‘)
    return res
  # 上面的效果就相当于在这里加了一句 wrapper.__doc__ = func.__doc__
  return wrapper

  装饰器的参数:
    再包一层

def doco(file_type = ‘file‘):
    def outer(func):
        def wrapper(*args, **kwargs):
            if file_type == ‘file‘:
                print(‘with open file‘)
            elif file_type == ‘mysql‘:
                print(‘deal with mysql‘)
            else:
                print(‘i do not konw how to deal‘)
            res = func(*args, **kwargs)
            return res
        return wrapper
    return outer

@doco(‘file‘)
def func1():
    print(‘fucn1‘)

@doco(‘mysql‘)
def func2():
    print(‘fucn2‘)

@doco(‘abc‘)
def func3():
    print(‘fucn3‘)

func1()
func2()
func3()

迭代器
  1.重复
  2.基于上一次的结果
  可迭代对象:
    python为了提供一种不依赖于索引的迭代方式,
    会为一些对象内置 __iter__ 方法,
    obj.__iter__称为可迭代的对象
      obj.__iter__() 得到的结果就是迭代器
      得到的迭代器,既有__iter__又有__next__方法
        __iter__:
        __next__: 返回下一个值
    好处:
      1.可以不依赖索引
      2.惰性计算,节省内存
    缺点:
      1.取值麻烦,需要一个一个取值
      2.不能往回取值
      3.不能获取迭代器的长度

========================homework================

# 整理今天装饰器代码(每人手写一份,注意,是手写,交到小组长手里,明天我检查),准备明天默写
def demeo(file_type = ‘file‘):
    def outer(func):
        def inner(*args, **kwargs):
            if file_type == ‘file‘:
                print(‘deal with \033[35;0mfile\033[0m...‘)
            elif file_type == ‘mysql‘:
                print(‘deal with \033[35;0mmysql\033[0m...‘)
            else:
                print("deal with \033[35;0mothers\033[0m...")
            res = func(*args, **kwargs)
            return res
        return inner
    return outer

@demeo()
def f1():
    print("my name is f1...")

@demeo(‘mysql‘)
def f2():
    print(‘f2 is my name...‘)

@demeo(‘abc‘)
def f3():
    print(‘is me, f3...‘)

f1()
f2()
f3()
# 2 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到文件中#  注意:时间格式的获取#     import time#     time.strftime(‘%Y-%m-%d %X‘)
import time

log_path = r‘C:\Users\Administrator\PycharmProjects\老男孩全栈5期\homework\day08\log\log.log‘

def outer(func):
    def inner(*args, **kwargs):
        with open(log_path, ‘a‘, encoding=‘utf-8‘) as f:
            log_info = time.strftime(‘%Y-%m-%d %X ‘) + func.__name__ + ‘ run\n‘
            f.write(log_info)

        res = func()

        return res
    return inner

@outer
def f1():
    print("This is f1.....")

f1()
# 3 判断下列数据类型是可迭代对象or迭代器## s=‘hello‘# l=[1,2,3,4]# t=(1,2,3)# d={‘a‘:1}# set={1,2,3}# f=open(‘a.txt‘)## 4 分别用依赖索引和不依赖索引两种方式迭代上述对象
from collections import Iterable

s=‘hello‘
l=[1,2,3,4]
t=(1,2,3)
d={‘a‘:1}
set={1,2,3}
f=open(‘a.txt‘)

def print_while(a):
    count = 0
    while count < len(a):
        print(a[count])
        count += 1
def print_for(a):
    for i in a:
        if isinstance(a, dict):
            print(i,a[i])
        else:
            print(i)

print(‘  s is Iterable: %s‘%isinstance(s, Iterable))
print_while(s)
print_for(s)

print(‘  l is Iterable: %s‘%isinstance(l, Iterable))
print_while(l)
print_for(l)

print(‘  t is Iterable: %s‘%isinstance(t, Iterable))
print_while(t)
print_for(t)

print(‘  d is Iterable: %s‘%isinstance(d, Iterable))
# print_while(d)
print_for(d)

print(‘set is Iterable: %s‘%isinstance(set, Iterable))
# print_while(set)
print_for(set)

print(‘  f is Iterable: %s‘%isinstance(f, Iterable))
# print_while(f)
print_for(f)
# 5 选做题:#  基于课上所讲网页缓存装饰器的基础上,实现缓存不同网页的功能#  要求,用户提交的不同url,都能缓存下来,对相同的url发起下载请求,优先从缓存里取内容
import os, time, hashlib

#
# print(hash(‘abcdefg‘))
# print(hash(‘abcdefg‘))

cach_dir = "C:\\Users\\Administrator\\PycharmProjects\\老男孩全栈5期\\homework\\day08\\cach\\"      # 设置一个缓存的目录
print(cach_dir)

if not os.path.exists(cach_dir):          # 查看缓存目录是否存在,如果不存在,创建
    os.mkdir(cach_dir)

url_dict = {‘baidu‘:‘http://www.baidu.com‘,
            ‘52pojie‘:‘http://www.52pojie.cn‘,
            }                                                # 创建一个字典,将已经知道的网址放入里面,下次可以继续使用

from urllib.request import urlopen                 # 导入一个可以下载网页的模块

def wrapper(func):
    """
    这是个装饰器,主要的作用是接收一个url的路径,然后返回这个网页的代码
    :param func:
    :return:
    """
    def inner(*args, **kwargs):

        url_name = args[0]                         # url_name,就是想要下载的网页的名字
        sha1 = hashlib.sha1()                         # 调用加密算法 sha1
        sha1.update(url_name.encode())                    # 将url 进行加密,得到结果,后期用来查看缓存是否存在
        sha1_name = sha1.hexdigest()                         # 将加密后的 url(字符串) ,赋值给 sha1_name
        file_name = cach_dir + sha1_name                   # 确定文件路径

        url_dict[args[0].split(‘.‘)[1]] = args[0]               #  将网页信息写入字典中,如果存在,则更新

        if os.path.exists(file_name) and os.path.getsize(file_name) > 0:        # 判断缓存文件是否存在,大小是否大于 0
            with open(file_name, ‘rb‘) as f:          # 打开文件,并且用 rb 二进制的方式打开
                print(‘缓存已经存在,正在读取。。。‘)
                time.sleep(2)
                return f.read()

        # 将新网址加入字典中

        # url_dict[args[0].split(‘.‘)[1]] = args[0]               #  将网页信息写入字典中,如果存在,则更新

        print(‘正在从网上下载。。。‘)
        time.sleep(2)
        res = func(*args, **kwargs)

        with open(file_name, ‘wb‘) as f:
            f.write(res)
        # input(‘回车键结束。。。。‘)
        return res
    return inner

@wrapper
def get(url):
    return urlopen(url).read()

# res = get(‘http://www.baidu.com‘)
# print(res.decode())

# print(get(‘http://www.baidu.com‘).decode())

while True:
    choose_list = []                 # 这里我定义了一个列表,主要是把存放地址的字典的 key 放进去,因为字典是无须的,我想实现输入序号(下表)的方式选择地址,用列表的话,可以实现数字(下标)对应列表元素(字典的keys)
    for c, i in enumerate(url_dict): # 打印序号,并循环打印字典的keys
        choose_list.append(i)        # 分别将 每个 key 放入到列表中,这样的话,下面打印选项的时候,我就可以通过对应关系找到 用户所选择的网址是哪一个
        print(‘ %s  %s\t\t%s‘%(c+1, i, url_dict[i]))            # 将字典中的内容打出来,例如:  1   baidu    www.baidu.com
    choose = input(‘\n请输入序号或直接输入网址:http://www.baidu.com\n>>>‘).strip()   # 这里获取一个用户的选择
    if choose.upper() == "Q":                    # 如果选择是 ‘q‘ 或者 ‘Q‘, 那么退出
        break
    elif choose.isdigit() and 0 < int(choose) <= len(choose_list):   # 如果 choose 是数字,而且,数字的大小等于列表的长度(也就是说选择范围为打印菜单的序号)

        res = get(url_dict[choose_list[int(choose) - 1]])           # 那么,就把这个选择对应的网址传给函数   get(), 得到的返回值给 res
        print(res)
    elif ‘http://‘ in choose:                               # 如果, choose 中包含 ‘http://‘ 这几个字符的话,我就认为,你输入了一个完整的网址
        res = get(choose)                      # 这个时候,我就将这个完整的网址传个  get()  函数,将返回值给 res
        print(res)
    else:                   # 如果都不满足,提示输入错误
        print(‘输入错误‘)
    time.sleep(2)
时间: 2024-10-07 06:28:39

day20 装饰器补充的相关文章

Python札记 -- 装饰器补充

本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: 1 #!/usr/bin/env python 2 3 def deco(func): 4 def wrapper(): 5 print "Wrap start" 6 func() 7 print "Wrap end\n" 8 return wrapper 9 10 @deco 11 def foo(): 12 """Do

Python基础day-8[装饰器补充,迭代器(未完)]

wraps模块: 让函数保留原来的说明信息. 在闭包函数上面 @wraps 可以把原代码的解释,引用到装饰器中,让用户彻底无法感知装饰器的存在 使用 func.__doc__ 和 print(help(func))来查看函数的注释信息 from functools import wraps import time def coutime(func): @wraps(func) #调用wraps模块 def wrapper(*args,**kwargs): # 'a1231231231231232

Python 装饰器补充

定义了一些函数,这些函数都要被外部所调用,但是这些函数在被调用之前,都有些相同的功能需要被实现,在这种情况下,装饰器是最好的解决方案: def f1(): print ("F1") def f2(): print ("F2") 在另一个模块中调用的时候 import s1 s1.f1() s1.f2()执行结果:F1F2 这个时候,我们需要在f1,f2中分别添加打印日志的功能,于是,函数的定义变成了 def f1(): print ("log")

python装饰器(补充完整)

一.什么是装饰器         1.对现有已经实现功能的代码进行扩展. 2.不用修改被撞时对象的源代码和调用方法 二.装饰器的使用 无参数装饰器: 示例: def zsq(func): def yz(args): print("验证") return func(args) return yz @zsq def hs(name): print("我是一个函数%s"%name) return "hs fanhuizhi" ceshi = hs(&q

python之-- 装饰器

高阶函数+嵌套函数 == 装饰器 什么是装饰器: 其实也是一个函数. 功能:为其他的函数添加附加功能 原则:不能修改被装饰的函数的源代码和调用方式 学习装饰器前首先要明白以下3条事项: 1:函数 即 "变量" (什么意思呢,就是说我们定义的一个函数,其中函数名就是一个变量,函数体就是存于内存的数据). def foo(): #函数名就相当于变量 print('test') #函数体就相当于内容 类似于:x(变量) = 1(内容) 内容实际存储于内存,变量相当于门牌号(映射内存内容).

python-day5-装饰器补充、模块、字符串格式化和序列化

装饰器补充之双层装饰器 1 user_info = {} 2 3 4 def check_login(func): 5 def inner(*args, **kwargs): 6 if user_info.get('is_login', None): 7 ret = func(*args, **kwargs) 8 return ret 9 else: 10 print('请先登录...') 11 return inner 12 13 14 def check_user_type(func): 1

Day4 装饰器——迭代器——生成器

一 装饰器 1.1 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if def foo(): print('foo') def bar(): print('bar') dic={ 'foo':foo, 'bar':bar, } while True: choice=input('>>: ').strip() if choice in dic: dic[ch

python-之装饰器、迭代器、生成器

一.装饰器 1.为何要用装饰器 #开放封闭原则:对修改封闭,对扩展开放 2. 什么是装饰器 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式 装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能 import time def index(): time.sleep(3) print('welcome to index') # index() def wrapper(func):

函数对象、函数嵌套、名称空间与作用域、装饰器

一 函数对象 1.函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 2.利用该特性,优雅的取代多分支的if def foo(): print('foo') def bar(): print('bar') dic={ 'foo':foo, 'bar':bar, } while True: choice=input('>>: ').strip() if choice in dic: dic[choice]()