文章目录
什么是函数?
1、函数时组织好的,可重复使用的,用来实现单一或相关联功能的代码段。
2、函数能提高应用的模块性和代码的重复利用率,Python提供了许多内建函数,如print(),但也可自己创建函数,被称为用户自定义函数。
定义一个函数
规则
- 函数代码块以def关键词开头,后接函数标识符名称和圆括号()
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性的使用文档字符串_用于存放函数说明
比如:
def printinfo(age):
"打印任何传入的字符串"
print("年龄":age)
return
- 函数内容以冒号起始,并且缩进
- return[表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的return相当于返回None.
语法
def 函数名(参数列表):
函数体
默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的
实例
输出"hello world"
def hello():
print("hello world")
hello()
更复杂点的,函数中带上参数变量
def area(width,height):
return width * height
w=4;h=5
print(area(w,h))
def print_welcome(name):
print("welcome",name)
print_welcome("China!")
返回值的注意事项:不同于C语言,Python函数可以返回多个值,多个值以元组的方式返回,如:
def fun(a,b):
return a,b,a+b
print(fun(2,5))
函数调用
- 定义一个函数:给了函数一个名称,指定了函数里包含的参数和代码块结构
- 此函数基本结构完成后,通过另一个函数调用执行,也可直接从Python命令提示符执行
实例调用printme()函数:
def printme( str ):
print(str)
printme("武汉加油!")
printme("中国加油!")
参数传递
在Python中,类型属于对象,变量没有类型:
a=[1,2,3]
a="China"
a是一个对象的引用(一个指针),可以指向List类型对象,也可以指向String类型对象。
可更改(mutable)与不可更改(immutable)对象
简单的说:不可更改类型传到函数里重新赋值后,两次输出值不一样,而可更改类型传到函数里对对象的"属性" 重新赋值后输出值一样。
在python中,strings,tuples和numbers是不可更改的对象,而list,dict等则是可以修改的对象
- 不可变类型:变量赋值a=5后再赋值a=10,这里实际是新生成一个int值对象10,再让a指向它,而5被丢弃,不是改变a的值,相当于新生成了a。
- 可变类型:变量赋值a=[1,2,3,4]后再赋值a[2]=5则是将list a 的第三个元素值更改,本身a没有动,只是其内部的一部分值被修改了
Python函数的参数传递:
- 不可变类型:类似C++的值传递,如整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身,比如在fun(a)内部修改a的值,只是修改另一个复制的对象,不会影响a本身。
- 可变类型:类似C++的引用传递,如列表,字典。例如fun(a),则是将a真正的传过去,修改后fun外部的a也会受影响
传不可变参数对象实例:
def fun(a):
a=10
b=20
fun(b)
print(b)#结果是20
实例中有int 对象10,指向它的变量是b,在传递给fun函数时,按传值的方式复制了变量b,a和b都指向了同一个int对象,在a=10时,则新生成了
一个int值对象10,并让a指向它
传可变对象实例:
可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:
def fun(list):
list.append([1,2,3,4,5])
print(list)
list=['k','d','z']
fun(list)
print(list)
传入函数和在末尾添加新内容的对象用的是同一个引用。所以:
修改一下,结果就不一样了
def changeme( mylist ):
"修改传入的列表"
mylist = [1,2,3,4]
print ("函数内取值: ", mylist)
return
# 调用changeme函数
mylist = [10,20,30]
changeme( mylist )
print ("函数外取值: ", mylist)
结果是:
函数内取值: [1, 2, 3, 4]
函数外取值: [10, 20, 30]
参数
正式参数类型:
- 必须参数
- 关键字参数
- 默认参数
- 不定长参数
必须参数
必须参数须以正确的顺序传入函数,调用时的数量必须和声明时的一样
调用printme()函数,必须传入一个参数,不然会出现语法错误:
def printme(str):
"打印任何传入的字符串"
print(str)
return
#调用函数,不加参数会报错
printme()
关键字参数
- 关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
- 使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为Python解释器能够用参数名匹配参数值
实例演示,调用函数时使用参数名:
def printme(str):
"打印任何传入的字符串"
print(str)
return
#调用函数
printme(str = "China")
演示函数参数的使用不需要使用指定顺序:
def printinfo(name,age):
"打印任何传入的字符串"
print("名字:",name)
print("年龄:",age)
return
#调用函数
printinfo(age=18,name='kdz')
默认参数
调用函数时,如果没有传递参数,则会使用默认参数,以下实例中如果没有传入age,则使用默认值17
注意:默认参数必须放在最后面,否则报错:
def printinfo(name,age=17):#默认参数
"打印任何传入的字符串"
print("名字:",name)
print("年龄:",age)
return
#调用函数
printinfo(age=18,name='kdz')
print("--------------------")
printinfo(name="zzh")#使用默认参数age
不定长参数
不定长参数能处理比当初声明时更多的参数,与上述参数不同,声明时不会命名。基本语法如下:
def functionname([formal_args,] *var_args_tuple ):
"函数_文档字符串"
function_suite
return [expression]
加了*的参数会以元组形式导入,存放所有未命名的变量参数。
def printinfo(name,* hobby):
"打印任何传入的参数"
print("输出:")
print(name)
print(hobby)
#调用参数
printinfo('kdz','basketball','music','guitar','movie')
如果在函数调用时没有指定参数,它就是一个空元组,我们也可以不向函数传递未命名的变量。如下实例:
def printinfo(name,* hobby):
"打印任何传入的参数"
print("输出:")
print(name)
for x in hobby:
print(x)
return
#调用参数
printinfo('sing')
printinfo('kdz','basketball','music','guitar','movie')
带两个*的参数基本语法如下:
def functionname([formal_args,] **var_args_dict ):
"函数_文档字符串"
function_suite
return [expression]
加两个星号*的参数会以字典的形式导入
def printinfo(name,** hobby):
"打印任何传入的参数"
print("输出:")
print(name)
print(hobby)
return
#调用参数
printinfo('kdz',a='basketball',b='guitar')
声明函数时,参数中 * 可以单独出现,但如果单独出现星号 * , * 后的参数必须用关键字传入,例如:
def f(a,b,*,c):
return a+b+c
print(f(1,2,c=3))
如果不用关键字键入会报错
匿名函数
python使用lambda来创建匿名函数。
所谓匿名意即不再使用def语句这样标准的形式定义一个函数。
- lambda只是一个表达式,函数体比def简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率
语法
lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
如下实例:
sum = lambda a,b:a+b
#调用sum函数
print(sum(100,151))
补充:
- lambda函数也可以使用关键字参数传递
- 也可以设定默认值,且放在最后位置
return语句
**return[表达式]**语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值得return语句返回None.
return语句用法:
def sum(a,b):
total=a+b
return total
#调用sum函数
s=sum(10,20)
print(s)#结果自然是30
强制位置参数
python3.8新增一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数得形式。
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
#a,b必须使用指定位置参数
#c或d可以是位置形参或关键字形参
#而e或f要求为关键字形参
下面是正确的使用方法:
def f(a,b,/,c,d,*,e,f):
print(a,b,c,d,e,f)
f(10,20,30,d=40,e=50,f=60)
下面是错误的使用方法:
def f(a,b,/,c,d,*,e,f):
print(a,b,c,d,e,f)
f(10,b=20,30,d=40,e=50,f=60)
#b不能使用关键字参数的形式
f(10,20,30,d=40,50,f=60)
#e必须使用关键字参数的形式
补充
函数内可以访问全局变量,但不能更新其值
例如:
a=24
def sum(n):
n+=a
print(a,n)
sum(5)
但如果引用了没更新的值就会报错:
a=24
def sum(n):
n+=a
a=8
print(a,n)
sum(5)#报错
但可以加上global引用以更新变量值
global关键字会跳过中间层直接将嵌套作用域内的局部变量变为全局变量
如:
a=24
def sum(n):
global a
n+=a
a=8
n+=a
print(a,n)
sum(5)