zoukankan      html  css  js  c++  java
  • 函数名、闭包及迭代器

    一、函数名的应用及闭包

    # 函数名的应用 及闭包
    #1, 函数名就是函数对象在内存中的内存地址
    def func():
        print(6666)
    
    print(func)   # <function func at 0x000002666B812E18>
    
    #2 函数名,可以作为变量
    # a = 2
    # b = a
    # c = b
    # print(b)
    
    def func1():
        print(8888)
    f = func1
    f2 = f
    f()    # 8888
    
    #3,函数名,可以作为函数的参数
    def func2():
        print(777,end=" ")
    def func3(x):
        print(999,end=" ")
        print(x,end=" ")
        x()
    print(func2)   # <function func2 at 0x00000243C9718950>
    func3(func2)   #  输出 999  <function func2 at 0x00000243C9718950> 777
    
    #函数名,可以当作函数的返回值
    print("
    "+"华丽的分隔线".center(68,'*'))
    def wrapper():
        def inner():
            print("in inner")
        return inner
    f=wrapper()
    f()
    # 函数名可以作为容器类型元素
    def foo():
        print("I am foo")
    def duck():
        print("You are duck")
    def beat():
        print("I like this beat")
    dic = {'foo':foo,'duck':duck,"beat":beat}
    dic['foo']()   # I am foo
    dic['duck']()  # You are duck
    dic['beat']()  # I like this beat
    
    # 像上面函数名这种,称为第一类对象
    # 第一类对象的特点
    # 1, 可在运行期创建
    # 2,可用作函数参数或返回值
    # 3,可存入变量的实体
    ## 不明白吗?那就记住一句话,就当普通变量用
    
    # 闭包
    # 内层函数 对 外层 函数的变量(非全局变量)的引用,这样就形成闭包,内层函数就叫闭包函数
    def wrapper():
        name = 'chris'
        def inner():
            print(name)
        return inner
    func = wrapper()
    func()      # chris
    
    # 判断闭包函数的常用方法:  __closure__
    def wrapper():
        name = "LiMing"
        def inner():
            print(name)
        print(inner.__closure__)  # 输出的 __closure__有cell元素:是闭包函数   ,内部函数 被 一层外部函数,闭包
        return inner
    wrapper()    #  (<cell at 0x000001FDE53D65B8: str object at 0x000001FDE70485E0>,)
    
    
    name = 'egg'
    def func2():
        def inner():
            print(name)
        print(inner.__closure__)   # 输出的__closure__为None : 不是闭包函数
        return inner
    f2 = func2()
    f2()   # egg
    
    print("分道线".center(100,'#'))
    
    def wrapper():
        money = 1000
        def func():
            name = 'baby'
            def inner():                             #  内部函数 被 外部两层函数 闭包
                print(name,money)
            print(inner.__closure__)    # (<cell at 0x00000222CAB465B8: int object at 0x00000222CABE6B30>, <cell at 0x00000222CAB46618: str object at 0x00000222CAC086C0>)
            print('inner',inner)       #    inner <function wrapper.<locals>.func.<locals>.inner at 0x00000222CABD8AE8>
            return inner
        return func
    f = wrapper()
    i = f()
    # i()
    
    print("一线天".center(59,'$'))
    
    hobby = 'sing'
    def  fn(n):                                    #   n = hobby n 是fn函数的局部变量
        def inner():
            print(n)
            print(n +"1")
        print(inner.__closure__)    # (<cell at 0x000001DFEA006678: str object at 0x000001DFEA0C8768>,)
        return inner
    f = fn(hobby)
    print(f.__closure__[0].cell_contents)    # 查看闭包的元素
    f()                     # sing
    
    '''
    闭包的作用:
        当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间,
    如果这个函数内部形成了闭我,那么他就不会随着函数的结束而结束。
    #闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
    #应用领域:延迟计算(原来我们是传参,现在我们是包起来
    '''
    from urllib.request import urlopen
    
    def index(url):
        def get():
            return urlopen(url).read()
        return get
    
    baidu=index('http://www.baidu.com')
    print(baidu().decode('utf-8'))

     二、迭代器:

    # 可迭代对象  内部 有 __iter__ 方法
    
    # lis = [1,3,5,10]
    #
    # print(dir(lis))
    # print("__iter__" in dir(lis))
    
    
    # 什么是迭代器?
    # 对象内部含有__iter___方法且含有__next__方法, 就是迭代器
    
    # f = open('register',encoding='utf-8')
    # print(f)
    # print("__iter__" in dir(f))
    # print("__next__" in dir(f))
    #
    # print("__iter__" in dir(dict))
    # print("__next__" in dir(dict))
    # print(dir(f))
    
    
    # 判断一个对象是否可迭代对象:
    # 第一个方法
    dic = {'name':'chris'}
    s1 = "hello world"
    print('__iter__' in dir(dic))  # True
    print("__iter__" in dir(s1))   # True
    # 第二种方法
    # from collections import Iterable
    # from collections  import Iterator
    # print(isinstance(s1,Iterable))  # True  字符串是可迭代对象
    # print(isinstance(s1,Iterator))  # False  字符串不是迭代器
    # print(isinstance(s1,str))       #  True
    
    # isinstance()方法  vs  type()方法
    # isinstance()可以判断对象 ,所从属的所有对象类别 ,而type()方法,仅判断 基本数据类型
    
    
    
    #  dir()方法,获取指定对象的所有方法名,将方法名以字符串类型,保存在一个列表中返回。
    
    # 什么是迭代器? 迭代器,从表象上来说,就是具有 __iter__ 和 __next__方法的对象。
    # 常见的迭代器,比如说,打开文件时,产生的文件句柄
    
    fhandler = open("register",encoding='utf-8')
    print(fhandler)   # <_io.TextIOWrapper name='register' mode='r' encoding='utf-8'>
    # 验证 文件句柄 是否具有  __iter__ 和 __next__ 方法
    print( "__iter__" in dir(fhandler))    # True
    print( "__next__" in dir(fhandler))    # True
    
    # 验证 dict 类型 ,是不是迭代器?
    print('__iter__' in dir(dict))        # True    具有这个方法,表示是可迭代对象
    print('__next__' in dir(dict))        # False
    # 可见 dict 类型,不是迭代器,它仅仅是一个可迭代对象。
    # 另外一种判定方法:
    from collections import Iterator
    print(isinstance(fhandler,Iterator))   # True   是迭代器
    
    
    # 可迭代对象 vs 迭代器
    # 可迭代对象不能取值 ,迭代器是可以取值的。
    # 可迭代对象 ---》 (转化成)迭代器
    lis = [1,3,5]   # 可迭代对象
    ite1 = lis.__iter__()
    print(ite1)     # <list_iterator object at 0x00000164B0C784E0>  列表迭代器对象
    ite2 = iter(lis)   # <list_iterator object at 0x000001D4D0B451D0>  列表迭代器对象
    print(ite2)
    # 总结 : 调用可迭代对象的__iter__()方法,或者用iter(iterable)方法,把迭代对象传参进去
    
    # 迭代器如何取值呢? next 一次,取一个值
    # print(ite2.__next__())  # 1
    # print(ite2.__next__())  # 3
    # print(ite2.__next__())  # 5
    # print(ite2.__next__())  #  StopIteration   当手动从迭代器,取值,取完了,还取,抛出异常
    
    # 迭代器的特点:
    # 1,可迭代对象不能取值,迭代器是可以取值的
    # 2, 迭代器非常节省内存
    # 3, 迭代器每一次只会取一个值
    # 4,迭代器单向的,一条路走到头
    
    # 用 while 循环 模拟 for 循环:
    # 1,将可迭代对象转化成迭代器
    # 2,调用__next__方法取值
    # 3,利用异常处理停止报错
    # l = [11,12,13,14,15]
    # iter_l = iter(l)
    # while 1:
    #     try:
    #         print(iter_l.__next__())
    #     except StopIteration:
    #         break
  • 相关阅读:
    yii 面包屑
    php == ===
    算法竞赛入门经典 暴力求解法 简单枚举 7.1.4 双基回文数
    算法竞赛入门经典 暴力求解法 简单枚举 7.1.4 双基回文数
    算法竞赛入门经典 暴力求解法 简单枚举 7.1.4 双基回文数
    算法竞赛入门经典 暴力求解法 简单枚举 7.1.4 双基回文数
    折半(对半)搜索算法
    折半(对半)搜索算法
    折半(对半)搜索算法
    折半(对半)搜索算法
  • 原文地址:https://www.cnblogs.com/chris-jia/p/9493599.html
Copyright © 2011-2022 走看看