函数使用 (三)

零碎知识

  • 灵活的 if-else

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    if True:
    print('真')
    else:
    print('假')

    # 相当于限制条件写在了后面
    a = 3 if False else 5
    print(a)

    # 相当于简化了这段代码
    if False:
    a = 3
    else:
    a = 5
    1
    2
    3
    4
    5
    # 示例:成绩等级评价
    while 1:
    score = int(input('请输入考试成绩(0-100):'))
    evaluation = '优秀' if 90 <= score <= 100 else '良好' if 70 <= score < 90 else '及格' if 60 <= score < 70 else '不及格' if 0 <= score < 60 else '请输入有效的成绩(0-100)'
    print(evaluation)
  • 灵活的 or

    1
    2
    3
    4
    5
    6
    # or 表示逻辑或

    # 赋值前会判断前面的值,若为真则使用,若为假,则使用or后面的值
    a = False or 2

    print(a)
  • 类型判断

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    a = 10
    print(type(a))

    # 判断是否是整型
    if type(a) == int:
    print('整型')

    # 判断一个变量是否是一个类型的实例,是返回True,不是返回False
    print(isinstance(a, int))
    print(isinstance(a, float))
  • 判断是否是同一变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    a = [1, 2, 3]
    # b = a
    b = a.copy()

    # 判断内容是否一样
    if a == b:
    print('a等于b')

    # 判断是否是同一个对象
    if id(a) == id(b):
    print('是同一个')

    # 判断是否是同一个对象
    if a is b:
    print('是同一个')

匿名函数

  • 函数可以像普通变量一样赋值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 函数可以像普通变量一样赋值
    def hello():
    print('hello world')


    print(hello.__name__)

    a = hello

    print(a.__name__)

    hello()
    a()
  • 函数可以作为参数传递,拓展函数的功能
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 函数可以作为参数传递
    def add(a, b):
    return a + b


    def calc(a, b, func):
    return func(a, b)


    print(calc(2, 3, add))
  • 场景:当函数作为另一个函数的参数,只使用一次也得定义,否则无法使用,于是匿名函数就出现了
  • 定义:就是没有名字的函数,使用 lambda 关键字定义
  • 格式:
    • lambda 开头
    • 后面跟上该匿名函数的参数,多个使用逗号隔开
    • 最后一个参数后面跟上冒号 :
    • 冒号的后面跟上一个表达式,这个表达式就是返回值,不需要使用 return
  • 示例 1:
    1
    2
    3
    4
    5
    6
    7
    def calc(a, b, func):
    return func(a, b)


    # mul = lambda x, y: x * y
    # print(calc(3, 5, mul))
    print(calc(3, 5, lambda x, y: x * y))
  • 示例 2:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    l = [5, 3, 2, 6, 1]
    l = [
    {'name': 'xiaowang', 'age': 15, 'height': 150},
    {'name': 'xiaodu', 'age': 14, 'height': 145},
    {'name': 'xiaopang', 'age': 12, 'height': 140},
    {'name': 'banhua', 'age': 13, 'height': 155},
    ]

    # def d_key(d):
    # return d['age']
    # l.sort(key=d_key)

    # 当列表这个的元素无法比较大小时,需要传递参数key
    # key是一个函数,接受元素作为参数,返回用于用于比较的项
    l.sort(key=lambda x: x['height'])
    for i in l:
    print(i)

练习(不强求)

  • 试着自己封装一个列表的 sort 函数,接受参数:排序对象、key、reverse

闭包

  • 定义:
    • 外部函数中定义一个内部函数,
    • 内部函数中使用了外部函数的变量,
    • 外部函数将内部函数作为返回值返回。
  • 示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    '''
    # 这不是闭包
    def wai():
    def nei():
    print('内部函数')
    return nei

    a = wai()
    a()
    '''

    '''
    def wai(n):
    def nei():
    return n * n

    return nei


    f1 = wai(3)
    f2 = wai(5)

    print(f1())
    print(f2())
    '''

    '''
    def wai(*args):
    def nei():
    he = 0
    for i in args:
    he += i
    return he

    return nei


    f1 = wai(1, 2, 3)
    print(f1())
    '''


    # y = ax + b
    def wai(a, b):
    def nei(x):
    return a * x + b

    return nei


    f1 = wai(3, 5)
    # f1 <=> y = 3*x + 5

    print(f1(3))

    f2 = wai(5, 8)
    print(f2(6))

    print(wai(2, 3)(4))
  • 作用:提高代码的复用度

装饰器

  • 作用:当我们想要增强已有函数的功能,但不想(无法)修改原函数,可以使用装饰器解决
  • 使用:
    • 先写一个装饰器,就是一个函数,该函数接受一个函数作为参数,返回一个闭包,而且闭包中执行传递进来的函数,闭包中可以在函数执行的前后添加一些内容。
    • 在需要装饰的函数前添加 @装饰器名 就可以使用了,如:
      1
      2
      3
      @zhuangshiqi  # 等价于 show = zhuangshiqi(show)
      def show():
      print('原函数的内容')
    • 再使用原函数时,就已经是装饰过的了
  • 示例 1:无参无返回值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    def zhuangshiqi(func):
    def wrapper():
    print('原函数前边添加的内容')
    func()
    print('原函数后边添加的内容')

    return wrapper


    @zhuangshiqi # 等价于 show = zhuangshiqi(show)
    def show():
    print('原函数的内容')


    show()
  • 示例 2:带参数的装饰器
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 带参数的装饰器
    def zhuangshiqi(func):
    def wrapper(*args, **kwargs):
    print('今天天气不错,出门就打到车了')
    func(*args, **kwargs)

    return wrapper


    @zhuangshiqi
    def test(n):
    print('我的幸运数字是:{}'.format(n))


    test(7)
  • 示例 3:带参数有返回值的装饰器
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 带参数有返回值的装饰器
    def zhuangshiqi(func):
    def wrapper(*args, **kwargs):
    return func(*args, **kwargs) + 10

    return wrapper


    @zhuangshiqi
    def pingfang(n):
    return n * n


    print(pingfang(4))

生成器(generator)

  • 列表生成式,可以快速的生成列表
    1
    2
    3
    4
    5
    # 数据量非常小,内存占用不大
    l = print([i for i in range(10)])

    # 数据量特别大,会造成内存占用突然增大
    l2 = [i for i in range(10000)]
  • 为了解决内存突然增大问题,python 中引入了生成器
  • 产生方式:
    • 将列表生成式的 [] 改为 ()
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      # 数据量非常小,内存占用不大
      l = [i for i in range(10)]

      # 数据量特别大,会造成内存占用突然增大
      # l2 = [i for i in range(10000)]

      # 生成器
      l2 = (i for i in range(2))

      print(type(l))
      print(type(l2))

      # 可以转换为列表
      # print(list(l2))

      # 使用next获取生成器的值,一次一个,遍历结束会报错
      # print(next(l2))
      # print(next(l2))
      # print(next(l2))

      # 可以for-in遍历
      for i in l2:
      print(i)
    • 通过在函数中使用 yield 关键字
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      def test(n):
      l = []
      for i in range(1, n + 1):
      l.append(i)
      return l


      # print(test(5))

      def test2(n):
      for i in range(1, n + 1):
      yield i


      t = test2(5)
      for j in t:
      print(j)
  • 特性:
    • 可以使用 next 获取数据,一次一个,结束时会报错
    • 只能遍历一遍
    • 可以转换为列表
    • 可以使用 for-in 遍历