1.2.声明函数
Python像其它编程语言一样也有函数,但是却没有像C++那样的头文件或者像Pascal那样的interface/implementation部分.当你需要一个函数时,只要像下面一样声明就可以了:
def approximate_size(size, a_kilobyte_is_1024_bytes=True):
函数的开始是关键字def,紧跟着是函数名,然后是括号中的参数.参数之间用逗号分隔.
另外需要注意的是函数没有返回类型.Python函数不指定特定的返回类型,甚至不需要指定是否返回一个值.(实际上,每一个python函数都会返回一个值.如果执行了return语句,那么它会返回这个值,否则,它返回一个None.None是Python的null值.)
注:在某些编程语言中,函数(那些有返回值的)以function开头,而子程序(那些没有返回值的)以sub开头.在Python中没有子程序的概念.每个都是函数,每个函数都有返回值(即使它是None),每个函数都以def开头.
函数approximate_size()有两个返回值--size和a_kilobyte_is_1024_bytes,但是每个都没有指定类型.在Python中,变量从不需要指定类型.Python会自己辨识类型并对其进行跟踪.
注:在java和其它强类型编程语言,你必须指定函数返回值和参数的类型.在Python中你不需要为任何东西指定数据类型.根据赋值时的值类型,python会自动跟踪值的类型.
1.2.1.可选参数和定名参数(Optional and named arguments)
Python允许函数参数有默认值.如果函数在调用时没有给该参数赋值,则该参数会被赋成默认值.更进一步,通过定名参数,可以以任意顺序来给参数赋值.
让我们再重新审视一下approximate_size()的函数声明.
def approximate_size(size, a_kilobyte_is_1024_bytes=True):
第二个参数a_kilobyte_is_1024_bytes的默认值为True.这意味着该参数是可选的:你可以不给该参数赋值而调用函数,Python会为其赋值为True.
现在让我们来看下底部的脚本:
if __name__ == '__main__':
print(approximate_size(1000000000000, False)) ①
print(approximate_size(1000000000000)) ②
1.这次函数调用有两个参数.在函数approximate_size中,a_kilobyte_is_1024_bytes会被赋值为False,因为你已经明确这样做了.
2.这次函数调用只有一个参数.但是这样没有问题,因为第二个参数是可选的.既然函数调用时没有特别指定,第二个参数会被赋值为默认值True,就像函数声明中所说的那样.
你甚至可以通过参数名称将值传到函数中.
>>> from humansize import approximate_size
>>> approximate_size(4000, a_kilobyte_is_1024_bytes=False) ①
'4.0 KB'
>>> approximate_size(size=4000, a_kilobyte_is_1024_bytes=False) ②
'4.0 KB'
>>> approximate_size(a_kilobyte_is_1024_bytes=False, size=4000) ③
'4.0 KB'
>>> approximate_size(a_kilobyte_is_1024_bytes=False, 4000) ④
File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg
>>> approximate_size(size=4000, False) ⑤
File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg
1.这次调用将4000赋给第一个参数size,将False赋给一个名叫a_kilobyte_is_1024_bytes的参数.(这正好是第二个参数,不过没有关系,我们呆会儿将会再次看到这种用法.)
2.这次调用将4000赋给名叫size的参数,将False赋给名叫a_kilobyte_is_1024_bytes的参数.(这次定名参数的顺序正好与函数声明的参数顺序相同,不过仍然没有关系)
3.这次调用将False赋值给a_kilobyte_is_1024_bytes,将4000赋值给size.(看,我告诉过你参数顺序没有关系吧)
4.这次调用失败了,因为你在定名参数后面跟了一个非定名参数,这永远不可行.参数列表从左到右,如果你碰到了一个定名参数,那么它后面的参数必须都是定名参数.
5.这次调用也失败了,原因因上次一样.不管怎么说,你将4000赋给了一个名叫size的参数,所以"理所当然地"False会赋值给a_kilobyte_is_1024_bytes.但是这种方式在Python下可行不通.只要你碰到一个定名参数,它后面的所有参数都必须是定名参数.