python函数(三)

313 阅读4分钟

一、函数定义

定义:def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。

例如:

def my_abs(x):

    ifx >=0:

        return x 

    else:return-x

二、函数参数

函数参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数

必选参数,

默认参数,是必选参数在前,默认参数在后。当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数默认参数必须指向不变对象!

可变参数,传入的参数个数是可变的,由于参数个数不确定,所以把参数当作list或tuple传递进来。

例:def calc(numbers):

            sum =0

            for n in numbers: 

                 sum = sum + n * n

            return sum

关键字参数,允许传入0个或任意个含参数名的参数,在函数内部自动组装为一个dict。例如:

def person(name, age, **kw):

    print 'name:', name,'age:', age,'other:', kw

三、递归函数

在函数内部,可以调用其它函数。递归函数的优点是定义简单,逻辑清晰。使用递归函数需要注意防止栈溢出

尾递归是指,在函数返回的时候,调用自身本身。

例如:def fact(n):

               ifn==1:

                    return1

           returnn * fact(n -1)

在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。通过尾递归可以解决栈溢出。

上面的函数用尾递归的写法:

def fact(n):

    return fact_iter(n,1)

def fact_iter(num, product):

    if num ==1:

        return  product 

    return fact_iter(num -1, num * product)

Python解释器没有对尾递归做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出

四、高阶函数

变量可以指向函数,比如python的内置函数可以赋值给一个变量,f=abs  f(-10)可以得到10;

函数名也是变量名;把abs指向10后,就无法通过abs(-10)调用该函数了!因为abs这个变量已经不指向求绝对值函数了,而是指向了固定值10。abs函数实际上是定义在__builtin__模块中的,所以要让修改abs变量的指向在其它模块也生效,要用__builtin__.abs = 10。

传入函数,一个函数可以接受另一个函数作为参数,这种函数称之为高阶函数。例如:

defadd(x, y, f):

    returnf(x) + f(y)

map(f,[]);传入两个参数,第一个是函数,第二个是要进行计算的list,结果返回一个list。

filter();接收一个函数和一个序列,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

sorted();可以对list内部元素的大小进行排序。通常规定,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1。对字符串排序是按照ASCII的大小比较的。

返回函数;把函数作为结果值返回。例如:

def lazy_sum(*args):

  def sum():

    ax =0

    for n in args:

            ax = ax + n

     return ax 

  return sum

说明:调用lazy_sum()时返回求和函数sum(),内部函数sum还可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种程序结构称为“闭包”。注意:lazy_sum中每次调用都会返回一个新的函数,即使传入的参数相同。

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