• 迭代器、递归


    一、函数名的使用

    1.函数名的内存地址    

    def func():
        pass
    
    print(func)  # 函数的内存地址    <function func at 0x0000028C53141EA0>

    2.函数名可以当做值赋值给变量

    def func():
        print(1)
    a = func
    a()
    # func()   # 函数名可以当做值赋值给变量

    3.函数名可以当做元素放到容器里

    def func():
        print(1)
    
    def func2():
        print(2)
    
    li = [func,func2]
    print(li)  # 函数名可以当做元素放到容器里
               #[<function func at 0x000001E2EC391EA0>, <function func2 at 0x000001E2EC56E950>]

    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()    # 执行上面返回的函

    二、闭包

    1.一个嵌套函数

    2.在嵌套函数的内部函数使用外部(非全局的变量)

    满足以上两条就是闭包

    内部函数包含对外部作用域而非全局作用域变量的引用,该内部函数称为闭包函数
    函数内部定义的函数称为内部函数

    def func1():
        name = "alex"
        def func2():
            print(name)
            # 闭包
        func2()
    func1()
    # 结果: alex
    def func():
        name = 'eva'
        def inner():
            print(name)
        return inner
    
    f = func()
    f()
    函数外部调用函数内部的函数

     判断闭包函数的方法__closure__

    def wrapper():
        a = 10
        def inner():
           print(a)
        print(inner.__closure__) # 不是None 就是闭包
        inner()
    wrapper()
    #   (<cell at 0x000001F2FD158468: int object at 0x00000000714F6D30>,)
    #   10
    money = 10
    # 全局里存放会有污染和不安全的现象
    
    def wrapper():
        money = 10
        def inner(num):
            nonlocal money
            money += num
            print(money)
        return inner
    wrapper()(100)
    def wrapper():
        money = 1000
        def func():
            name = 'eva'
            def inner():
                print(name,money)
            return inner
        return func
    
    f = wrapper()
    i = f()
    i()
    闭包的嵌套

    python中闭包,会进行内存驻留, 普通函数执行完后就销毁了

    全局里存放会有污染和不安全的现象

    面试必问,装饰器 -- 装饰器的本质就是闭包

    闭包有个弊端:会出现内存泄漏

    三、迭代器

    1.1什么是可迭代对象?   Iterable: 可迭代对象. 内部包含__iter__()函数

    字符串、列表、元组、字典、集合都可以被for循环,说明他们都是可迭代的

    1.2可迭代协议

    可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法。

    可迭代的:内部必须含有一个__iter__方法。

    li = [1,2,3]
    a = li.__iter__()
    print(a.__next__())
    print(a.__next__())  #一个一个取
    print(a.__next__())
    
    b = li.__iter__()
    print(b.__next__())
    print(b.__next__())
    print(b.__next__())

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

    迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。

    for循环,能遍历一个可迭代对象,他的内部到底进行了什么?

    • 将可迭代对象转化成迭代器。(可迭代对象.__iter__())
    • 内部使用__next__方法,一个一个取值。
    • 加了异常处理功能,取值到底后自动停止。

    迭代器特性:

        惰性机制

        不能从下向上走

        一次性的,用完就没了

    li = [1,2,3,4,6,7,87,8,9,90,0,0,0,0,8,7,7,67,]
    em = li.__iter__()
    while 1:
        try:
            print(em.__next__())
    
        except StopIteration:
            break
    dic = {'1':1}  # 8679250325822402967 = 1
    print(hash('1'))
    for i in range(10):
        print(i)

    四、递归

    自己调用自己本身

    有明确结束条件

    def func():
        print(1)
        func()
    func()

    超出了递归的最大层次

    递归默认层次,官方说明 1000,实际测试 998/997/993

    count = 0
    def func():
        global count
        count += 1
        print(count)
        if count == 500:
            return
        func()
    func()
    def func(n):
        n+=1
        print(n)
        if n == 100:
            return
        func(n)
    func(0)
    def func(age):
        age = age + 1
        print(age)
        if age == 5:
            return
        func(age)
    func(2)
    def func(age):
        print(age)
    
    def func1(age):
        print(age)
        func(age+1)
    
    def func2(age):
        print(age)
        func1(age+1)
    func2(2)

    递归的效率比较低,尾递归的用时 和 for的用时 是一样的,比for慢

     

    递归的应用场景:

        在不明确要循环的次数时候,可以用递归

        递归操作文件目录

     

  • 相关阅读:
    使用微软消息队列实现C#进程间通信(转)
    JavaScript获得页面区域大小的代码
    我的第一份外包经历及所得 (转)
    用Aptana调试JavaScript教程(转)
    NET中的消息队列
    c#线程基础之线程控制
    c#线程基础之原子操作
    sql2005分区表示例
    系统资源调用和shell32.dll简介
    Windows API入门简介
  • 原文地址:https://www.cnblogs.com/Xiao_Xu/p/10537756.html
Copyright © 2020-2023  润新知