函数定义举例:
def my_square(x):
return x*x
函数调用时位置参数(positional)必须提供值,并且必须通过位置来表示值的含义。关键字参数(keyword)在调用时对参数的个数和位置没有固定要求,在调用时没有提供的参数值使用默认值。
使用/表示位置参数的结束,用*表示名字参数的开始,这中间的是带默认值的参数。但是很多时候并没有明确标识边界。
举例:
def hello(greeting='hello', name='jack'):
print(greeting,name)
def hello2(greeting, name='jack'):
print(greeting,name)
hello()
hello(name='Wood')
hello(name='Tom',greeting='How are you')
hello2('hi', name='Sam')
输出为:
hello jack
hello Wood
How are you Tom
hi Sam
函数定义时*args(var-positional)表示支持任意数量的位置参数,放在位置参数的最后,这些参数组成一个元组传入函数。
函数定义时**kwargs(var-keyword)表示支持任意数量的关键字参数,放在关键字参数的最后,这些参数组成一个字典传入函数。
unpack参数列表:
如果要将列表的成员作为一组参数传入function_name(*args),需要function_name (*list_name)。如果直接使用function_name (list_name),列表会被当做元组的一个元素。
如果要将字典作为参数传入function_name (**kwargs),需要function_name (**dict_name)。如果直接使用function_name (list_name),整个字典会被当做一个位置参数,但是函数没有位置参数,所以会抛出异常。
例如:
def f2(**d1):
print(d1)
f2(a=1,b=2) #打印为{'a': 1, 'b': 2}
局部函数:如果只在一个函数中需要重复使用多段代码,可以在这个函数中定义一个局部函数。定义和调用方式和普通函数相同。差异就在于定义位于调用它的函数内部,也只有这个函数能调用它。
Documentation Strings:
函数定义开始前的注释是docstrings。第一行简单描述对象的目的。这一行以大写字母开始,以句号结尾。第二行是空行。第三行开始是具体的对象调用说明、副作用等。对函数参数和返回值进行说明。第三行决定了整个documentation string的缩进方式。不使用第一行是因为其前有三个引号,所以它的缩进方式不够明显。Documentation Strings工具会剥除缩进。function_name.__doc__获取该函数的Documentation Strings。
可以使用sphinx通过python代码中的docstring生成web版本的API文档。
Function annotations:
Function annotations用于说明参数和返回值的类型。例如:
def f(ham: str, eggs: str = 'eggs') -> str:
f.__annotations__是一个字典,内容为{'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
lambda函数:
语法为
lambda perameters: expression
expression是表达式,不能是语句,但是可以使用条件表达式来实现简单的分支逻辑。
lambda函数是没有名字的函数。有些地方必须使用函数,对于只使用一次并且逻辑非常简单的函数可以定义为lambda函数。例如:
list2=sorted(list1,key=lambda x: abs(x))
list2=sorted(list1,key=lambda x: abs(x) if x<-10 else x)
使用global声明已定义的全局变量或者新声明一个全局变量。