【飞桨/百度领航团/零基础Python】百度飞桨领航团零基础Python速成营笔记-03

文章目录

  • 一、函数
      • 1.1、函数的定义
      • 1.2、定义一个函数;函数调用
  • 二、参数传递
      • 2.1、位置参数
      • 2.2、缺省参数
      • 2.3、可变参数
      • 2.4、关键字参数
      • 2.5、命名关键字参数
      • 2.6、参数的组合
  • 三、变量的作用域和global变量
  • 四、lambda匿名函数
  • 五、高阶函数
      • 5.1、map / reduce
      • 5.2、sorted:返回的是排序的结果
  • 六、装饰器
      • 6.1、函数作为返回值
      • 6.2、闭包
      • 6.3、装饰器
      • 6.4、偏函数
  • 七、模块
      • 7.1、安装 / 卸载第三方模块

课程传送门

一、函数

1.1、函数的定义

  • 函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。

  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。

  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。

  • 函数内容以冒号起始,并且缩进。

  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

1.2、定义一个函数;函数调用

  • 例子

    def student_name(name):
        "打印学生的名字"
        print('姓名:', name)
        return {
           '姓名':name}
    
    rst = student_name('Alice')
    print(rst) 
    '''结果:
    姓名: Alice
    {'姓名': 'Alice'}'''
    
  • 返回多个值的函数:

    def student_name_and_age():
        "记录学生的名字和年龄"
        name = input('请输入姓名\n')
        age = int(input('请输入年龄\n'))
        print(f'姓名:{name};年龄:{age}')
        return name,age
    #有两种接受返回值方式
    rst = student_name_and_age()  #rst是tuple类型
    name, age = student_name_and_age()  #name和age要和函数的返回位置相对应,否则会传错值
    
  • 函数的嵌套使用

    def worker(s):
        rst = 10 / float(s)
        return rst
    
    def group_leader(s):
        rst = worker(s) * 2
        return rst
    
    def CTO(s):
        return group_leader(s)
    CTO('4')
    

二、参数传递

2.1、位置参数

  • 位置参数是最简单的一种函数调用的方式。位置参数须以正确的顺序传入函数、数量必须和声明时的一样。

  • 例子

    def student_name_and_age(name, age):
        print('姓名:%s 年龄 %s' %(name, age))
    student_name_and_age('张三', 18)
    

2.2、缺省参数

  • 调用函数时,缺省参数的值如果没有传入,则被认为是默认值。

  • 例子

    def student_name_and_age(name, age='不愿透露'):
        "设置默认参数"
        print('姓名:%s 年龄 %s' %(name, age))
    student_name_and_age('张三')
    

2.3、可变参数

  • 顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。

  • 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple

  • 例子

    def all_student_names(*names):     #这里的names是tuple类型
        for name in names:
            print('姓名:', name)
    all_student_names('张三','李四','王五')
    
    #运行结果和上面一样
    names = ('张三','李四','王五')
    all_student_names(names)
    

2.4、关键字参数

  • 关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict

  • 例子01

    def student_info(name, age, **kw):
        print(f'我的名字叫:{name},年龄:{age},其它信息:{kw}')
        if 'city' in kw:
            print('来自:', kw['city'])
    student_info('张三', 18, height=180, city='北京')
    '''
    结果:
    我的名字叫:张三,年龄:18,其它信息:{'height': 180, 'city': '北京'}
    来自: 北京
    '''
    
  • 例子02

    def score_info(name, **kw):
        if '语文成绩' in kw:
            print(name, '的语文成绩', kw['语文成绩'])
        if '数学成绩' in kw:
            print(name, '的数学成绩', kw['数学成绩'])
            
    
    def person_info(name, age, **kw):
        print('姓名:', name, '年龄:',age)
        score_info(name, **kw)    
    
    score_cfg = {
           '语文成绩':65, '数学成绩':60}
    person_info('张三', 18, **score_cfg)
    '''
    结果:
    姓名: 张三 年龄: 18
    张三 的语文成绩 65
    张三 的数学成绩 60
    '''
    

2.5、命名关键字参数

  • 如果要限制关键字参数的名字,就可以用命名关键字参数

  • 例子

    def print_person_info(name, age, *, height, weight):
        print('我的名字叫:', name, '年龄:', age,'身高', height, '体重', weight)
        
    print_person_info('张三', 18, height=180, weight=75)
    

2.6、参数的组合

  • 在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数

  • 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:

  • 例子01

    def student_info(name, age=18, *books, **kw):
        print('我的名字叫:', name, '年龄:', age,'其它信息:',kw)
        if 'city' in kw:
            print('来自:', kw['city'])
        for book in books:
            print('我有',book,'书')
            
    student_info('张三', 20, '语文','数学','计算机', city='北京', height=180, weight=75)
    '''
    结果
    我的名字叫: 张三 年龄: 20 其它信息: {'city': '北京', 'height': 180, 'weight': 75}
    来自: 北京
    我有 语文 书
    我有 数学 书
    我有 计算机 书
    '''
    
  • 例子02

    def student_info(name, age=18, *books, city, **kw):
        # 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
        print('我的名字叫:', name, '年龄:', age,'其它信息:',kw)
        print('来自:', city)
        for book in books:
            print('我有',book,'书')
            
    student_info('张三', 18, '语文','数学','计算机', city='北京', height=180, weight=75)
    

