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 明日内容

    • 生成器
    • 列表推导式
  • 相关阅读:
    基于Metaweblog API 接口一键发布到国内外主流博客平台
    uva144 Student Grants
    Uva 10452
    Uva 439 Knight Moves
    Uva 352 The Seasonal War
    switch语句
    java——基础知识
    我的lua学习2
    codeforces 431 D. Random Task 组合数学
    codeforces 285 D. Permutation Sum 状压 dfs打表
  • 原文地址:https://www.cnblogs.com/Redbean1231/p/13330195.html
Copyright © 2011-2022 走看看