一、相关
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
Python函数可以在类外定义。
Python函数类似Java中的方法。
二、定义一个Python函数
Python中以def开始定义函数,无需注明函数的返回值类型。
函数名后跟(),其中放入函数所需要的参数,同样的参数不需要注明类型。
函数体以冒号开始,并且首行按规定缩进。
函数第一行可以选择性地使用文档字符串来进行函数说明。
可以选择性地以return结束函数,不包含return的函数,返回值为None。
1.函数定义通式
def 函数名(参数列表):
"函数说明"
函数体
2.定义一个hello函数
def hello():
"""一个hello函数"""
print("Hello World!!!")
hello()
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
Hello World!!!
Process finished with exit code 0
3.定义一个带参函数
def hello(str):
"""一个hello函数"""
print(str)
str = "Hello World!!!"
hello(str)
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
Hello World!!!
Process finished with exit code 0
三、函数的调用
函数的简单调用,我们在上面已经实现过,现在需要说明的是,函数在调用过程中,需要满足函数的要求。比如,如果函数要求调用是需要传入一个参数,那么我们应当满足这个要求,否则就会报错
def hello(str): #要求传入一个参数:str
"""一个hello函数"""
print(str)
str = "Hello World!!!"
hello(str) #传入了参数
hello() #未传入参数
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
Hello World!!!
Traceback (most recent call last):
File "E:/Workspaces/PycharmProjects/untitled/openTest.py", line 7, in <module>
hello() #未传入参数
TypeError: hello() missing 1 required positional argument: 'str'
Process finished with exit code 1
如上运行结果所显示的,第一次调用时传入了参数,运行正常打印,第二次调用函数时,未传入参数,出现报错:hello() missing 1 required positional argument: 'str'
四、Python中参数的传递形式
首先我们需要知道的是,在Python中规定,对象才拥有类型,变量不用对类型。strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
不可变类型(immutable):对于不可变类型变量来说,对其进行重新赋值后,并不是改变了这个变量的值,而是重新生成了一个不可改变类型对象,然后让变量指向这个新生成的对象,原对象的值并没有改变。Python函数传递不可变类型参数时,传递的知识值,相当于值传递。
可变类型(mutable):对可变类型变量来说,我们都是修改可变类型内的值,例如,我们传入list类型后,会修改list内的某个值,但其实对于对象本身的储存地址来说,是没有改变的,相当于引用传递。
关于值传递和引用传递的相关内容请查看:我与校花同桌之间的金钱交易(又名:戏说值传递与引用传递,这还看不懂你来打我)
1.不可变类型参数传递
def change(a):
a += 1 # 对参数执行价1
a = 1
change(a)
print(a)
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
1
Process finished with exit code 0
执行程序后显示,不可变类型参数的传递,不会影响原变量
2.可变类型参数传递
def change(list):
list.append(["baldwin","jack","tony"]) # 改变参数
list = ["tom","jsaon"]
print(list)
change(list)
print(list)
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
['tom', 'jsaon']
['tom', 'jsaon', ['baldwin', 'jack', 'tony']]
Process finished with exit code 0
五、传参方式
除了通过参数传递方式来分类参数外,还可以通过参数要求的不同来分类参数:必需参数、关键字参数、默认参数、不定长参数
1.必需参数
必需参数是比较常见的,我们上面所定义的参数都是必需参数,必需参数要求我们以正确的顺序传入,不可缺失,否则报错:hello() missing 1 required positional argument: 'str',上面有例子,这里不再细说。
2.关键字参数
使用关键字传参时,不再要求参数传入顺序与函数规定的参数顺序相同,因为Python解释器会根据参数名关键字来自动对应参数。
def printBaldwin(name,age):
print(name+"`s age is " + age)
printBaldwin(name="Baldwin",age="18")
printBaldwin(age="19",name="Baldwin")
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
Baldwins age is 18<br/>Baldwin
s age is 19
Process finished with exit code 0
很明显的,虽然第二次传参的顺序不符合函数规定顺序,但是由于我们采用的是关键字传参,参数仍然能够正确地在函数中使用。
个人是比较喜欢关键字传参的,这样我们能够清晰地看到每个参数是什么意义,也不用担心参数传输顺序错误所导致的问题了。
3.默认参数
默认参数指的是,若是在调用函数时,没有传入某个参数,那么函数会取一个默认值,这个值需要在定义函数时去注明。
def printBaldwin(name,age = "18"):
print(name+"`s age is " + age)
printBaldwin(name="Baldwin")
printBaldwin(age="20",name="Baldwin")
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
Baldwins age is 18<br/>Baldwin
s age is 20
Process finished with exit code 0
如上第一次调用printBaldwin函数时,并没有传入age的值,但是由于我们在定义printBaldwin函数时,已经规定了age参数默认值为18,所以这种情况下我们得到了默认值18.
4.不定长参数
不定长参数在各个语言中都是很常见的,用来处理我们不知道需要具体多少个参数时候得情形。基本定义规则如下
def 方法名([formal_args,] [*var_args_tuple,][**var_args_dict] ):
"函数说明"
函数体
return [expression]
formal_args:普通函数形参
*var_args_tuple:不定长形参(元组)
**var_args_dict:不定长形参(字典)
不定长参数包括*var_args_tuple和**var_args_dict
我知道你看完基本定义规则后肯定一脸懵逼,别急,将以以下几个例子来看:
var_args_tuple
def printBaldwin(name,age, money):
print("普通形参 : name=",name)
print("普通形参 : age=",age)
print("不定长形参 :money=",money)
printBaldwin("Baldwin","18",1,1,1,1)
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
普通形参 : name= Baldwin
普通形参 : age= 18
不定长形参 :money= (1, 1, 1, 1)
Process finished with exit code 0
此时我们参数中的name和age就是普通形参,*money就是元组类型的不定长形参,在使用函数传参时会先把普通形参的参数传进去,然后再给不定长形参赋值。
当然如果定义方法时把name和age参数删掉也是可以的,我们所有的值都会传到*money这个不定长形参中。
var_args_dict
def printBaldwin(name,age, money):
print("普通形参 : name=",name)
print("普通形参 : age=",age)
print("不定长形参 :money=",money)
printBaldwin("Baldwin","18",a=1,b=2,c=3)
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
普通形参 : name= Baldwin
普通形参 : age= 18
不定长形参 :money= {'a': 1, 'b': 2, 'c': 3}
Process finished with exit code 0
发现了么?我们通过*var_args_dict传进去参数的方式与var_args_tuple是不同的哦!而且在打印这个参数后我们可以看出**var_args_dict参数是以字典的形式存在的。
不定长参数总结
首先要明白的是,引入不定长参数的两种方法,区别在于一个参数名之前有一个*,另一个是**。定长参数与两种不定长参数,三者是可以混合使用的。
def printBaldwin(name,age,*wallet, **money):
print("name=",name)
print("age=",age)
print("wallet=",wallet)
print("money=",money)
printBaldwin("Baldwin","18", 1, 1, 1, a=1, b=2, c=3)
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
name= Baldwin
age= 18
wallet= (1, 1, 1)
money= {'a': 1, 'b': 2, 'c': 3}
Process finished with exit code 0
还有一点比较重要的是,三者之间是存在顺序的,定长参数最前,*args其次,**args最后
六、匿名函数
匿名函数是一种很方便的用法,Python中使用lambda来创建匿名函数,注意,匿名函数不是说这个函数没有名字!
lambda 只是一个表达式,函数体比 def 简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
英国央行http://www.gendan5.com/decision/gbp.html lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
1.匿名函数基本通式
lambda [arg1 [,arg2,.....argn]]:expression
2.使用匿名函数来创建一个加法器
sum = lambda a ,b : a+b
print(sum(10,11))
sum作为这个函数的函数名。
sum函数没有方法体,不需要def来进行函数定义。
使用lambda来创建一个匿名函数。
a、b作为匿名函数的参数。
冒号右边说明本匿名函数的操作,加法器。
C:\Python\Python37-32\python.exe E:/Workspaces/PycharmProjects/untitled/openTest.py
21
Process finished with exit code 0
七、return
return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。有点编程基础的同学都应该了解return,在此不再累述。
八、总结
1.Python中的函数类似Java中的方法,但是Python函数可以在类之外进行定义。
2.函数的不定长参数传递顺序
3.匿名函数
来源:51CTO
作者:Gendan5
链接:https://blog.51cto.com/14513127/2480435