函数二函数进阶二

函数进阶二

  1. 关键字

    globla:在局部作用域声明全局变量(此变量只存在于全局,局部是没有的,但可以在局部进行更改)

    • 声明一个全局变量
    • 在局部要对全局变量进行修改时要用到global
    def func():
        global a
        a = 3
    func()
    print(a)
    

    nonlocal:在局部作用域对父级作用域变量进行修改时需要用到nonlocal

    • 不能改变全局变量
    • 在局部作用域中,对父级作用域的变量进行引用和修改,并且引用的哪层从那层以下此变量全部发生改变
    def add_b():
        b = 42
        def do_global():
            b = 10
            print(b)
            def dd_nonlocal():
                nonlocal b
                b = b + 20		#改变的是dd_nonlocal()和do_global()中b的大小
                print(b)
            dd_nonlocal()
            print(b)
        do_global()
        print(b)
    add_b()
    结果:
    10 30 30 42
    
  2. 默认参数的坑

    当你的默认参数如果是可变的数据类型,每次执行函数都是对同一个对象进行更改

    def func(a,l=[]):
    	l.append(a)
        return l
    print(func(1))  # [1,]
    print(func(2))  # [2,]
    print(func(3))  # [3,]
    结果:
    [1,2,3]
    
  3. 函数名的应用

    函数名是一个特殊的变量

    • 函数名指向的是函数的内存地址,加上()就执行这个函数

    • 函数名是一个变量

      age1 = 12
      age2 = age1
      age3 = age2
      print(age3)
      def func():
      	print(666)
      f1 = func
      f2 = f1
      f2()
      f1()
      结果:
      12 666 666
      
    • 函数名可以作为容器类类型的元素

      def func1():
          print('in func1')
      def func2():
          print('in func2')
      def func3():
          print('in func3')
      l = [func1,func2,func3]
      for i in l:
          i()
      结果:
      in func1	in func2	in func3
      
    • 函数名可以作为函数的实参

      def func1():
          print('in func1')
      def func2(argv):
          argv()
          print('in func2')
      func2(func1)
      结果:
      in func1
      in func2
      
    • 函数名可以作为函数返回值

      b = 666
      def func1(argv):
          print('in func1')
          return argv
      ret = func1(b)
      print(ret)
      结果:
      in func1
      666
      
  4. 新的格式化输出 f'{}'

    • f/F 不区分大小写
    • {}中可加入表达式
    • 可以结合函数
    • 不能放一些特殊的字符 ! , : {} ;
  5. 可迭代对象

    1. 定义

      可以重复迭代的实实在在的东西。

      内部含有'__iter__'方法的对象

      目前接触到的有:str,dict,tuple,set,range,文件句柄

    2. 判断一个对象是否是可迭代对象

      内置函数:dir()

      print('iter' in dir(str))
      
    3. 优点:

      • 直观。
      • 操作方法比较多
    4. 缺点:

      • 占内存
      • 不能迭代取值(除去索引和字典的key)
  6. 迭代器

    1. 定义

      字面意思:可以重复迭代的工具

      专业角度:内部含有'__iter__'并且含有'__next__'方法的对象,就是迭代器

    2. 可迭代对象转化为迭代器

      • 使用内置函数iter()将可迭代对象转化为迭代器,使用next()对迭代器进行取值
      # 迭代器可以迭代取值。利用next()进行取值
      l1 = [1, 2, 3, 4, 5]
      # 内置函数iter()
      obj = iter(l1)
      # print(obj)
      print(next(obj))
      print(next(obj))
      print(next(obj))
      print(next(obj))
      print(next(obj))
      print(next(obj))
      结果:
      1
      2
      3
      4
      5
      报错:StopIteration
      
      • python中的异常处理

        try except

      li = [1]
      try:
          li[100]
      except:
          IndexError
      
      • 使用while循环模拟for循环循环机制

        • 先要将可迭代对象转化成迭代器。
        • 利用next对迭代器进行取值。
        • 利用异常处理try一下防止报错。
        li = [1,2,3,4,5]
        obj = iter(li)
        while 1:
            try:
                print(next(obj))
            except StopIteration:
                break
        结果:
        1 2 3 4 5  
        
    3. 优点:

      • 非常节省内存
      • 惰性机制
    4. 缺点:

      • 不直观
      • 操作不灵活
      • 效率相对低
    5. 特性

      l1 = [22, 33, 44, 55, 66, 77]
      obj = iter(l1)
      for i in range(3):
          print(next(obj))
      for i in range(2):
          print(next(obj))
      结果:
      22 33 44 55 66
      
    6. 可迭代对象与迭代器对比

      • 可迭代对象

        是一个私有的方法比较多,操作灵活(比如列表,字典的增删改查,字符串的常用操作方法等),比较直观,但是占用内存,而且不能直接通过循环迭代取值的这么一个数据集。

        应用:当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。

      • 迭代器

        是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。

        应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。(可参考为什么python把文件句柄设置成迭代器)。

posted @ 2019-06-19 20:48  小小蚂蚁mm  阅读(114)  评论(0编辑  收藏  举报