写在之前
函数是很有深度的,需要我们深入探究,实践过程中,有很多对函数的不同理解,需要我们在学习的过程中不断的思考,下面我们在昨天文章(
零基础学习 Python 之与函数的初次相见
)的基础上,再学习一些函数的相关应用。
返回值
所谓的返回值,就是在调用函数的地方由函数返回的数据。下面我们用我们最熟悉的斐波那契数列为例,我们编写一个函数来实现斐波那契数列:
>>>deffibs(n):
...res = [,1]
...foriinrange(n-2):
...res.append(res[-2] + res[-1])
...returnres
...
>>>if__name__ =="__main__":
...now = fibs(10)
...print(now)
...
在上面的代码中我们首先定义了一个函数,名字叫做 fibs,参数是输入一个整数(其实你输入非整数也是可以的,只是结果不同),然后通过 now = fibs(10) 调用这个函数。这里的参数给的是 10,这就以为着要得到的是 n = 10 的斐波那契数列。运行以后的结果如下 :
[,1,1,2,3,5,8,13,21,34]
当然如果你想换 n 的值,只需要在调用的时候修改一下参数就好了。然后我们来观察上面的函数,最后有一个语句 return res,意思是将 res 的值返回,但是返回给谁呢?这要看是在什么位置调用的函数。在上面的代码中,用 now = fibs(10) 调用了函数,那么函数就将值返回到当前状态,并记录在内存中,然后把它赋值给变量 now。
需要注意的,上面虽然返回的是列表,但其实只是返回了一个返回值,有时候我们需要返回多个的时候,要用元组的方式。
>>>defmy_digit():
...return1,2,3
...
>>>now = my_digit()
>>>now
(1,2,3)
对于上面的这个函数,其实我们还可以像下面一样:
>>> x,y,z = my_digit()
>>> x
1
>>> y
2
>>> z
3
并不是所以的函数都有 return,比如某些函数就只是执行一条语句或者干脆什么也不做,它们不需要返回值,其实看过昨天文章的朋友可能会有印象,其实它们也有,只不过是 None。比如下面的函数:
>>>defcau():
...pass
...
>>>now = cau()
>>>print(now)
None
这个函数的作用就是什么也不做,当然也就不需要 return。
我们可以特别注意一下那个 return,它其实还有一个作用,请看下面的例子:
>>>defmy_info():
...print('my name is rocky')
...return
...print('i like python')
...
>>>my_info()
my nameisrocky
看出什么了吗?明明有两个 print,在中间插入一个 return 以后,只执行了第一个 print,第二个并没有执行。这是因为在第一个之后遇到 return,它告诉函数要终端函数体内的流程,所以 return 在这里的作用就是:结束正在执行的流程,并离开函数体返回到调用的位置。
函数的文档
函数的文档,一般是写在函数的名字下面,说明这个函数的用途,因为这个我感觉很重要,之前虽然也说过注释的重要性,但还是感觉有必要再次说明。
deffibs(n):
"""
这是一个求斐波那契数列的函数
"""
在函数的下面,用三对引号的方式包裹着这个函数文档,也叫函数的说明。
比如我们用 dir 来查看函数对象,比如 dir(type),我们会看到 __doc__,这个就是文档:
>>> dir(type)
['__abstractmethods__','__base__','__bases__','__basicsize__','__call__','__class__','__delattr__','__dict__','__dictoffset__','__dir__','__doc__','__eq__','__flags__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__init_subclass__','__instancecheck__','__itemsize__','__le__','__lt__','__module__','__mro__','__name__','__ne__','__new__','__prepare__','__qualname__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasscheck__','__subclasses__','__subclasshook__','__text_signature__','__weakrefoffset__','mro']
>>> type.__doc__
"type(object_or_name, bases, dict)\ntype(object) -> the object's type\ntype(name, bases, dict) -> a new type"
如果上面的例子在交互模式下的话,用 help(fibs),得到的也是三对引号所包裹的文档信息,感兴趣的可以尝试一下。
函数的属性
任何对象都具有属性,我们前面的文章说过函数是对象,那么函数也有属性。
>>>defcau():
..."""this is a cau function"""
...pass
...
对于上面的函数,最熟悉的属性应该就是上面提到的函数文档 __doc__,它可以用英文句号的方式表示为 cau.__doc__:
>>> cau.__doc__
'this is a cau function'
这就能体现出这种方式表示函数属性的优势,只要对象不同,不管你属性的名字是否相同,用英文句号都可以说明属性所对应的对象。
我们还可以给对象增加属性,比如我们给 cau 增加一个 pig 属性,并设置为 100,顺便我们再调用一下它:
>>> cau.pig = 100
>>> cau.pig
100
还记得上面我说的那个查看对象属性和方法的 dir 吗?现在有请它闪亮登场:
>>> dir(cau)
['__annotations__','__call__','__class__','__closure__','__code__','__defaults__','__delattr__','__dict__','__dir__','__doc__','__eq__','__format__','__ge__','__get__','__getattribute__','__globals__','__gt__','__hash__','__init__','__init_subclass__','__kwdefaults__','__le__','__lt__','__module__','__name__','__ne__','__new__','__qualname__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','pig']
在这里列出了所有 cau 这个函数对象的属性和方法,仔细观察我们会发现,我们刚用过的 __doc__ 和我们新增加的 pig 都在其中,至于你在纠结那些名字前后都是用双下划线的,你暂且可以把它们称之为特殊属性,所有的这些属性都是可以用英文句点的方式调用,感兴趣的可以试一试。
写在之后
本来在这里想把参数和变量一起说了,但是基于现在的篇幅长度和参数变量那涉及的东西,一起写的话显得太长了。其实在我的认知里,从公众号上学知识其实不是最好的方式,因为代码什么的看起来不舒服,所以文章的内容在你有限的耐心时间段里看能达到相比来所比较好的效果。
最近比较忙,我现在还在坚持着每天更新,我尽量挤出时间来写文章,可能不能做的那么尽善尽美,希望朋友们能理解。
最后感谢你能看到这里,希望我写的东西能够让你有到收获,每天收获一点点,持之以恒,水能穿石。
The end。
看我这么卖力还不专注一波
领取专属 10元无门槛券
私享最新 技术干货