Python 函数

来源:互联网 发布:小米下载不了软件 编辑:程序博客网 时间:2024/06/06 18:56

一、创建和调用函数

  1. 创建函数

    • 定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后在缩进块中编写函数体,函数的返回值用return语句返回。
    • Python 函数可以有多个参数,且函数的参数必须为变量(不用指定变量的数据类型),不同的参数用逗号隔开。
    • 当 Python 执行到return语句时,Python 认为函数到此结束,需要返回了,当未设置返回值时,返回的是None
    • 函数可以同时返回多个不同类型值,默认以逗号隔开,则是一个tuple的形式返回,也可以用列表包含起来,返回一个列表。
  2. 调用函数

    • 要调用一个函数,需要知道函数的名称和参数
    • 函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”。
  3. 空函数

    • def nop(): pass
    • pass语句什么都不做,那有什么用?实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。
  4. 函数提出的目的:代码重用,实现特定功能。

    • 代码块重复,这时候必须考虑到函数,降低程序的冗余度
    • 代码块复杂,这时候必须考虑到函数,降低程序的复杂度

二、函数的参数

  1. 形参与实参(又叫位置参数,调用函数时,传入的实参值按照位置顺序依次赋给形参)
    • 形参(parameters):是指函数创建和定义过程中小括号里的参数。
    • 实参(arguments):是指函数在调用过程中传递进去的参数。
  2. 关键字参数
    • 函数在调用的时候,带上形参的名字去指定具体调用的是哪个参数,从而可以不用按照参数的顺序调用函数。
    • eg: hi(words='Hello', name='Tom') 使用关键字参数,可以有效的避免搞乱参数顺序导致BUG的出现。
  3. 默认参数
    • 形参定义的过程中为其赋初值
    • 当函数调用的时候,默认使用形参的初始值代替需要传入的实参值,此时括号中无需再指定实参数值,若指定实参数值,则指定的实参数值会替代初始形参值。
    • 使用默认参数最大的好处是能降低调用函数的难度
    • 默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
  4. 可变参数(又叫收集参数)
    • 可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。
    • *args是可变参数,args接收的是一个tuple
    • 可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3)
  5. 可变参数(收集参数)和关键字参数的区别
    • 可变参数(*args)允许传入任意个参数,这些可变参数在函数调用的时候自动组装成一个tuple;关键字参数(**kw)允许传入任意个含参数名的参数(eg: name = 'Tom'),这些关键字参数在函数调用的时候自动组装成一个dict
    • 可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple eg: args = [1, 2, 3],再通过*args传入:func(*args);关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict eg: kw = ['a':1, 'b':2],再通过**kw传入:func(**kw)

三、局部变量和全局变量

  • 局部变量:只有在特定过程或函数中可以访问的变量(作用域是定义该变量的子程序)
  • 全局变量:作用域是整个程序(在面向对象语言中,一般只使用局部变量)
  • 当局部变量和全局变量重名时:在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。

四、global 关键字、内嵌函数和闭包

  1. global 关键字
    • 在函数内部仅仅去访问全局变量就好,不要试图去修改它,因为那样只会影响到局部变量,而不会影响到全局变量。
    • 若要在函数内部修改全局变量,可使用global关键字定义变量,使其在全局生效。
  2. 内嵌函数: 在函数内部创建另一个函数
  3. 闭包 :如果在一个内部函数里,对在外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被认为是闭包。

五、lambda 表达式、filter()、map()、reduce()—Python 高阶函数

  1. lambda 表达式
    • 使用 lambda 关键字来创建匿名函数可以省下函数定义过程。
    • 当程序代码很短,且该函数只使用一次,为了程序的简洁,及节省变量内存占用空间,引入了匿名函数这个概念。
    • 没有函数名,函数执行的结果就是返回值。
    • 格式:dy = lambda 参数1,参数2,... : 返回值(可以加入条件语句)
    • 调用:dy(参数1, 参数2, ...)
    • eg:dy = lambda x : x if x%2 else None # dy 为一个函数对象
  2. filter(function or None, iterable)
    • 返回一个filter(过滤器) 对象,可以用list将其中元素转化为列表。
    • filter有两个参数,第一个参数可以是一个函数名(即,函数对象)或者None,如果是一个函数的话,则将第二个参数中的可迭代序列里的每一个元素作为函数的实参进行计算,把返回值为True的项筛选出来;如果第一个参数为None,则直接将第二个参数中的可迭代序列里的每一个为True的值筛选出来。
  3. map(func, *iterables)
    • 返回一个map(映射)对象,可以用list将其中元素转化为列表。
    • map有两个参数,第一个参数可以是一个函数名(即,函数对象),将第二个参数中的可迭代序列里的每一个元素作为函数的实参进行计算,返回所有加工完成后的元素构成的新序列
  4. reduce(func(x, y), seq)
    • func必须有两个参数
    • 每次func计算的结果继续和seq的下一个元素做累积计算

      lst = [a1, a2, a3, ..., an]
      reduce(func(x, y), lst) = func(func(func(a1, a2), a3), ... , an)

六、递归函数

  • 在函数内部,可以调用其他函数。如果一个函数在内部调用自身,这个函数就是递归函数
  • 递归必备条件:
    • 函数调用自身
    • 设置了正确的退出条件
  • 在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出
  • 使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出(Python3 处于保护,默认最深100层),而且每次函数的调用都需要压栈、弹栈、保存和恢复寄存器的栈的操作,所以在这个上边是非常消耗时间和空间的。
  • 典型应用:阶乘、斐波那契数列、汉诺塔

七、常见内置函数

这里写图片描述

0 0
原创粉丝点击