• day011 迭代器闭包


    三.今日主要内容
    1.第一类对象,函数名的使用
    函数名就是变量名,函数名存储的是函数的内存地址

    变量的命名规范:
    1.有数字,字母,下划线组成
    2.不能是数字开头,更不能是纯数字
    3.不能用关键字
    4.不能太长
    5.要有意义
    6.不要用中文
    7.要区分大小写
    8.驼峰或者下划线法

    2.闭包
    闭包:在内层函数中引入外层函数的变量
    作用:
    1.保护变量不受侵害(javascript)
    2.让一个变量常驻内存(函数的调用有可能在很多行代码之后)

    3.迭代器
    dir() 查看变量能够执行的方法(函数)
    Iterable:可迭代的, __iter__()
    Iterator:迭代器 __iter__(), __next__()

    for循环的过程:
    it = lst.__iter__()
    while 1:
    try:
    el = it.__next__()
    print(el)
    exception StopIteration:
    break
    从迭代器中获取数据的唯一方法:__next__()

    迭代器的三个特性:
    1.节省内存空间
    2.惰性机制
    3.只能往前,不能后退


    # 函数名遵循变量名的命名规则

    # # 2.函数名的运用
    # 1.函数名的内存地址

    a = 10
    b = a
    print(b)

    def a():
    print("我是可怜的a")

    b = a
    print(b) #<function a at 0x000002635AF41EA0>, 函数名存储函数命名空间的内存地址
    b() #我是可怜的a, b()执行a里面的函数,




    # 2.函数名可以赋值给其他变量
    def a():
    print("我是可怜的a")

    b = a
    b()

    # 3.函数名可以当做容器类的元素

    def func1():
    print("我是fun1")
    def func2():
    print("我是func2")
    def func3():
    print("我是func3")


    lst = [func1, func2, func3]
    print(lst) # [<function func1 at 0x000001F9D8601EA0>, <function func2 at 0x000001F9DA2C5EA0>, <function func3 at 0x000001F9DA2C5F28>]
    for i in lst:
    i()
    # 我是fun1
    # 我是func2
    # 我是func3

    # 4.函数名可以当做函数的参数

    # 代理模式
    # 装饰器的雏形
    # 把函数名当成变量来使用
    def chi(fn):
    print("开挂")
    fn()
    print(fn.__name__)
    print("洗包")

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

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

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

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

    chi(he)

    def outer():
    def inner():
    print("哈哈")
    return inner()
    outer()()

    def func():
    print("吃了么")
    def func2(fn):
    print("我是func2")
    func()
    print("我是func2")
    func2(func)

    # 5.函数名可以作为函数的返回值

    def outer():
    def inner():
    print("我是inner")

    return inner

    ret = outer()
    print(ret) #<function outer.<locals>.inner at 0x000001A7909920D0>
    ret() #我是inner

    def func_1():
    print("这里是函数1")
    def func_2():
    print("这里是函数2")
    print("这里是函数1")
    return func_2

    fn = func_1()
    print(fn)
    fn()

    def yue():
    print("1. 打开手机")
    print("2. 打开微信")
    print("3. 找个漂亮的小姐姐")
    print("4. 探讨一下人生")
    print("5. 一起出来happy")
    return "漂亮的小姐姐","大妈", "大爷", "鲜肉" # 返回到哪儿了???? 谁调用的就返回给谁

    ret = yue() # ('漂亮的小姐姐', '大妈', '大爷', '鲜肉')
    print(ret)

    # 1. 打开手机
    # 2. 打开微信
    # 3. 找个漂亮的小姐姐
    # 4. 探讨一下人生
    # 5. 一起出来happy
    # ('漂亮的小姐姐', '大妈', '大爷', '鲜肉')

    # 闭包,就是内层函数对外层函数(非全局)地变量的引用,叫闭包
    # 作用
    # 1.保护我们的变量不受侵害
    # 2.可以让一个变量常驻内存

    a = 10
    def func1():
    print(a)

    def func2():
    print(a)

    func1()

    # 你的同事搞事情
    def func3():
    global a
    a = 20

    func3()

    func2()

    def func():
    a = 10 # 安全的
    def func2():
    print(a)
    def func3():
    print(a)
    def func4():
    nonlocal a
    a = 20

    # 什么是闭包
    def func1():
    name = 'alex'
    def func2():
    print(name)
    func2()
    func1()

    # 我们可以使用__closure__来检测函数是否是闭包,使用函数名.__closure__返回cell就是闭包,返回None就是不闭包
    def func1():
    name ="karen"
    def func2():
    print(name)
    func2()
    print(func2)
    func1()

    # karen
    # <function func1.<locals>.func2 at 0x000002A176165EA0>

    # 如何在函数外边调用内部函数?
    def outer():
    name = 'karen'
    def inner():
    print(name)
    return inner
    fn = outer() # 访问外部函数,获取到内部函数的函数地址
    # 1800行代码...
    fn() # 访问内部函数,由于fn函数执行的时机是不确定的,必须要保证fn可以正常执行,必须把a保留到最后

    # 如果是多层嵌套
    def func1():
    # def func2():
    # def func3():
    # print('嘿嘿')
    # return func3
    # return func2
    # func1()()()

    # 由它我们可以引出闭包的好处. 由于我们在外界可以访问内部函数. 那这个时候内部函
    # 数访问的时间和时机就不⼀一定了了, 因为在外部, 我可以选择在任意的时间去访问内部函数. 这
    # 个时候. 想⼀一想. 我们之前说过, 如果⼀一个函数执⾏行行完毕. 则这个函数中的变量量以及局部命名
    # 空间中的内容都将会被销毁. 在闭包中. 如果变量量被销毁了了. 那内部函数将不能正常执⾏行行. 所
    # 以. python规定. 如果你在内部函数中访问了了外层函数中的变量量. 那么这个变量量将不会消亡.
    # 将会常驻在内存中. 也就是说. 使⽤用闭包, 可以保证外层函数中的变量量在内存中常驻. 这样做
    # 有什什么好处呢? 非常⼤大的好处. 我们来看⼀一个关于爬⾍虫的代码:
    from urllib.request import urlopen

    def but():
    content = urlopen("http://www.xiaohua100.cn/index.html").read()
    def get_content():
    return content
    return get_content()

    fn = but() # 这个时候就开始加载校花100的内容
    content = fn() # 获取内容
    print(content)

    content2 = fn() # 重新获取内容
    print(content2)
    # 综上,必报的作用就是让一个变量能够常驻内存,供后面的程序使用

    def func():
    a = 10
    def aa():
    print("哈哈")
    return aa
    ret = func()
    ret()

    # 可迭代的对象
    # str, list, tuple, dict, set,open()
    # int中没有__iter__
    # 可迭代对象dir(可迭代对象)里面都有__iter__函数
    # 可以通过isinstance()函数来查看一个对象是什么类型的
    lst = ["汉高祖", "清高祖", "明高祖", "哈哈", "娃哈哈", "爽歪歪"]
    it = lst.__iter__()
    print(it) #<list_iterator object at 0x0000024B2FC7A2B0>迭代器

    print(dir(it))

    print(it.__next__())
    print(it.__next__())
    print(it.__next__())
    print(it.__next__())
    print(it.__next__())
    print(it.__next__())
    print(it.__next__()) #StopIteration

    # for 循环内部的代码
    it = lst.__iter__()
    # while 1:
    # try:
    # el = it.__next__()
    # except StopIteration:
    # break

    # 三个特点
    # 1.节省内存(生成器)
    # 2.惰性机制,必须使用__next__()来获取数据
    # 3.只能往前,不能后退

    it = lst.__iter__()
    print(it.__next__())
    print(it.__next__())
    print(it.__next__())
    print("回去")
    it = lst.__iter__() # 重新获取迭代器
    print(it.__next__())

    # list(内部有for循环)
    # for内部 迭代器

    lst = [1,55,5,55,5,5,5,555,55,555]
    ll = list(set(lst))
    print(ll)


    list(1) # 'int' object is not iterable

    # 如何判断一个数据是否是可迭代对象
    # 1. dir() -> __iter__ 可迭代的
    # dir() -> __next__ 迭代器
    lst = ["秦始皇", "汉武帝", "孝文帝", "隋炀帝", "李世民"]
    print("__iter__" in dir(lst))
    print("__next__" in dir(lst))

    print("__iter__" in dir(int))
    print("__next__" in dir(int))
    #
    it = lst.__iter__()
    print("__iter__" in dir(it))
    print("__next__" in dir(it))

    lst = ["秦始皇", "汉武帝", "孝文帝", "隋炀帝", "李世民"]
    # # collections 关于集合类的相关操作
    # # Iterable : 可迭代的
    # # Iterator : 迭代器
    from collections import Iterable, Iterator
    print(isinstance(lst, Iterable))
    print(isinstance(lst, Iterator))

    print(isinstance({1,2,3}, Iterable))

    # 我们可以把要迭代的内容当成⼦子弹. 然后呢. 获取到迭代器__iter__(), 就把⼦子弹都装在弹夹
    # # 中. 然后发射就是__next__()把每⼀一个⼦子弹(元素)打出来. 也就是说, for循环的时候. ⼀一开始的
    # # 时候是__iter__()来获取迭代器. 后⾯面每次获取元素都是通过__next__()来完成的. 当程序遇到
    # # StopIteration将结束循环.
  • 相关阅读:
    DateTime与DateTime?赋值问题以及null类型的如何赋值问题
    ajax请求aspx.cs后台方法
    Windows 下安装 Memcached
    windows下mysql表名区分大小写
    csredis
    路由名称
    发布后的项目打开swagger
    IActionResult的返回类型
    ASP.NET Core开发之HttpContext
    Web SQL数据库
  • 原文地址:https://www.cnblogs.com/zero-zero-zero/p/9885753.html
Copyright © 2020-2023  润新知