1 2 3 4 5 6 7 8 | def square(x): return x**2 >>> square <function square at 0x031AA230> >>> dir(square) ['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name'] >>> |
其中,一些重要的函数属性包括以下几个:
1. __doc__返回指定函数的文档字符串。
1 2 3 4 5 6 | def square(x): """return square of given number""" return x**2 >>> square.__doc__ 'return square of given number' |
2. __name__返回函数名字。
1 2 3 4 5 6 | def square(x): """return square of given number""" return x**2 >>> square.func_name 'square' |
3. __module__返回函数定义所在模块的名字。
1 2 3 4 5 6 | def square(x): """return square of given number""" return x**2 >>> square.__module__ '__main__' |
4. func_defaults返回一个包含默认参数值的元组,默认参数将在后文进行讨论。
5. func_globals返回一个包含函数全局变量的字典引用。
1 2 3 4 5 6 | def square(x): """return square of given number""" return x**2 >>> square.func_globals {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'square': <function square at 0x10f099c08>, '__doc__': None, '__package__': None} |
6. func_dict返回支持任意函数属性的命名空间。
1 2 3 4 5 6 | def square(x): """return square of given number""" return x**2 >>> square.func_dict {} |
7. func_closure返回一个胞体元组,其中胞体包含了函数自由变量的绑定,闭包将在后文讨论。
函数可以作为参数传递给其他函数。这些以其他函数作为参数的函数通常称为更高阶函数,这就构成了函数式编程中一个非常重要的部分。高阶函数一个很好的例子就是map函数,该函数接受一个函数和一个迭代器作为参数,并将函数应用于迭代器中的每一项,最后返回一个新的列表。我们将在下面的例子中演示这一点,例子中将前面定义的square函数和一个数字迭代器传递给map函数。
1 2 | >>> map(square, range(10)) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] |
此外,函数也可以在其他函数代码块内部定义,同时也能从其他函数调用中返回。
1 2 3 4 5 | def outer(): outer_var = "outer variable" def inner(): return outer_var return inner |
在上面的例子中,我们在函数outer中定义了另一个函数inner,并且当函数outer执行时将返回inner函数。此外,像任何其他Python对象一样,函数也可以赋值给变量,如下所示:
1 2 3 4 5 6 7 8 9 10 | def outer(): outer_var = "outer variable" def inner(): return outer_var return inner >>> func = outer() >>> func <function inner at 0x031AA270> >>> |
在上面的例子中,outer函数被调用时将会返回一个函数,并将返回的函数赋值给变量func。最后,该变量就可以像被返回的函数一样被调用:
1 2 | >>> func() 'outer variable' |
函数定义
关键字def用于创建用户自定义函数,函数定义就是一些可执行的语句。
1 2 | def square(x): return x**2 |
在上面的square函数中,当包含该函数的模块加载到Python解释器中时,或者如果该函数在Python REPL中定义,那么将会执行函数定义语句def square(x)。然而,这对以可变数据结构作为值的默认参数有一些影响,这一点我们将会在后文讲述。函数定义的执行会绑定当前本地命名空间中的函数名(可以将命名空间当作名字到值的一种映射,并且这种映射还可以嵌套,命名空间和范围会在另一个教程中详细介绍)到一个函数对象,该对象是一个对函数中可执行代码的包装器。这个函数对象包含了一个对当前全局命名空间的引用,而当前命名空间指该函数调用时所使用的全局命名空间。此外,函数定义不会执行函数体,只有在函数被调用时才会执行函数体。
函数调用参数
除了正常的参数之外,Python函数还支持数量可变的参数。这些参数有主要有下面描述的三种类别:
1. 默认参数值:这允许用户为函数的参数定义一些默认值。这种情况下,可以以更少的参数来调用该函数,而函数调用时未提供的参数,Python会使用默认提供的值作为这些参数值。下面的例子展示了这种用法:
1 2 | def show_args(arg, def_arg=1, def_arg2=2): return "arg={}, def_arg={}, def_arg2={}".format(arg, def_arg, def_arg2) |
上面例子函数的定义中,包含一个正常位置的参数arg和两个默认参数def_arg和def_arg2。该函数可以以下面中的任何一种方式进行调用:
(1)只提供非缺省位置参数值。在本例中,缺省参数取默认值:
1 2 3 4 5 | def show_args(arg, def_arg=1, def_arg2=2): return "arg={}, def_arg={}, def_arg2={}".format(arg, def_arg, def_arg2) >>> show_args("tranquility") 'arg=tranquility, def_arg=1, def_arg2=2' |
(2)用提供的值覆盖一些默认的参数值,包括非缺省位置参数:
1 2 3 4 5 | def show_args(arg, def_arg=1, def_arg2=2): return "arg={}, def_arg={}, def_arg2={}".format(arg, def_arg, def_arg2) >>> show_args("tranquility", "to Houston") 'arg=tranquility, def_arg=to Houston, def_arg2=2' |
(3)为所有参数提供值,可以用这些值覆盖默认参数值:
1 2 3 4 5 | def show_args(arg, def_arg=1, def_arg2=2): return "arg={}, def_arg={}, def_arg2={}".format(arg, def_arg, def_arg2) >>> show_args("tranquility", "to Houston", "the eagle has landed") 'arg=tranquility, def_arg=to Houston, def_arg2=the eagle has landed' |
当使用可变的默认数据结构作为默认参数时,需要特别小心。因为函数定义只执行一次,所以这些可变的数据结构(引用值)只在函数定义时创建一次。这就意味着,相同的可变数据结构将用于所有函数调用,如下面例子所示:
1 2 3 4 5 6 7 8 | def show_args_using_mutable_defaults(arg, def_arg=[]): def_arg.append("Hello World") return "arg={}, def_arg={}".format(arg, def_arg) >>> show_args_using_mutable_defaults("test") "arg=test, def_arg=['Hello World']" >>> show_args_using_mutable_defaults("test 2") "arg=test 2, def_arg=['Hello World', 'Hello World']" |
在每个函数调用中,“Hello World”都被添加到了def_arg列表中,在调用两次函数之后,默认参数中将有两个“Hello World”字符串。当使用可变默认参数作为默认值时,注意到这一点非常重要。当我们讨论Python数据模型时,将会清楚理解其原因。
2. 关键字参数:以“kwarg=value”的形式使用关键字参数也可以调用函数。其中,kwarg指函数定义中使用的参数名称。以下面定义的含有默认和非默认参数的函数为例:
1 2 | def show_args(arg, def_arg=1): return "arg={}, def_arg={}".format(arg, def_arg) |
为了演示使用关键字参数调用函数,下面的函数可以以后面的任何一种方式调用: