声明
Python中定义函数很简单,关键字为def
,即define的意思。
def hellowWorld():
print("hellow world!")
hellowWorld()
# hellow world!
Python函数参数传递分两种,一种是其它语言中常见的位置传递,另一种叫做关键字传递。
我觉得叫做指名传递也蛮形象的。
位置传递
def showStr(string):
print(string)
showStr("hellow world!")
# hellow world!
关键字传递
除了按函数定义好的参数一一对应传参以外,还可以在传递参数的时候无视函数定义,直接指明参数名称传递参数:
def showPerson(name, age):
print("name: ", name)
print("age:", age)
showPerson(age=16, name="Jack Lee")
# name: Jack Lee
# age: 16
引用传递or值传递
在其它编程语言中,我们经常会涉及函数传参是引用传递还是值传递的讨论,如果是C++,讨论的会更复杂,比如指针传递和指针的指针传递。
但这在Python中都是一回事,因为之前我们已经说过,Python中所有的数据都是对象。
想重新理解一下的可以阅读
既然传递的参数全部是对象,自然也都是引用传递,不过这就和之前讨论过的一样,对于值不能改变的数据类型,比如int
/string
/tuple
等,其表现出来的效果就相当于值传递:
def doubleTuple(oneTuple):
oneTuple = oneTuple*2
print("after double: ", oneTuple)
oneTuple = ("a", "b", "c")
doubleTuple(oneTuple)
print(oneTuple)
# after double: ('a', 'b', 'c', 'a', 'b', 'c')
# ('a', 'b', 'c')
可以看出在函数体里对参数的改变并不能影响外部数据。
那我们如果传递的不是元组而是列表呢,是不是就能改变?
def doubleList(oneList):
oneList = oneList*2
print("after double: ", oneList)
oneList = ["a", "b", "c"]
doubleList(oneList)
print(oneList)
# after double: ['a', 'b', 'c', 'a', 'b', 'c']
# ['a', 'b', 'c']
依然没有改变,这是怎么回事?
其实如果C++或者Java基础扎实的话不难理解,在doubleList
函数体中,接受到的参数oneList
是一个引用,和外部主程序的oneList
变量指向的是同一个列表对象,如果用这个引用直接操作内部元素,当然可以改变对用的列表对象,外部主函数同名变量也会同样受到影响,因为它们指向的目标相同。但是,oneList=oneList*2
这条语句并非直接操作内部元素,而是用赋值语句重新给函数体内的oneList
变量赋予了一个新的列表对象。它不再指向原来的列表对象,即和外部同名变量不再有任何关系。
这个解释可以用下面的代码来验证:
def changeList(oneList):
oneList.pop()
print("after pop: ", oneList)
oneList = ["a", "b", "c"]
changeList(oneList)
print(oneList)
# after pop: ['a', 'b']
# ['a', 'b']
可以看出,这的确是引用传递。
参数默认值
如同其它编程语言,Python也支持函数默认参数:
def showPerson(name, age=16):
print("name: ", name)
print("age:", age)
showPerson("Jack Lee")
# name: Jack Lee
# age: 16
doc string
凡是刚从强类型检查语言(如C++、Java)转向弱类型检查语言(如PHP、Python),最不能忍受的肯定是在调用函数的时候压根不知道需要传递什么类型的参数,返回值也不知道是什么类型,本来弱类型语言是应该给开发者提供方便的,但在这方面真的会造成很大麻烦,尤其是对返回的对象再处理的时候,IDE识别不了对象类型自然也就不能进行智能联想。
好在也不是完全没有解决办法,比如PHP就有PHP doc
,风格和Java doc
相当类似,不仅增强了代码可读性,还解决了IDE智能联想的问题,基本上PHP代码可读性如何只要看有没有详细的PHP doc
即可。
相对应的,Python也有类似的doc string
:
def showPerson(name, age=16):
"""show a person information"""
print("name: ", name)
print("age:", age)
# showPerson("Jack Lee")
help(showPerson)
# Help on function showPerson in module __main__:
# showPerson(name, age=16)
# show a person information
在函数的第一行可以用3组引号的形式来说明一个函数的用途,并且可以用help()
来查看,这就是doc string
。
但是说好的标记参数类型和返回值呢?
可以这样:
def showPerson(name: str, age: int = 16) -> None:
"""show a person information"""
print("name: ", name)
print("age:", age)
# showPerson("Jack Lee")
help(showPerson)
# Help on function showPerson in module __main__:
# showPerson(name: str, age: int = 16) -> None
# show a person information
这里因为没有任何返回值,就在docstring中指定返回值为
None
,Python并没有类似Java中的void
标记,所以这里只能使用None
。
进阶内容
本系列文章的代码都存放在Github项目:
文章评论