Python学习笔记之装饰器

目录


装饰器

不改变函数代码给函数加上新功能,并且调用方式无需改变

推导过程

在不改变方法源代码和调用方式的情况下给方法加上功能,代码如下:

def timer(func):
    def decorator(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs)
        end_time=time.time()
        print('spend time : %s' %(end_time-start_time))
    return decorator


def func1():
    time.sleep(1)
    print('in the func1')


func1=timer(func1)
func1()

简单装饰器例子:

给函数加上运行时间计时功能,并且函数有形参

def timer(func):
    def decorator(*args,**kwargs):      #内嵌函数,也就是装饰器,参数个数无限制
        start_time=time.time()
        func(*args,**kwargs)
        end_time=time.time()
        print('spend time : %s' %(end_time-start_time))
    return decorator                    #把装饰器内存地址返回

@timer                          #把内存地址复制给func1,也就是函数本身,所以执行的代码块是刚刚定义的装饰器,原理和上面推导过程一样
def func1(name,age):            #有参数的函数
    time.sleep(1)
    print('in the func1,name is {_name} and age is {_age}'.format(_name=name,_age=age))


@timer
def func2():                    #无参数的函数
    time.sleep(1)
    print('in the func2')


func1("domain",18)            #再调用时就是执行装饰器的代码
func2()

复杂装饰器例子:

装饰器传入参数,并且被装饰函数有返回值

user,password='domain','123'

def auth(type):                         
    print("type",type)
    def out(func):
        def decor(*args,**kwargs):
            if type=="1":
                username=input('please input your name')
                userpassword=input('please input your password')
                if user==username and password==userpassword:
                    print('passed auth')
                    res=func()
                    return res
                else:
                    print('you username or password invaild.')
            elif type=="2":
                print("type ==2 ")
                username = input('please input your name')
                userpassword = input('please input your password')
                if user == username and password == userpassword:
                    print('passed auth')
                    res = func()
                    return res
                else:
                    print('you username or password invaild.')
        return decor
    return out


def index():
    print("welcome to index")

@auth("1")
def home():
    print("welcome to home")
    return "result form home "

@auth("2")
def bbs():
    print("welcome to bbs")

index()
print(home())
bbs()

生成器

一边循环一边生成,通过算法推断出元素数据,成为生成器(generator)


特点

  1. 只有在调用是时候才会生成对应的数据
  2. 只记录当前位置
  3. 只有一个next方法

简单生成器-列表生成式

把列表改成生成器

c=(i*2 for i  in range(10))
print(c)                        //为生成器 地址:<generator object <genexpr> at 0x000000BAAC687990>
print(c.__next__())             //为生成器里面的第一个值

复杂生成器-函数

#斐波那契
def fib(max):
    n,a,b=0,0,1
    while n<max:
        # print(b)
        yield b                 #定义b为 生成器的值 一碰到yield函数退出
        a,b=b,a+b
        n=n+1
    return 'done'                  #生成器异常返回值

c=fib(10)
print(c.__next__())

while True:
    try:
        print(c.__next__())
    except StopIteration as e:          #捕获超出生成器大小异常
        print("exception:",e.value)
        break

send 方法发送数据给生成器

def consumer (name):
    print("%s准备吃包子啦!"%name)
    while True:
        baozi=yield
        print("包子[%s]来了,被[%s]吃了!"%(baozi,name))

c=consumer("domain")
c.__next__()            #第一次执行 碰到yield 结束
c.send("韭菜馅")        #发送数据给生成器第二次执行 输出语句,然后进入循环 碰到yield 结束

迭代器

  • 迭代对象:可以用于for循环的对象成为迭代对象(Iteralbe),如:list,tuple,dict,set,str和生成器等。
  • 迭代器:可以被next函数调用并不断返回下一个值的对象成为迭代器(Iterator)

基本函数

  • 是否是迭代对象(导入模块后用isinstance函数判读):
from collections import  Iterable,Iterator
print(isinstance([],Iterable))
print(isinstance((),Iterable))
print(isinstance({"name","domain"},Iterable))
print(isinstance("domain",Iterable))
print(isinstance(123,Iterable))
  • 是否是迭代器(导入模块后用isinstance函数判读):
from collections import  Iterable,Iterator
print(isinstance([],Iterator))
print(isinstance((),Iterator))
print(isinstance({"name","domain"},Iterator))
print(isinstance("domain",Iterator))
print(isinstance(123,Iterator))
  • 非迭代器(可迭代对象)变成迭代器,用iter函数:
a=[1,2,3]
b=iter(a)   
b.__next__()

扩展

  • for 循环也是通过迭代器实现:
for x in range(10):
    print(x)


        break

等价于:

it = iter([0,1,2,3,4,5,6,7,8,9])
while True:
    try:
        x=it.__next__()
        print(x)
    except:
        break
  • 文件的读取也是通过迭代器实现:
for f in f:
    print(f)

更多最新Python教程资源关注微信公众号 凯撒网络研究院,回复 Python获取。

猜你喜欢

转载自blog.csdn.net/qq_24045059/article/details/80033227