使用关键字def定义函数

In [19]: def fib(n):
   ....:     a, b = 0, 1
   ....:     while a < n:
   ....:         print a,
   ....:         a, b = b, a+b
   ....:         
In [20]: fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

    

    函数可以直接传递给变量,相当于重新命名函数名:

In [21]: fib
Out[21]: <function __main__.fib>
In [22]: f = fib
In [23]: f(100)
0 1 1 2 3 5 8 13 21 34 55 89

    

    函数一般都有返回值,如果没有返回值,那么默认返回值是none

In [24]: def fib2(n):
   ....:     result = []
   ....:     a,b=0,1
   ....:     while a<n:
   ....:         result.append(a)
   ....:         a,b=b,a+b
   ....:     return result
   ....: 
In [25]: fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
In [26]: fib2(100)
Out[26]: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]


    

        三种定义函数的参数值

    1、给变量设置默认的参数值

In [1]: def ask_ok(prompt, retries=4, complaint='Yes or no, ple
   ...:     while True:
   ...:         ok=raw_input(prompt)
   ...:         if ok in ('y','ye','yes'):
   ...:             return True
   ...:         if ok in ('n','no','nop','nope'):
   ...:             return False
   ...:         retries = retries - 1
   ...:         if retries < 0:
   ...:             raise IOError('refusenik user')
   ...:         print complaint

        

    调用该函数有三种方式:

     (1)只给第一个必要的变量赋值:

In [2]: ask_ok('Do you really want to quit?')

      (2)除了第一个必要参数值,第二个可选参数值也赋值,相当于覆盖了原来的默认值

 In [5]: ask_ok('OK to overwrite the file?',2)

    (3)给所有参数都赋值

In [6]: ask_ok('OK to overwrite the file?',2,'Come on,only yes or not')

    

        注意一般来说,参数值的默认值只会赋值一次,比如以下这个方式:

In [7]: i=5
In [8]: def f(arg=i):
   ...:     print arg
   ...:     
In [9]: i=6
In [10]: f()
5

        

        但是如果参数的默认赋值是可变的列表,字典或者实例,那就会有些不同的地方,以下例子说明这个问题:

        

In [11]: def f(a,L=[]):
   ....:     L.append(a)
   ....:     return L
   ....: 
In [12]: print f(1)
[1]
In [13]: print f(2)
[1, 2]
In [14]: print f(3)
[1, 2, 3]

    

         如果不希望列表或者字典在多个函数调用中被累积调用,可以使用以下方式:

In [15]: def f(a,L=None):
   ....:     if L is None:
   ....:         L=[]
   ....:     L.append(a)
   ....:     return L

        

    2、关键词参数


        函数在调用的时候可以使用关键词直接赋值,通过以下函数例子说明:

In [16]: def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
   ....:     print "-- This parrot wouldn't", action,
   ....:     print "if you put", voltage, "volts through it."
   ....:     print "-- Lovely plumage, the", type
   ....:     print "-- It's", state, "!"

    parrot这个函数接受一个必要参数值(voltage)和三个可选参数值,函数可以通过以下几种方式调用:


parrot(1000)                            # 1 positional argument
parrot(voltage=1000)                    # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM')        # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000)        # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump')    # 3 positional arguments
parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

    

    以下几种方式不能用于调用函数:

parrot()                     # required argument missing
parrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argument
parrot(110, voltage=220)     # duplicate value for the same argument
parrot(actor='John Cleese')  # unknown keyword argument

    

    可以使用形参(formal parameter)来定义函数,*name接受一个元组,**name接受一个字典,*name形参必须在**name之前如以下例子:

        

In [10]: def cheeseshop(kind, *arguments, **keywords):
   ....:     print "-- Do you have any", kind, "?"
   ....:     print "-- I'm sorry, we're all out of", kind
   ....:     for arg in arguments:
   ....:         print arg
   ....:     print "-" * 40
   ....:     keys = sorted(keywords.keys())
   ....:     for kw in keys:
   ....:         print kw, ":", keywords[kw]

    

In [11]: cheeseshop("Limburger", "It's very runny, sir.",
   ....:            "It's really very, VERY runny, sir.",
   ....:            shopkeeper='Michael Palin',
   ....:            client="John Cleese",
   ....:            sketch="Cheese Shop Sketch")
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch


    

3、可变参数列表(Arbitaty Argument List)


In [12]: def write_multiple_items(file, separator, *args):
   ....:     file.write(separator.join(args))

    

4、分拆参数列表(Unpacking Argument List)


    当传递给函数调用的参数是列表或元组,那就需要分开位置变量,例如,系统内置的range()函数期望接收的是开始和结束的变量值,如果传递给它的是没有分开的参数,那么调用该函数时可以在参数前加“*”运算符来分拆列表或元组参数。

In [1]: range(3, 6)  正常调用
Out[1]: [3, 4, 5]
In [2]: args = [3, 6]    列表
In [3]: range(*args)
Out[3]: [3, 4, 5]

    

    同样的方式,字典也可以使用"**"运算符来传递关键词参数:

In [4]: def parrot(voltage, state='a stiff', action='voom'):
   ...:     print "-- This parrot wouldn't", action,
   ...:     print "if you put", voltage, "volts through it.",
   ...:     print "E's", state, "!"
   ...:     
In [5]: d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
In [6]: parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

    

5、Lamba表达式

        使用lamba关键词可以构造较小的匿名函数

In [7]: def make_incrementor(n):
   ...:     return lambda x: x + n
   ...: 
In [8]:  f = make_incrementor(42)
In [9]: f(0)
Out[9]: 42
In [10]: f(1)
Out[10]: 43

    构造一个函数作为参数传递给其他函数调用:

In [14]: pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
In [15]:  pairs.sort(key=lambda pair: pair[1])
In [16]: pairs
Out[16]: [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]


6、文档字符串(Documnet strings)

In [17]: def my_function():
   ....:     """Do nothing, but document it.
   ....:     No, really, it doesn't do anything.
   ....:     """
   ....:     pass
   ....: 
In [18]: print my_function.__doc__
Do nothing, but document it.
    No, really, it doesn't do anything.


7、编程风格PEP8


    推荐 PEP 8,PEP8的主要要点:


    (1)使用四个空格的缩进,不要使用tab;

    (2)将行包裹起来,这样使它不要超过79个字符;

    (3)使用空行来分隔函数和类,在函数里面分隔不同块;

    (4)使用文档字符串(Docstring)

    

    (5)使用空格隔开运算符,在逗号后面使用空格,但是不要直接在括弧构造中使用:

     (6)函数和类命名要一致性,使用CamClass这样的格式来命名类,使用

lower_case_with_underscores这样的格式来命名函数和方法,要使用self来表示第一个函数方法的参数


    (7)使用标准编码格式