zoukankan      html  css  js  c++  java
  • Day 11 迭代器:global nonlocal :函数名运用:新格式化输出

    01 今日内容大纲

    1. global nonlocal
    2. 函数名的运用
    3. 新特性:格式化输出
    4. 迭代器:
      • 可迭代对象
      • 获取对象的方法
      • 判断一个对象是否是可迭代对象
      • 小结
      • 迭代器
      • 迭代器的定义
      • 判断一个对象是否是迭代器
      • 迭代器的取值
      • 可迭代对象如何转化成迭代器
      • while循环模拟for循环机制
      • 小结
      • 可迭代对象与迭代器的对比

    02 昨日内容回顾以及作业讲解

    1. 函数的参数:

      1. 实参角度:位置参数,关键字参数,混合参数。
      2. 形参角度:位置参数,默认参数,仅限关键字参数,万能参数。
      3. 形参角度参数顺序:位置参数,*args, 默认参数,仅限关键字参数,**kwargs.
    2. *的魔性用法:

      • 函数的定义时:代表聚合。
      • 函数的调用时:代表打散。
    3. python中存在三个空间:

      • 内置名称空间:存储的内置函数:print,input.......
      • 全局名称空间:py文件,存放的是py文件(除去函数,类内部的)的变量,函数名与函数的内存地址的关系。
      • 局部名称空间:存放的函数内部的变量与值的对应关系。
    4. 加载顺序:内置名称空间,全局名称空间, 局部名称空间(执行函数时)。

    5. 取值顺序:就近原则。LEGB.

      1. 局部作用域只能引用全局变量,不能修改。

        name = 'alex'
        def func():
        	name = name + 'sb'
        
    6. 作用域:

      • 全局作用域:内置名称空间 + 全局名称空间。
      • 局部作用域:局部名称空间。
    7. 函数的嵌套

    8. globals() locals()

    03 今日内容

    1. global nonlocal

      • 补充:

        默认参数的陷阱

        # 默认参数陷阱
        def func(name,sex='男'):
            print(name)
            print(sex)
        func('alex')
        # alex
        # 男
        
        # 陷阱只针对于默认参数是可变的数据类型
        def func(name,alist=[]):
            alist.append(name)
            return alist
        
        ret1 = func('alex')
        print(ret1,id(ret1))
        ret2 = func('太白金星')
        print(ret2,id(ret2))
        
        # 如果你的默认参数指向的是可变的数据类型,无论你调用多少次这个默认参数,都是同一个.
        
        def func(a,alist = []):
            alist.append(a)
            return alist
        print(func(10,))  #func(100,)还没执行
        print(func(20,[]))
        print(func(100,))
        
        def func(a,list=[]):
            list.append(a)
            return list
        ret1 = func(10,)
        ret2 = func(20,[])
        ret3 = func(100,)
        print(ret1)  #[10, 100]  函数已经调用
        print(ret2)  #[20]
        print(ret3)  #[10, 100]
        
      • 局部作用域的坑:

        # 局部作用域的坑
        
        count = 1
        def func():
            count += 1
            print(count)
        func()
        
        #在函数中,如果你定义了一个变量,但是在定义这个变量之前对其引用了,那么解释器认为:语法问题.
        # 你应该在使用之前先定义
        
        count = 1
        def func():
            print(count)
            count = 3
        func()
        
        

        global nonlocal:

        # global nonlocal
        
        # global
        # 1.在局部作用域声明一个全局变量
        name = 'alex'
        def func():
            global name
            print(name)
            name = '太白金星'
        
        
        func()
        print(name)
        
        def func():
            global name
            name = '太白金星'
            print(locals()) #{}
        print(name)
        print(globals())
        func()
        print(name)
        print(globals())
        
        # 2.修改一个全局变量
        count = 1
        def func():
            # print(count)
            global count
            count += 1
        print(count)
        func()
        print(count)
        
        
        # nonlocal
        # 1.不能操作全局变量
        count = 1
        def func():
            nonlocal count
            count += 1
        func()        #报错!
        
        # 2.局部作用域:内层函数对外层函数的局部变量进行修改
        def wrapper():
            count = 1
            def inner():
                nonlocal count
                count += 1
            print(count)
            inner()
            print(count)
        wrapper()
        
    2. 函数名的运用:

      def func():
          print(666)
      print(func)#<function func at 0x0000028026651EA0>
      #函数名指向的是函数的内存地址<function func at 0x0000028026651EA0>
      # 函数名+()就可以执行函数
      
      a = 1
      # a() 报错
      # func()
      # a = {'name': 'alex'}
      # b = {'age' : 18}
      a = 1
      b = 2
      print(a + b)
      print(func,type(func))  # <function func at 0x000001BA864E1D08> <class 'function'>
      
      # 2.函数名就是变量
      def func():
          print(666)
      print(func)
      
      # a = 2     #相当于
      # b = a
      # c = b
      # print(c)
      
      f = func
      f1 = f
      f2 = f1
      f()
      func()
      f1()
      f2()
      
      def func():
          print('in func')
      
      def func1():
          print('in func1')
      
      func1 = func
      func()      #in func
      
      # 3.函数名可以作为容器类数据类型的元素
      
      def func1():
          print('in func1')
      def func2():
          print('in func2')
      def func3():
          print('in func3')
      
      l1 = [func1,func2,func3]
      for i in l1:
          i()
      
      # 4.函数名可以作为函数的参数
      def func(a):
          print(a)
          print('in func')
      b = 3
      func(b)
      print(func)#<function func at 0x000001F3E79F1EA0>
      
      def func():
          print('in func')
      
      def func1(x):
          x()
          print('in func1')
      func1(func)
      
      # 5.函数名可以作为函数的返回值
      def func():
          print('in func')
      def func1(x):
          print('in func1')
          return x
      
      ret = func1(func)# = func
      ret()# = func()
      
      
    3. 新特性:格式化输出

      # 新特性:格式化输出
      name = '太白'
      age = 18
      msg = f'我叫{name},今年{age}'
      print(msg)
      
      # 可以加表达式
      dic = {'name':'alex','age':79}
      msg = f'我叫{dic["name"]},今年{dic["age"]}'
      print(msg)
      
      count = 7
      print(f'最终结果为{count**2}')
      
      name = 'barry'
      print(f'我的名字是{name.upper()}')
      
      # 结合函数写
      def _sum(a,b):
          return a+b
      
      msg = f'最终的结果是{_sum(2,5)}'
      print(msg)
      
      #!,:{}这些标点不能出现在{}里面
      # 优点:
      #   1.结构更加简化
      #   2.可以结合表达式和函数进行使用
      #   3.效率可以提升很多
      

      优点:

      1. 结构更加简化
      2. 可以结合表达式和函数进行使用
      3. 效率提升很多
    4. 迭代器:

      • 可迭代对象

        • 字面意思:对象? python中一切皆对象.一个实实在在存在的值

        • 可迭代?:更新迭代,重复的,循环的过程,更新迭代每次都有新内容

        • 可以进行循环更新的一个实实在在的值

        • 专业角度:可迭代对象?内部含有'__iter__'方法的对象,可迭代对象

        • 目前学过的可迭代对象? str list tuple dict set range文件句柄

        • 获取对象的所有方法并且以字符串的形式表现:dir()

        • 判断一个对象是否是可迭代对象:

          # 获取一个对象的所有方法:dir()
          s1 = 'afaasda'
          l1 = [11,22,33,44,55,66,77,88,99,]
          print(dir(s1))
          print(dir(l1))
          print('__iter__'in dir(s1))
          print('__iter__'in dir(range(10)))
          
          
        • 小结:

          • 字面意思:可以进行循环更新的一个实实在在值.
          • 专业角度:内部含有'__iter__'方法的对象,为可迭代对象
          • 判断一个对象是不是可迭代对象:'__iter__'in dir(对象)
          • str list tuple dict set range
          • 优点:
            1. 存储数据直接能显示,比较直观.
            2. 拥有的方法比较多,操作方便
          • 缺点:
            1. 占用内存
            2. 不能直接通过for 循环,不能直接取值(索引,key除外)(里面做了一步转化,先转化成迭代器,然后再取值)
        • 迭代器

        • 迭代器的定义

          • 字面意思:更新迭代,器:工具:可以更新迭代的工具
          • 专业角度:内部含有'__iter__'的方法,并且含有'__next__'方法的对象就是迭代器
          • 可以判断是否是迭代器:'__iter__'and'__next__'是否在dir(对象)中
        • 判断一个对象是否是迭代器:

          with open('文件1.txt',encoding='utf-8',mode='w') as f1:#文件曲柄为迭代器
              print(('__iter__'in dir(f1))and('__next__'in dir(f1)))
          
        • 迭代器的取值:

          # 可迭代对象可以转化成迭代器
          s1 = 'a;akldsjfklsdlk'
          obj = iter(s1)#s1.__iter__()
          print(obj)
          print(next(obj))#print(obj.__next__())
          print(next(obj))
          print(next(obj))
          print(next(obj))
          print(next(obj))
          print(next(obj))
          print(next(obj))
          print(next(obj))
          
          # 可迭代对象可以转化成迭代器
          s1 = 'a;akldsjfklsdlk'
          obj = iter(s1)#s1.__iter__()
          print(obj)
          print(next(obj))#print(obj.__next__())
          print(next(obj))
          print(next(obj))
          print(next(obj))
          print(next(obj))
          print(next(obj))
          print(next(obj))
          print(next(obj))
          
          
        • 可迭代对象如和转化成迭代器

          iter([1,2,3,4,5])

        • while循环模拟for 循环机制

          l1 = [11,22,33,44,55,66,77,88,99,1111,1133,15652]
          # for i in l1:
          #     print(i)
          # 利用while 循环,模拟for 循环和迭代器对象的取值机制:
          obj = iter(l1)
          while 1:
              try:
                  print(next(obj))
              except StopIteration:#报错类型
                  break
          
          
        • 小结:

          • 字面意思:更新迭代,器:工具:可更新迭代的工具
          • 专业角度:内部含有'__iter__'方法并含有'__next__'方法的对象就是迭代器
          • 优点:
            1. 节省内存
            2. 惰性机制,next一次,只取一个值
          • 缺点:
            • 速度慢
            • 不走回头路
      • 可迭代对象与迭代器的对比:

        • 可迭代对象是一个操作方法多,比较直观,存储数据相对少(几百万个对象,8G内存可以承受)的一个数据集.
        • 当你侧重于对于数据可以灵活处理,并且内存空间足够将数据集设置为可迭代对象是明确的选择.
        • 迭代器,非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但不直观,操作方法比较单一的数据集.
        • 当你数据量过大,大到足以撑爆内存或者以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择

    04 今日总结

    1. 默认参数的坑,作用域的坑!!!
    2. 格式化输出
    3. 函数名的应用
      1. 可以做赋值运算
      2. 可以做容器类型的元素
      3. 可以做函数的参数
      4. 可以做函数的返回值
    4. 对比:迭代器是什么?迭代器的优缺点,可迭代对象转化成迭代器,next对迭代器取值

    05 明日内容

    • 生成器
    • 列表推导式
  • 相关阅读:
    angular源码分析:angular中$rootscope的实现——scope的一生
    angular源码分析:图解angular的启动流程
    angular源码分析:angular的整个加载流程
    angular源码分析:injector.js文件分析——angular中的依赖注入式如何实现的(续)
    angular源码分析:angular中jqLite的实现——你可以丢掉jQuery了
    第二章:互联网的进化成型
    angular源码分析:angular的源代码目录结构说明
    angular源码分析:angular中各种常用函数,比较省代码的各种小技巧
    angular源码分析:angular中的依赖注入式如何实现的
    【Linux】Shell基础命令、文件软(硬)链接的理解
  • 原文地址:https://www.cnblogs.com/Redbean1231/p/13330195.html
Copyright © 2011-2022 走看看