zoukankan      html  css  js  c++  java
  • 迭代器

    主要内容:

    • 1. 函数名的使用以及第⼀类对象
    • 2. 闭包
    • 3. 迭代器

    1. 函数名的使用以及第⼀类对象

      函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量。

    (1) 函数名的内存地址

    def func():
        print("呵呵")
    print(func)            #<function func at 0x000001EBCE5D6048>

    (2)函数名可以赋值给其他变量

    def func():
        print("呵呵")
    print(func)
    a = func      # 把函数当成⼀个变量赋值给另⼀个变量
    a()           # 函数调⽤用 func()       #呵呵

    (3)函数名可以当做容器类的元素

    def func1():
        print("呵呵")
    def func2():
        print("呵呵")
    def func3():
        print("呵呵")
    def func4():
        print("呵呵")
    lst = [func1, func2, func3]
    for i in lst:
        i()

    (4)函数名可以当做函数的参数

    def func():
        print("吃了了么")
    def func2(fn):
        print("我是func2")
        fn()    # 执行传递过来的fn
        print("我是func2")
    func2(func)     # 把函数func当成参数传递给func2的参数fn.

    (5)函数名可以作为函数的返回值

    def func_1():
        print("这里是函数1")
        def func_2():
                print("这里是函数2")
        print("这里是函数1")
        return func_2
    fn = func_1()   # 执⾏函数1.  函数1返回的是函数2, 这时fn指向的就是上面函数2
    fn()    # 执⾏上面返回的函数

    (6) 一个设计模式

    def panpan():
        print("我是潘潘. 我喜欢毒丈夫 ")
    def xiaoping():
        print("我是小萍萍. 我喜欢毒丈夫 ")
    def daguanren():
        print("大官人喜欢xxxx")
    def wangpo(nv, nan): # 核心业务逻辑
        nv()
        nan()
    wangpo(xiaohua, daguanren)             # 王婆代理了大官人和潘潘

    (7)函数名既然是变量,变量名是任意的,在多次的赋值和调用过程中后续可能不知道初始的变量名,可以通过.__name__ 来得到初始的变量名

    def chi():
        print("我是吃")
    a = chi
    haha = a
    hehe = haha
    bilibili= hehe
    bilibili()
    print(bilibili.__name__) # 函数名

    (8)函数的注释

    def play(wanjv1, wanjv2, wanjv3):
        '''
            这是一个关于玩儿的函数
            :param wanjv1: 玩具1
            :param wanjv2: 玩具2
            :param wanjv3: 玩具3
            :return: 开心
        '''
        print("我要玩儿荡秋千")
        return "开心"
    # play("独木桥", "独轮车", "独眼龙")
    print(play.__doc__) #  document   以文档的形式查看注释
    print(str.join.__doc__)   #查看join里面是什么东西
    #结果:
    # 这是一个关于玩儿的函数
    # :param
    # wanjv1: 玩具1
    # :param
    # wanjv2: 玩具2
    # :param
    # wanjv3: 玩具3
    # :return: 开心
    # 
    # S.join(iterable) -> str
    
    # Return a  string which is the  concatenation of the strings in the iterable.The separator between elements is S.

    2. 闭包

      闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包

    def func1():
        name = "alex"
        def func2():
            print(name)     # 闭包
        func2()
    func1()       # alex

    我们可以使用__closure__来检测函数是否是闭包. 使用函数名.__closure__返回cell就是闭包,返回None就不是闭包

    def func1():
        name = "alex"
        def func2():
            print(name)     # 闭包
        func2()
        print(func2.__closure__)     #(<cell at 0x000001AF73627588: str object at 0x000001AF736B7378>,)
    func1()       # alex

    在函数外边调用内部函数

    def outer():
        name = "alex"
        # 内部函数
        def inner():
            print(name)
        return inner
    fn = outer()         # 访问外部函数, 获取到内部函数的函数地址
    fn()                 # 访问内部函数

    如果多层嵌套,只需要一层一层的往外层返回

    def func1():
        def func2():
            def func3():
                print("嘿嘿")
            return func3
        return func2
    func1()()()

    闭包的好处: 

    • 当在外界访问内部函数时, 那这个时候内部函数访问的时间和时机就不⼀定了,因为在外部, 可以选择在任意的时间去访问内部函数.
    • 如果⼀个函数执行完毕, 则这个函数中的变量以及局部命名空间中的内容都将会被销毁. 在闭包中如果变量被销毁了, 那内部函数将不能正常执行.
    • python规定:如果你在内部函数中访问了外层函数中的变量,那么这个变量将不会消亡. 将会常驻在内存中,这样闭包可以保证外层函数中的变量在内存中常驻.

    3. 迭代器

     str, list, tuple, dict, set. 那为什么我们可以称他们为可迭代对象呢, 因为他们都遵循了可迭代协议.

    # 对的
    s = "abc"
    for c in s:
        print(c)
        
    #  错的
    for i in 123:
     print(i)
    结果:

    Traceback (most recent call last):
     File "E:/Python_workspace/day 011/011整理.py", line 111, in <module>
      for i in 123:
    TypeError: 'int' object is not iterable

     'int' object is not iterable' 即如果整数类型对象是不可迭代的,iterable表示可迭代的,表示可迭代协议,我们可以通过dir函数来查看类中定义好的

        所有包含了__iter__的东西都可以使用for循环. 都可以进行迭代

    s = "我的哈哈哈"
    print(dir(s))       # 可以打印对象中的⽅方法和函数
    print(dir(str))     # 也可以打印类中声明的⽅方法和函数
    s = "alex"
    print(dir(s)) # 在字符串中发现了__iter__. 没有__next__
    a = 123
    print(dir(a)) # 在int中没有__iter__ 没有__next__
    lst = [1, 2, 3,]
    print(dir(lst)) # 在list中也有__iter__

       (1)调用了__iter__(), 访问__iter__()可以得到迭代器

    lst = [1, 2, 3, 4, 5, 6]
    it = lst.__iter__()  # iterator 迭代器
    while 1:
        try:
            print(it.__next__())
        except StopIteration:
            print("结束了")
            break
    for el in lst:
        print(el)
    else:
        print("结束了")

    (2) 迭代器给所有的数据类型提供了一种统一的遍历的方式(可迭代协议), Iterable, __iter__()

    lst = [1, 2, 3, 4, 5]
    print("__iter__" in dir(lst))    #True
    print("__next__" in dir(lst))    #False
    lst = [1, 2, 3, 4, 5]
    it = lst.__iter__()
    print("__iter__" in dir(it)) #  迭代器里面是有__iter__的.  迭代器一定是可迭代的     #True
    print("__next__" in dir(it))                                                     #True
    #
    for el in it: # 迭代器可以使用for循环
        print(el)

     Iterable: 可迭代对象. 内部包含__iter__()函数       

     Iterator: 迭代器. 内部包含__iter__() 同时包含__next__(). 

    from collections import Iterable # 可迭代的
    from collections import Iterator # 迭代器
    #
    lst = ["周润发","麻花藤","刘伟"]
    print(isinstance(lst, Iterable)) # instance  实例, 对象    #True
    print(isinstance(lst, Iterator)) # instance  实例, 对象    #False
    #
    it = lst.__iter__()
    print(isinstance(it, Iterable)) # instance  实例, 对象      #True
    print(isinstance(it, Iterator)) # instance  实例, 对象       #True

     迭代器的特点:             

    • 1. 节省内存.           
    • 2. 惰性机制           
    • 3. 不能反复, 只能向下执行
  • 相关阅读:
    从MVC和三层架构说到ssh整合开发-下
    Codeforces Round #226 (Div. 2)--A Bear and Raspberry
    ISA95的抽象惯例
    Difference between End-to-end testing and System testing
    javascript Date format(js日期格式化)
    给easyui datebox扩展一个清空按钮
    easyui combobox开启搜索自动完成功能
    给你的webstorm添加快速生成注释得快捷键
    location.origin兼容IE
    将json转换成struts参数
  • 原文地址:https://www.cnblogs.com/wcx666/p/9663417.html
Copyright © 2011-2022 走看看