python--有参装饰器、迭代器

有参装饰器的引入:

import time
import random
from functools import wraps

def timmer(func):
    @wraps(func)
    def wrapper():
        # wrapper.__doc__=func.__doc__
        start_time = time.time()
        func()
        stop_time = time.time()
        print('run time is %s' % (stop_time-start_time))
        # wrapper.__doc__=func.__doc__
    return wrapper

@timmer
def index():
    'index function'
    time.sleep(3)
    print('welcome to index page')

# print(index.__doc__)
index()
print(index.__doc__)
结果:
welcome to index page
run time is 3.000171661376953
index function

先来简单介绍一下functools.wraps。

      我们在使用 Decorator 的过程中,难免会损失一些原本的功能信息。而functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 __module____name____doc__,或者通过参数选择。

 

def foo():
    'foo function------------>'
    pass

print(help(foo))
结果:
foo()
    foo function------------>

None

help函数python的一个内置函数(它是python自带的函数,任何时候都可以被使)。

help函数能作什么:

       在使用python来编写代码时,会经常使用python 调用函数自带函数或模块,一些不常用的函数或是模块的用途不是很清楚,这时候就需要用到help函数来查看帮助。

这里要注意下,help()函数是查看函数或模块用途的详细说明,而dir()函数是查看函数或模块内的操作方法都有什么,输出的是方法列表。

怎么使用help函数查看python模块中函数的用法:

help( )括号内填写参数,操作方法很简单。

使用help函数查看帮助时需要注意哪些问题:

1、查看一个模块的帮助
>>>help('sys')
之后它回打开这个模块的帮助文档

2、查看一个数据类型的帮助
>>>help('str')
返回字符串的方法及详细说明

 

>>>a = [1,2,3]
>>>help(a)
这时help(a)则会打开list的操作方法
>>>help(a.append)
会显示list的append方法的帮助

下面来几个栗子:

def foo():
    'foo fuction'
    print(foo.__doc__)
    foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
    pass

print(help(foo))
结果:
Help on function foo in module __main__:

foo()
    foo fuction

None
def foo():
    'foo fuction'
    print(foo.__doc__)
    foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
    pass

print(foo.__doc__)
结果:
foo fuction
def foo():
    'foo fuction'
    print(foo.__doc__)
    foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
    pass


foo.__doc__ = 'abcdefg'
print(foo.__doc__)
结果:
abcdefg
def foo():
    'foo fuction'
    print(foo.__doc__)
    foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
    pass


foo.__doc__ = 'abcdefg'
print(help(foo))
结果:
Help on function foo in module __main__:

foo()
    abcdefg

None
def foo():
    'foo fuction'
    print(foo.__doc__)
    foo.__doc__ = 'asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas'
    pass

foo()
print(foo.__doc__)
结果:
foo fuction
asdfasdfasdfasdfsadfasdfasdfsadfasdfasfas

有参装饰器

db_path=r'C:\Users\Administrator\PycharmProjects\untitled4\db.txt'

login_dic = {
    'user': None,
    'status': False,
}
def deco(auth_type='file'):
    def auth(func):
        def wrapper(*args, **kwargs):
            if auth_type == 'file':
                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')
            elif auth_type == 'ldap':
                print('ldap认证方式')
            elif auth_type == 'mysql':
                print('mysql认证方式')
            else:
                print('不知到的认证方式')
        return wrapper
    return auth

@deco(auth_type='abc') #@auth #index=auth(index)
def index():
    print('welcome to index')

@deco(auth_type='ldap')
def home(name):
    print('welcome %s to home page' % name)

index()

home('egon')
结果:
不知到的认证方式
ldap认证方式
def deco(auth_type='file'):
    def auth(func):
        def wrapper(*args,**kwargs):
            if auth_type == 'file':
                print('文件的认证方式')
            elif auth_type == 'ldap':
                print('ldap认证方式')
            elif auth_type == 'mysql':
                print('mysql认证方式')
            else:
                print('不知到的认证方式')
        return wrapper
    return auth

@deco(auth_type='abc') #@auth #index=auth(index)
def index():
    print('welcome to index')

@deco(auth_type='ldap')
def home(name):
    print('welcome %s to home page' % name)

index()

home('egon')
结果:
不知到的认证方式
ldap认证方式

思考:

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

