Day-4: Python函数

  每一个具体问题都有具体的实现方法,而对于同一类问题,不同的具体方法可以抽象成这一类的方法,当给定一个特定的输入时,这一类方法会变成适用于一具体问题的具体方法。

  这就是函数想要做的事,将一类方法简化抽象,使得每次都可以通过该函数实现想要实现的功能。

  python内置很多函数,例如:

  abs(),求绝对值的函数;

  cmp(x, y),比较x, y之间大小的函数等等

  还可以自己定义自己想要的函数:

  如下:

def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x

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

  函数什么都不做,就是空函数,如下:

def nop():
    pass

  实际上空函数中,pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。

  在设计函数的参数时,应注意必选参数在前,默认参数在后。默认参数可以简化函数的调用:

def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

  定义一个默认幂数是2的求幂函数后,只输入一个参数时,就默认幂数为2,输入两个参数,则第二个参数为新的幂数:

>>> power(5)
25
>>> power(5, 2)
25

  但是注意这里默认参数得是不可变的,而不能是一个变量,不然重复调用时会出现错误。

def add_end(L=[]):
    L.append('END')
    return L

  第一次使用默认参数调用时,结果还是对的

>>> add_end()
['END']

  但是多次调用就明显出错了

>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']

  这是因为原函数中的默认参数时[],它实质上是一个list的变量,会随着每次使用而改变。这里表示空的list常量,应该用“L=None”

  如果函数的输入的个数不确定,则使用可变参数*args;如果传入的参数是一个dict类型,则应使用关键字参数**kw

  前者是将多个参数封装成tuple,后者是将这些封装成一个dict。所以前者得传入一个个单个的量,后者得传入key-value键值对。

  当要一起用到必选参数、默认参数、可变参数、关键字参数时,应注意参数定义的顺序是:

  必选参数、默认参数、可变参数、关键字参数。

  递归函数中每次进入一个函数调用会增加一层栈帧,每当函数返回时,栈就会减少一层,这样递归函数就可能会出现栈溢出。

  解决递归调用栈溢出的方法是通过尾递归优化。尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

  遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化==

 注:本文为学习廖雪峰Python入门整理后的笔记

posted @ 2017-09-08 19:25  倔强的小蚂蚁  阅读(111)  评论(0编辑  收藏  举报