python day14

带参装饰器

装饰器主要是为被装饰函数添加新功能,有时候也是需要外界提供的参数

当需要外界提供参数时:

    1、装饰器函数(outer)只能有一个形参,为了让被装饰函数对象传进去

    2、装饰器内部的闭包函数(inner)的参数也是固定的和被装饰函数的参数一直

  --以上两个都靠不住的时候,我们就把整个装饰器作为一个整体,嵌套定义在另一个函数的内部,通过外部的函数对里面的函数进行传参

def warps(info):
    def outer(func):
        def inner(*args, **kwargs):
            # 添加新功能   可以接收info进行操作
            res = func(*args, **kwargs)
            # 添加新功能
            return res  # 可以对结果进行修改
        return inner
    return outer   #把装饰器函数传到外界
@warps(info)     #括号里面传参,函数遇到括号就执行,返回outer  
def fn():           #所以实际上@warps(info) = @outer  和之前是一样的
    pass
fn()

    系统的wraps带参装饰器,改变inner的假指向,本质上外界使用的还是inner,但是打印__doc__()和地址都改成wraps()括号里的函数。

form functools import wraps

def outer(func):

  @wraps(func)  # 改变inner的假指向,doc(文档注释)和地址假指func

  def inner(*args,**kwargs):

    res = func(*args,**kwargs)

    return res

  return inner

迭代器

#可迭代对象  可以通过某种方法得到迭代器对象

#迭代器对象  可以不用依赖索进行取值的容器

    --迭代器的优点:可以不依赖索引进行取值

    --迭代器的缺点:取值只能从前到后取,不能取特定地方的值

可迭代对象

#可迭代对象:有__iter__()方法的对象是可迭代对象,可迭代对象调用__iter__()得到迭代器对象

ls = [1,2,3,4]

res = ls.__iter__()  ==>ls有iter的方法,所以ls(列表list)是可迭代对象

直接访问res是访问  得到的迭代器对象  的地址

#可迭代对象有哪些:字符串(str)、列表(list)、元组(tuple)、字典(dict)、集合(set)、  迭代器对象、生成器对象

迭代器对象

#迭代器对象:有__next__()方法的对象是迭代器对象,迭代器对象可以用__next__()方法进行取值

with open('1.txt','rb') as f:

  res = f.__next__()  #文件中第一行的内容

  print(res)

  res = f.__next__()  #文件中第二行的内容

  print(res)

 #迭代器的对象有哪些:文件对象、枚举对象(enumerate(s))

for循环迭代器

#直接用while循环在迭代器对象中通过__next__()取值,终究会有取完的时候,取完再取

就会抛出StopIteration异常

ls = [1,2,3,4]
iterator = ls.__iter__()        #先把ls变成迭代器对象
while True:
    try:            #取完会报StopIteration异常,用try  except语法来捕捉异常
        print(iterator.__next__())      #通过while循环取值
    except StopIteration:   #捕捉到异常之后结束循环
        break

所以for循环就是对while取迭代器的封装

ls = [1,2,3,4]
for v in ls:
    print(v)
for v in ls.__iter__():     #->可迭代对象取完就是迭代器对象
    print(v)
iterator = ls.__iter__()    #->迭代器对象取完就是本身    (三个循环取值的结果都是一样的)
for v in iterator:
    print(v)

for循环迭代器取值的工作原理

for v in obj:pass

#1、获取obj__iter__()的结果,  就是得到要操作的迭代器对象

#2、迭代器对象通过__next__()方法进行取值,依次将当前循环的结果赋值给v

#3、当取值抛出异常之后,自动处理StopIteration异常并结束循环

枚举对象

#给可迭代对象及迭代器添加迭代索引

s = 'abc'

for v in enumerate(s):

  print(v)  #(0,'a')  (1,'b')  (2,'c')

生成器

生成器:语法和函数相同,内部有yield关键字,函数名()得到的是生成器对象,生成器对象也有next方法所以:

        --生成器就是自定义的迭代器对象

            --就是用函数语法来声明生成器,用yield关键字取代return关键字来返回值,参数没有多少变化

#执行流程

def fn():

  yield 1      #从上往下执行,遇到一个yield返回一个值

  yield 2      #然后再取找下一个yield,再返回一个值

  yield 3      #如果找不到yield,就会抛异常stopiteration

            #和for连用的话for会自动处理Stopiteration异常并结束循环

range()就是一个系统的生成器,我们也可以自己定义一个和range功能一样的生成器

posted @ 2019-04-29 17:31  hesujian  阅读(147)  评论(0编辑  收藏  举报