迭代器

  • 迭代:
    1.  重复
    2. 下一次重复是基于上一次的结果

'''
python为了提供一种不依赖于索引的迭代方式,
python会为一些对象内置__iter__方法
obj.__iter__称为可迭代的对象
'''

obj.__iter__() 得到的结果就是迭代器

得到的迭代器:既有__iter__又有一个__next__方法

d={'a':1,'b':2,'c':3}

i=d.__iter__() #i叫迭代器
print(i)
print(i.__next__())
print(i.__next__())
print(i.__next__())
# print(i.__next__()) #StopIteration
结果:
<dict_keyiterator object at 0x0000000001DBF2C8>
a
b
c 

迭代器的优点:

  • 1:提供了一种不依赖于索引的取值方式
  • 2:惰性计算。节省内存

迭代器的缺点:

  • 1:取值不如按照索引取值方便
  • 2:一次性的。只能往后走不能往前退
  • 3:无法获取长度

迭代器的应用:

  •  1. 提供了一种不依赖索引的统一的迭代方法
  •  2. 惰性计算,比如取文件的每一行
l = [1, 2, 3]
for item in l: #i=l.__iter__()
    print(item)
结果:
1
2
3
 作业:
2 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到文件中
    注意:时间格式的获取
        import time
        time.strftime('%Y-%m-%d %X')

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 分别用依赖索引和不依赖索引两种方式迭代上述对象

5 选做题:
    基于课上所讲网页缓存装饰器的基础上,实现缓存不同网页的功能
    要求,用户提交的不同url,都能缓存下来,对相同的url发起下载请求,优先从缓存里取内容
答案:
# 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\untitled\log.txt'
# def log_deco(func):
#     def wrapper(*args,**kwargs):
#         with open(log_path,'w') as f:
#             func(*args, **kwargs)
#             a = f.write(time.strftime('%Y-%m-%d %X'))
#             return a
#
#         # res=func(*args,**kwargs)
#         # return res
#     return wrapper
#
# @log_deco
# def f1():
#     print('welcome to f1 page')
#
# 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')
#
#字符串,列表,元祖,字典,集合,文件都是可迭代对象,可以object.__iter__
# s='hello'
# s1=s.__iter__()
# print(s1.__next__())
# print(s1.__next__())
# print(s1.__next__())
# print(s1.__next__())
# print(s1.__next__())


# l=[1,2,3,4]
# l1=l.__iter__()
# print(l1.__next__())
# print(l1.__next__())
# print(l1.__next__())
# print(l1.__next__())


# t=(1,2,3)
# t1=t.__iter__()
# print(t1.__next__())
# print(t1.__next__())
# print(t1.__next__())


# d={'a':1}
# d1=d.__iter__()
# print(d1.__next__())


# set={1,2,3}
# set1=set.__iter__()
# print(set1.__next__())
# print(set1.__next__())
# print(set1.__next__())


# f=open('a.txt')
# f1=f.__iter__()
# print(f1.__next__())
# print(f1.__next__())
# print(f1.__next__())
# print(f1.__next__())
# print(f1.__next__())
# print(f1.__next__())


# 4 分别用依赖索引和不依赖索引两种方式迭代上述对象
# s='hello'
# l=[1,2,3,4]
# t=(1,2,3)
# d={'a':1}
# set={1,2,3}
# f=open('a.txt')
#
#
# for i1 in s:
#     print(i1)
#
# i1=0
# while i1<len(s):
#     print(s[i1])
#     i1+=1
#
#
# for i2 in l:
#     print(i2)
#
# i2=0
# while i2<len(l):
#     print(l[i2])
#     i2+=1
#
#
# for i3 in t:
#     print(i3)
#
# i3=0
# while i3<len(t):
#     print(t[i3])
#     i3+=1
#
#
# for i4 in d:
#     print(i4)



# for i5 in set:
#     print(i5)
#

# with open('a.txt','r',encoding='utf-8')as f:
#     for line in f:
#         print(line,end='')

#
# 5 选做题:
#     基于课上所讲网页缓存装饰器的基础上,实现缓存不同网页的功能
#     要求,用户提交的不同url,都能缓存下来,对相同的url发起下载请求,优先从缓存里取内容

 

posted @ 2017-06-18 23:48  始怡  阅读(220)  评论(0编辑  收藏  举报