• python基础之函数名的使用,闭包以及迭代器


    内容梗概:
    1. 函数名的使⽤用以及第⼀一类对象
    2. 闭包
    3. 迭代器

    1.函数名
    一. 函数名的运⽤.
    函数名是一个变量, 但它是⼀个特殊的变量, 与括号配合可以执行函数的变量.
    1.1 函数名的内存地址
    1.2 函数名可以赋值给其他变量
    def func():
    print("哈哈")
    a = func #将函数名赋值给a
    a()
    print(func) #内存地址是一致的
    print(a)
    1.3 函数名可以当做容器类的元素
    def func1():
    print("呵呵")
    def func2():
    print("呵呵")
    def func3():
    print("呵呵")
    def func4():
    print("呵呵")
    lis = [func1,func2,func3,func4]
    for el in lis:
    el()
    1.4. 函数名可以当做函数的参数
    def func2():
    print("我是func2啊")
    def func(fn):
    print("我是啥玩意")
    fn()
    func(func2)

    1.5. 函数名可以作为函数的返回值
    def func1():
    print("这里是函数一啊")
    def func2():
    print("这里是函数二啊")
    return func2
    fn = func1() # 执行函数1. 函数1返回的是函数2, 这时fn指向的就是上⾯面函数2
    fn()

    1.6 代理模式 (比较特殊)
    装饰器的雏形
    把函数名当成变量来使用
    def chi(fn): # fn 代理了func1和func2
    print("开挂")
    fn()
    print(fn.__name__) # 返回函数名
    print("洗包")

    def play_dnf():
    print("疯狂的刷")

    def func1():
    print("我是func1")

    def func2():
    print("我是func2")

    def he():
    print("我要喝酒")

    chi(play_dnf)

    2. 闭包
    2.1什么是闭包? 闭包就是内层函数,对外层函数(非全局)的变量的引⽤.叫闭包
    闭包的样式:
    def func1():
    name = "alex"
    def func2():
    print(name) # 闭包
    func2()
    func1()
    注意:闭包的特点: 1.保护我们的变量 2.必须是局部变量
    2.2 如何判别闭包
    def outer():
    a = 10
    def inner():
    print(a)
    print(inner.__closure__) # (<cell at 0x000001C079677588: int object at 0x0000000054776D30>,)
    inner() # 返回CELL得值就是,返回NONE则不是
    outer()
    问题:如何在外部调用内部的函数?
    def func1():
    def func2():
    def func3():
    print("嘿嘿")
    return func3
    return func2
    func1()()() #将内层函数返回到外层就可以调用,多层嵌套一层一层返回就可以了

    2.3 闭包的作用
    1. 保护我们的变量不受侵害
    2. 可以让一个变量常驻内存,供后面程序的使用
    2.的解释 python规定. 如果你在内部函数中访问了了外层函数中的变量. 那么这个变量将不会消亡.
    将会常驻在内存中. 也就是说. 使用闭包, 可以保证外层函数中的变量在内存中常驻


    2.4 补充注释
    def func1(a,b):
    '''
    这个函数用来计算两个数的和并返回
    :param a: 第一个参数a
    :param b: 第二个参数b
    :return: a+b的和
    author:zwh
    '''
    print("我是func")
    return a + b
    print(func1.__doc__) #可查看函数的文档注释
    print(func1.__name__) #可查看函数名



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

    3.2 如何进验证你的数据类型是否符合可迭代协议. 我们可以通过dir函数来查看类中定义好的所有方法
    实例:
    s = [0,1,2,3,5,6,9]
    print(dir(s)) #查看是否含有__iter__,只要含有就是可迭代对象

    3.3 如何查看一个对象为什么类型
    法1:
    collections: 关于集合类的相关操作
    Iterable : 可迭代的
    Iterator : 迭代器

    lst = ["秦始皇", "汉武帝", "孝文帝", "隋炀帝", "李世民"]
    from collections import Iterable,Iterator
    print(isinstance(lst,Iterable))
    print(isinstance(lst,Iterator))

    法2 (野路子)
    lst = ["秦始皇", "汉武帝", "孝文帝", "隋炀帝", "李世民"]
    a = dir(lst)
    print("__iter__" in a) # True 可迭代的
    print("__next__" in a) # False 不可迭代的

    tips:
    如果对象中有__iter__函数. 那么我们认为这个对象遵守了可迭代协议.就可以获取到相应的迭代器.
    这里的__iter__是帮助我们获取到对象的迭代器. 我们使用迭代器中的__next__()来获取到一个迭代器中的元素.,,

    3.4 for 循环的内部机制
    lst = ["秦始皇", "汉武帝", "孝文帝", "隋炀帝", "李世民"]
    a = lst.__iter__() #获得迭代器 <list_iterator object at 0x0000027BCA220748>
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__()) #当没有下一个元素的时候,会报错 StopIteration

    所以我们可采用新机制
    lst = ["秦始皇", "汉武帝", "孝文帝", "隋炀帝", "李世民"]
    a = lst.__iter__() #获得迭代器 <list_iterator object at 0x0000027BCA220748>
    while 1:
    try:
    print(a.__next__())
    except StopIteration:
    break #这种方法不会出现报错

    3.5 迭代器特点总结
    Iterable: 可迭代对象. 内部包含__iter__()函数
    Iterator: 迭代器. 内部包含__iter__() 同时包含__next__().
    迭代器的特点:
    1. 节省内存.
    2. 惰性机制(必须用__next__()来获取数据)
    3. 不能反复, 只能向下执⾏行行.
    我们可以把要迭代的内容当成子弹. 然后呢. 获取到迭代器__iter__(), 就把子弹都装在弹夹中.
    然后发射就是__next__()把每一个子弹(元素)打出来.
    也就是说, for循环的时候. 一开始的时候是__iter__()来获取迭代器.
    后⾯面每次获取元素都是通过__next__()来完成的. 当程序遇到StopIteration将结束循环.
  • 相关阅读:
    字符,字符串,字节
    111
    串口通信
    字符编码
    枚举和结构体
    参数数组
    .Net垃圾回收机制
    try{ } catch{ } finally{ }
    LVS 工作原理图文讲解
    自动化运维工具—Ansible常用模块二
  • 原文地址:https://www.cnblogs.com/Mixtea/p/9884494.html
Copyright © 2020-2023  润新知