本章的内容将会介绍如何将语句组织成函数,到目前为止所有接触到的程序还都很小,但是当我们接触到大型程序时,就会遇到不小的麻烦,为此呢需要我们学会构建和使用自己的函数,从而做到事半功倍~
6.1 创建函数
函数可以被调用,执行某种操作并且返回一个值,一般而言内建函数callable函数可以用来判断函数是否可以被调用:
>>> import math
>>> x=1
>>> y=math.sqrt
>>> callable(x)
False
>>> callable(y)
True
python中的保留字def用于定义函数,传递参数啊,返回一个值,看个简单例子::
def hello(name):
return ('Hello,'+name+'!')
print(hello('QTY'))
运行结果:
Hello,QTY!
6.2.1 记录函数
如果想要给函数写文档让后面使用该函数能理解的话,可以给函数加上注释,另外一个方式就是直接加上字符串,如果在函数的开头写下字符串,他就会作为函数的一部分进行存储,这玩意成为文档字符串。做个简单演示:
def square(x):
'Calculates the square of the given x.'
return x*x
a=int(input('Give a number:'))
print(square(a))
>>> square.__doc__
'Calculates the square of the given x.'
字符串的访问方式通过上面的方式进行,这个_doc_是函数的属性,关于这方面的知识会在下一章节进行介绍。
6.2 参数魔法
函数使用起来很简单,创建函数也并不复杂,但是关于函数参数的用法有时候就有些不可思议了还是先从最基础的进行介绍。
6.2.1 值从哪里来
函数被定义之后,所操作的值是从哪里来的呢?一般来说我们并不需要担心这个问题,函数只是给程序需要的部分提供服务,只要能保证参数正确正常工作就可以,参数错的话就会导致失败,
6.2.2 我能改变参数吗
在这里要介绍到全局变量和局部变量的概念,在函数内部为参数赋予新的值并不会改变外部的任何变量,因为这个变量只在函数的内部起作用。字符串、数字和元组都是不可变的,不可以被修改(必须用新的值进行覆盖)所以如果使用这些当成参数就没什么好说的了,但是考虑一下如果是用可变的数据结构比如列表作为参数:
>>> def change(n):
... n[0]='QTY'
>>> names=['James','Durant']
>>> change(names)
>>> names
['QTY', 'Durant']
至于为什么要改变参数,答案非常显而易见,如果你在编写一些比较繁琐需要大量重复的程序时,你就会知道这样做的好处了,比如:举个栗子来说,我现在想编写一个程序,建立一个数据库把一个人的名字分字存储起来(齐天宇:first=齐,middle=天,last=宇),你一个个手输,确实可以,但是非常sb,用参数方法还是比较快的:
def init(data):
data['first']={}
data['middle']={}
data['last']={}
storage={}
init(storage)
print(storage) #这里 函数包办了初始化
#编写存储名字的函数前,再编写一个获得名字的函数
def lookup(data,label,name):
return data[label].get(name) #标签及名字可以作为参数提供给函数使用
storage这个数据结构的存储方式是带有三个键的字典,每个键下面都又存储一个字典,子字典中我们可以使用名字等作为键,插入联系人列表作为值,比如我想要插入一个联系人:
me='Qi Tian Yu'
storage['first']['Qi']=[me]
storage['middle']['Tian']=[me]
storage['last']['Yu']=[me]
>>> storage['middle']['Tian']
['Qi Tian Yu']
这样好像还是很麻烦的样子,那我们再写一个名字写入程序。
def store(data,full_name):
names=full_name.split()
if len(names)==2:names.insert(1,'')
labels='first','middle','last'
for label,name in zip(labels,names):
people=lookup(data,label,name)
if people:
people.append(full_name)
else:
data[label][name]=[full_name]
这个函数对于初学者确实不太友好,那么我来解释一下store函数执行的步骤:
①使用参数data和full_name进入函数,这两个参数被设置为函数在外部获得的一些值。
②通过拆分full_name得到了一个叫做names的列表
③如果names的长度为2(名字只有俩字)那么就插入一个空白字符作为中间名
④将字符串‘first’,‘middle’,‘last’作为元组存储在labels中(也可以使用列表,这里只是为了方便所以去掉了括号[])
⑤使用zip函数联合标签和名字,对于每一个(label,name)对,进行以下的处理:
■ 获得属于给定标签和名字的列表
■ 将full_name添加到列表中,或者插入一个新的列表:
>>> Mynames={}
>>> init(Mynames)
>>> store(Mynames,'Qi Tian Yu')
>>> lookup(Mynames,'middle','Tian')
['Qi Tian Yu']
好像可以工作,再试试:
>>> store(Mynames,'Sun Shu Xia')
>>> store(Mynames,'Sun Xiao Xia')
>>> lookup(Mynames,'first','Sun')
['Sun Shu Xia', 'Sun Xiao Xia']