python中的函数
函数的定义
函数代码块以“def”关键字开头,后接函数标识符名称和圆括号()。
传入参数须放在圆括号之内,不同的参数用逗号隔开。即使一个参数也没有,这对圆括号也必须保留。
函数体必须以冒号起始,
函数的作用范围要按规定统一缩进
。
以“return [表达式]”结束函数,选择性地返回某个特定值给调用方。如果不写return表达式,
系统会自动返回一个默认值None
。
函数名、参数类型及其出现顺序,构成了一个函数的“签名”。在调用函数时,除了函数名必须正确,函数的实参和形参也需要按函数声明中定义的顺序一一匹配。也就是说,“函数签名”必须一致,验明正身,函数才能被正确调用。
其实,还可以定义一个什么都不做的空函数,其中用pass语句代替函数内部的代码块,在if语句等语句中也可以使用,类似于c语言中的“;”
def hello_world():
print('hello world')
pass
helloworld()
函数的返回值
Python的函数可以利用return语句,选择性地返回一个特定值给调用方。如果没有使用return语句,系统会自动返回一个默认值None。是否可以让函数返回多个值?
答案是否定的。
def helloworld():
str1='hello'
str2='world'
return str1,str2
h,w=helloworld()
print(h," ",w)
这样来看,函数是可以返回多个值的,但是如果细究python语法,可以发现返回的str1,str2构成了一个匿名的元组,赋值给了h,w这个元组,因此,这个函数的返回值应当是一个元组而不是所谓返回了多个值,而元组之间的赋值,其实就是按照元素对应(element-wise)位置一一赋值。
类似地,我们可以利用函数返回一个列表、一个字典、一个集合等。而列表、字典、集合等都属于复合数据类型,它们内部都可以包含多个元素。如此一来,同样能达到Python函数返回多个值的目的。
函数文档
Python中的注释方式
:单行注释以#开头,进行多行注释时通常用三个单引号(’’’)将注释部分包裹起来。
在函数的定义中,常利用多行注释给函数写文档,称为函数文档。为什么要给函数写文档呢?函数实现其对应的功能不就大功告成了吗?当然没有这么简单。
给函数添加注释的目的在于,描述如何使用这个函数。下面我们先来感受一下Python官方给出的文档注释范本。比如说,假设我们不知道字符串对象str的使用信息,于是我们需要寻求帮助。对于不熟悉的函数,只要在命令行中使用帮助函数help()即可获取查询对象的帮助信息,如下图操作:
在Python中,一切皆对象,函数也不例外。作为一个对象,函数有一个特殊的属性__doc__(注意:
doc左右两侧均为两个下画线
),通过这个属性同样可以获得函数的描述文档。为了避免出现\n影响阅读,可以使用print函数来输出。
函数的参数传递
关键字参数
相比于位置参数的位置是至关重要的,在关键字参数中,位置无关紧要,但参数(即形参)的名称非常重要。也就是说,有了关键字(参数名称)的标定,即使参数顺序变了,解释器依然能“按图索骥”找到实参和形参的对应关系.
这其中的门道就在于,在传递实参时指定了关键字(即形参的名称),通过这种绑定关系,即使实参顺序有误,解释器也能帮忙纠偏。
可变参数
在Python中,其实也能很方便地使用可变参数。Python中的可变参数的表现形式为,在形参前添加一个星号(*),意为函数传递过来的实参个数不定,可能为0个、1个,也可能为n个(n≥2)。需要注意的是,不管可变参数有多少个,在函数内部,它们都被“收集”起来并统一存放在以形参名为某个特定标识符的元组之中。因此,可变参数也被称为“收集参数”。
除了用单个星号(
)表示可变参数,其实还有另一种标定可变参数的形式,即用两个星号(**)来标定。通过前文的介绍,我们知道,一个星号(
)将多个参数打包为一个元组,而两个星号(**)的作用是什么呢?它的作用就是把可变参数打包成字典模样。
def fun1(*num):
print(num)
def fun2(**x):
print(x)
fun1(1,2,3,4)
fun2(a=1,b=2,c=3)
默认参数
为了避免用户提供的参数少于函数的参数,可在函数定义时提前给某些形参赋予一个默认值。我们可以使用“函数名.
defaults
”的形式来查看某个函数中参数的默认值。
Python函数在刚定义时,默认参数L的值就已经被计算出来了,即空列表[]。但由于列表L是一个可变量(mutable),每次调用该函数时,如果改变了L的内容,则下次调用时,默认参数就会改变,不再是函数刚开始定义时的那个空列表[]了。
在定义默认参数时务必要让这个默认参数是不可变对象(immutable),比如说数值型、元组、字符串、不可变集合(frozenset)、None等。
参数的打包和解包
python函数有两种可变参数的标记方式:利用一个星号(*)构建一个参数元组;利用两个星号(**)构建参数字典。而解包操作,就是将这两种方式反过来,将列表、字典传入函数。
如果实参为一个列表或元组,它不会自动解包,将其内的元素一一分配给不同的形参,需要在前面加上一个*,字典类似,加上**来将其中的元素传入其中。
参数的引用传递和地址传递
Python中所有的函数参数传递,统统都是基于传递对象的引用进行的。这是因为,在Python中,一切皆对象。而传对象,实质上传的是对象的内存地址,而地址即引用。
Python的参数传递方式是整齐划一的,但具体情况还得具体分析。在Python中,对象大致分为两类,即可变对象和不可变对象。可变对象包括字典、列表及集合等。不可变对象包括数值、字符串、不变集合等。
简单来说,传整形、浮点型、字符型并不会影响它们的值,而传字典、列表等会影响其中的内容。