函数function是可向调用者返回某个值的一组语句,他可以接收若干参数并在函数体中使用。

函数定义

函数定义是一条可执行语句。函数定义语句会在当前局部命名空间中,将函数名称与函数对象绑定。此函数对象包含对当前全局命名空间的引用,作为函数被调用时所使用的全局命名空间。 函数定义时函数体不会执行,只有函数调用时函数体才会。 于Python而言,定义一个函数、类,与定义一个实例并无本质区别。在函数、类内定义函数、类,只是新增了一个局部对象。若是将Python执行上下文理解为一个散列表,而Python所有对象都是基于object(PyObject)的类的实例。上下文只是将这些名字与实例关联起来的容器。如类type(PyTypeObject)、函数function(PyFunctionObject)等。

装饰

函数可以被若干个装饰器表达式所包装。当执行函数定义时,在该作用域对装饰器表达式求值,返回一个可调用对象绑定到函数名称。多个装饰器将以嵌套方式求值。

@f1(arg)
@f2
def func(): pass

形同

def func(): pass
func = f1(arg)(f2(func))

但前者,没有原始函数绑定到名称func的中间过程。

默认形参值

形参 = 表达式形式的参数具有默认形参值,表达式求值结果即其默认值。默认形参值会在执行函数定义时,按从左往右顺序求值。 表达式仅在函数定义时求值一次,此值将在之后的函数调用过程中持续使用。若表达式求值结果为一可变对象,则其修改将会影响后续的函数调用过程。 若欲使函数具有默认形参值,又不希望被可变对象性质所影响,则可将之默认值置为None,并进行判断。

def whats_on_the_telly(penguin=None):if penguin is None:penguin = []penguin.append("property of the zoo")return penguin

参数 argument

参数是函数调用时实际传入的值。根据传参方式不同,可将参数分为一下两种:

  • 关键字参数 在函数调用时,前面带有标识符,或具有前缀**的字典里的值。如:
complex(real=3, imag=5)
complex(**{'real': 3, 'imag': 5}) # 参数是 real=3, imag=5
  • 位置参数 关键字参数之外的参数。于参数列表开头,或具有前缀*的可迭代对象里的值。如:
complex(3, 5)
complex(*(3, 5)) # 参数是 3, 5

形参 parameter

形参是函数定义中的命名实体,代表函数可以接受的参数argument。它可以是以下几种形式:

  1. 位置或关键字形参 默认形参类型,可以通过位置,也可以通过关键字传入的参数。如foobar
def func(foo, bar=None): ...
  1. 仅限位置形参 在部分参数列表之后,插入/参数,表示只能通过指定位置传入。如posonly1posonly2
def func(posonly1, posonly2, /, positional_or_keyword): ...
  1. 仅限关键字形参 在部分可变位置形参之前,插入*参数,表示只能通过指定关键字传入。如kw_only1kw_only2
def func(arg, *, kw_only1, kw_only2): ...
  1. 可变位置形参 在其他位置参数之后的参数名称前添加*,表示任意数量位置参数。如args
def func(arg1, arg2, *args): ...
  1. 可变关键字形参 在其他关键字参数之后的参数名称前添加**,表示任意数量关键字形参。如kwargs
def func(*args, **kwargs): ...