Loading

8-函数高级

函数高级使用

  • f:既是函数名称,也是指向函数的一个变量

  • 所有指向函数的变量都可以调用该函数

  • 回调函数

    • m1(3, m2)
    • m1是普通函数,m2作为参数,在m1内部调用m2

函数作用域

  • 作用域:起作用的范围
  • 局部变量与全局变量
    • 局部变量:函数内部定义的变量,只能在函数内部使用
      • nonlocal b
      • 调用非本地(函数内部)的最近的b
      • 优点:不会被外部干扰
      • 缺点:内存会被回收(变量会被删除)
    • 全局变量:函数外部定义的变量,具有全局作用域
      • 默认不可以修改全局变量
      • global 作用是a使用的是全局变量a
        • global a
      • 优点:内存不会被回收(变量不会被删除)
      • 缺点:可能会被干扰

函数嵌套和闭包

  • 函数嵌套

    • def f1():
          print('f1')
          def f2():
              print('f2')
          # f2()
          return f2
      res = f1()  # res = f2
      res()  # 等价于f2()
      
    • 传参

      • f(3)(4)
  • 函数闭包

    • 闭包:函数嵌套,把内部函数返回,可以让外部函数中的参数或变量不被释放(让变量不消失)

    • 闭包的特点:不会被外部干扰,内存也不会被回收

      • def out():
            p = 10
            def inner():
                nonlocal p
                p += 1
                print('p=', p)
            return inner
        
        f = out()  # f = inner
        f()  # 11,相当于inner()
        f()  # 12
        f()  # 13
        

生成器扩展

  • 生成器和迭代器很相似,其实它们都是消费者和生产者模型,都是用户通过next()方法来获得数据,而生成器和迭代器都是只有用户在调用next()时才返回数据。不同的是迭代器是通过自己实现next()方法来逐步返回数据,而生成器则使用yield自动完成了提供数据并且让程序进入wait状态,等待用户的进一步操作,所以生成器更加灵活和方便
  • 生成器的方法
    • next()方法
    • send(msg)方法
      • 当使用send(msg)发送消息给生成器时,wait_and_get会检测到这个信息,然后唤醒生成器,同时该方法获取msg并赋值给x
      • g.send(5)
    • throw()方法
      • 生成器提供throw()方法从生成器内部来引发异常,从而控制生成器的执行
      • h.throw(GeneratorExit)
    • close()方法
      • 当使用close()方法时,生成器会直接从当前状态退出
    • 生成器的用途
      • 节省内存
      • 线性遍历访问数据
        • 生成器可以将非线性化的处理转换成线性化的方式,典型的例子就是对二叉树的访问。传统的方法是使用递归函数来访问和处理,需要将处理方法放到访问的过程中,既容易出错也不清晰。比较好的方法是先将树的节点访问转换成线性,然后在外面遍历每一个节点,这样一来,处理每个节点的过程不需要放到访问每个节点的diamagnetic中去,更加清晰

列表生成器&列表生成式

  • 列表生成式

    • ages = [i * 10 for i in range(2, 5) if 2 < i < 4]
    • l3 = [i+j for i in l1 for j in l2]
  • 字典生成式

    • d = {i: i+1 for i in range(1, 4)} #
  • 列表生成器

    • ages = (i for i in range(5)) # <generator object <genexpr> at 0x0000015A66E54AC8>

    • 生成器对象:可以不一次性占用太多的内存空间,我们一般需要一个一个元素取出来

    • next函数

      • print(next(ages))  # 0
        print(next(ages))  # 1
        print(next(ages))  # 2
        
    • 生成器函数

      • 生成器函数:在普通函数中包含yield关键字,则是生成器函数
      • yield:
        • 1.写在函数中,让普通函数变成生成器函数
        • 2.可以返回值,但是不会退出函数
        • 3.需要结合next使用,每次使用next,则会运行至下一个yield

计算代码耗时

  • 计算代码耗时

    • import time
      start = time.time()  # 获取当前时间
      for i in range(1000):
          pass
      end = time.time()
      print(end - start)
      

可迭代对象&迭代器

  • from collections.abc import Iterable # 可迭代对象

  • from collections.abc import Iterator # 迭代器

  • 可迭代对象

    • 可迭代对象:只要可以使用for-in循环,就是可迭代对象
    • 有:list, tuple, dict, set, str,generator
  • isinstance(): 检测某个对象是否属于某个类

    • print(isinstance([1, 3], Iterable)) # True
  • 迭代器

    • 迭代器:既要能用for-in循环,且可以使用next调用

    • iter():将可迭代对象变成迭代器

      • l = [1, 3, 4]
        l2 = iter(l)
        print(l2)  # <list_iterator object at 0x0000017DB5C4BE48>
        print(next(l2))  # 1
        print(list(l2))  # [3, 4], 1已经被取出了
        
    • _iter_()将可迭代对象变成迭代器

      • l1 = [1, 3, 4]
        l1_iter = l1.__iter__()
        print(type(l1_iter))  # <class 'list_iterator'>
        for x in l1_iter:
            print(x)
        

偏函数

print(int('10'))
print(int('10', base=2))  # 2,将10看成是二进制
print(int('1010', base=8))  # 520

import functools
int2 = functools.partial(int, base=2)
print(int2('1010'))  # 10
posted @ 2020-11-19 19:04  lotuslaw  阅读(90)  评论(0编辑  收藏  举报