三、变量的作用域和global变量

  • 局部变量 作用域:在函数内:定义在函数内部的变量,函数结束之后自动消亡

  • 全局变量 作用域:在函数外

  • 函数优先使用局部变量 在没有局部变量的情况下, 使用全局变量

  • 例子

    def change_my_name():
        global name  #global说明这里的name是全局变量,没有global会报错
        print('我的名字曾经是', name)
        name = '李四'
        print('我的名字现在是', name)
        
    name = '张三'
    change_my_name()
    print(name)
    '''
    结果
    我的名字曾经是 张三
    我的名字现在是 李四
    '李四'
    '''
    

四、lambda匿名函数

  • python 使用 lambda 来创建匿名函数。

  • lambda 只是一个表达式,函数体比 def 简单很多。

  • lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。

  • lambda 函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。

  • 虽然 lambda 函数看起来只能写一行,却不等同于 C 或 C++ 的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

  • 例子:lambda 若干个输入参数 : 返回值的表达式

    # 加法运算 接受两个参数,返回参数之和
    add = lambda arg1, arg2: arg1 + arg2   
    add(1,2)
    
    # 数字转字符串
    int2str = lambda x : str(x)
    int2str(5)
    

五、高阶函数

  • 定义:一个函数可以接收另一个函数作为参数,这种函数就称之为高阶函数。

  • 函数名其实就是指向函数的变量!

    my_print = print 
    my_print('a')
    
  • 例子:

    def func_x(x, f):
        return f(x)
    
    func_x(-1, abs)  #abs返回数字的绝对值
    

5.1、map / reduce

  • map()函数:接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。(可以用for循环访问的都是可迭代对象)

    • 例子:

      fx = lambda x:x**2
      
      #方法01
      ls = [1,2,3,4,5,6,7,8,9]
      ms = []
      for l in ls:
          ms.append(fx(l))
      print(ms)
      
      #方法02
      rst = map(fx, ls)  #左边接受函数,右边接受Iterable
      list(rst)
      #两个方法的结果均为:[1, 4, 9, 16, 25, 36, 49, 64, 81]
      
  • reduce: 用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,依此类推,最后得到一个结果。

    • 例子:

      from functools import reduce
      # 从python3开始,reduce函数移动到了functools这个包,每次使用前要先import
      mul_xy = lambda x, y: x*y
      a = reduce(mul_xy, [1, 3, 5, 7, 9])
      print(a)
      
    • 图示

5.2、sorted:返回的是排序的结果

  • 排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。

  • 例子

    sorted([36, 5, -12, 9, -21])   #升序
    sorted([36, 5, -12, 9, -21], reverse=True)   #降序
    sorted([36, 5, -12, 9, -21], key=abs)   # 按绝对值排序key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序  [5, 9, -12, -21, 36]
    
    points = [(5,2), (7,3), (3,4),(1,1),(2,6)] 
    # 按x坐标排序   [(1, 1), (2, 6), (3, 4), (5, 2), (7, 3)]
    f_x = lambda x:x[0]  
    sorted(points, key=f_x)
    # 按y坐标排序   [(1, 1), (5, 2), (7, 3), (3, 4), (2, 6)]
    f_y = lambda x:x[1]
    sorted(points, key=f_y)
    # 按到0点距离排序  [(1, 1), (3, 4), (5, 2), (2, 6), (7, 3)]
    f_r = lambda x:x[0]**2+x[1]**2
    sorted(points, key=f_r)
    

六、装饰器

6.1、函数作为返回值

  • 例子

    def lazy_sum(*args):
        def sum():
            ax = 0
            for n in args:
                ax = ax + n
            return ax
        return sum
    f = lazy_sum(1, 3, 5, 7, 9)   # 这里的f不进行计算,但可以看到参数
    f()   #返回的函数不会立即执行,只有调用的时候才会进行计算
    

6.2、闭包

  • 定义:python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).

  • 返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

  • 例子:

    def create_pointer(my_string):
        def pointer(n):
            return my_string[n]
        return pointer
    
    pointer = create_pointer('my name is Molly')
    pointer(5)   #这里才会执行
    

6.3、装饰器

  • 顾名思义,从字面意思就可以理解,它是用来"装饰"Python的工具,使得代码更具有Python简洁的风格。换句话说,它是一种函数的函数,因为装饰器传入的参数就是一个函数,然后通过实现各种功能来对这个函数的功能进行增强。

  • 例子:

    # 装饰器输入一个函数,输出一个函数
    def print_working(func):
        def wrapper():
            print(f'{func.__name__} is working...')
            func()
        return wrapper
    
    #调用方法1
    def worker1():
        print('我是一个勤劳的工作者!')
    worker1 = print_working(worker1)
    worker1()
    
    #调用方法2
    @print_working
    def worker1():
        print('我是一个勤劳的工作者!')
    worker1()
    
  • 带参数的装饰器

    def arg_decorator(func):
        def wrapper(*args, **kw):
            print(f'{func.__name__} is working...')
            func(*args, **kw)
        return wrapper
    
    @arg_decorator
    def student_info(name, age=18, *books, **kw):
        print(f'我的名字叫{name}, 今年{age}岁,我有很多本书:')
        for book in books:
            print(book)
        print(kw)
    
  • 装饰器的使用场景

    • 计算函数运行时间
    • 给函数打日志
    • 类型检查

6.4、偏函数

  • 通过设定参数的默认值,降低函数调用的难度

  • 例子

    from functools import partial
    def student_info(name, age, city):
        print(f'我的名字叫{name}, 今年{age}岁,来自{city}')
    
    student_info_beijing = partial(student_info, city='北京')   #吧city的默认值修改为‘北京’
    student_info('Molly',18)
    

七、模块

  • from functools import partial as pr   #从functools中引入partial并重命名为pr
    

7.1、安装 / 卸载第三方模块

你可能感兴趣的:(python速成营,python)