1.函数简介
• 函数也是一个对象
• 函数用来保存一些可执行的代码,并且可以在需要时,对这些语句进行多次调用
语法
def 函数名([形参1,形参2,形参3....]):
代码块
#定义一个函数
#函数中保存的代码不会立即执行,需要调用函数代码才会执行
def fn():
print("这个是我的第一个函数")
"/Users/artemisyan/PycharmProjects/study with python/venv/bin/python" "/Users/artemisyan/PycharmProjects/study with python/Day 10/dome 1.py"
Process finished with exit code 0
#以上空白 未执行#
def fn():
print("这个是我的第一个函数")
print(fn)#加()代表执行此功能
<function fn at 0x10d963e18> #表示调用的这个函数的内存地址
def fn():
print("这个是我的第一个函数")
# print(fn)
fn() #不加print表示调用此函数
这个是我的第一个函数
代码都存到了函数之中,只需调用一次就可以将所有代码直接调用出来,调用多次,即可将代码多次调用。
def fn():
print("这个是我的第一个函数")
print("hello")
print("heiehi¥¥¥")
print("hhehe")
fn()
fn()
fn()
这个是我的第一个函数
hello
heiehi¥¥¥
hhehe
这个是我的第一个函数
hello
heiehi¥¥¥
hhehe
这个是我的第一个函数
hello
heiehi¥¥¥
hhehe
#fn 是函数对象,fn()调用函数
注意: 函数名必须符合标识符的规范(可以包含字母、数字、下划线但是不能以数字开头) print是函数对象 print()是调用函数
2. 函数的参数
2.1 形参和实参
#定义一个函数,来求任意2个数的和
def s():
a=1
b=2
print(a+b)
s()
3
#在定义函数的时候,可以在函数后面的()中定义数量不等的形参,多个形参之间使用","隔开
def s(a,b):
a=None
b=None
print(a+b)
s() #TypeError: s() missing 2 required positional arguments: 'a' and 'b' #少了实际的参数
def s(a,b):
print("a=",a)
print("b=",b)
s(1,2)
a= 1
b= 2
#实参传的是谁,形参就是谁
def s(a,b):
print(a,"+",b,"=",a+b)
s(1,2)
1 + 2 = 3
• 形参(形式参数) 定义形参就相当于在函数内部声明了变量,但是并不是赋值
• 实参(实际参数)指定了形参,那么在调用函数时必须传递实参,实参将会赋值给对应的形参,简单来说有几个形参就要有几个实参
2.2 函数的传递方式
• 定义形参时,可以为形参指定默认值。
#定义形参时,可以为形参指定默认值
def fn(a,b,c=20):
print("a=",a)
print("b=", b)
print("c=", c)
fn(1,2,3)
a= 1
b= 2
c= 3
#定义形参时,可以为形参指定默认值
#指定了默认值以后,如果用户传递了参数默认值不会生效
#如果用户没有传递参数,默认值则生效
def fn(a,b,c=20):
print("a=",a)
print("b=", b)
print("c=", c)
fn(1,2)
a= 1
b= 2
c= 20
def fn(a=5,b=10,c=20):
print("a=",a)
print("b=", b)
print("c=", c)
fn(1)
a= 1
b= 10
c= 20
def fn(a=5,b=10,c=20):
print("a=",a)
print("b=", b)
print("c=", c)
# fn(1)
fn()
a= 5
b= 10
c= 20
指定了默认值以后,如果用户传递了参数则默认值不会生效。如果用户没有传递,则默认值就会生效
• 位置参数:位置参数就是将对应位置的实参赋值给对应位置的形参
def fn(a=5,b=10,c=20):
print("a=",a)
print("b=", b)
print("c=", c)
fn(1,2,3)
a= 1
b= 2
c= 3
• 关键字参数 : 关键字参数可以不按照形参定义的顺序去传递,而根据参数名进行传递
def fn(a=5,b=10,c=20):
print("a=",a)
print("b=", b)
print("c=", c)
fn(b=1,c=2,a=3)
a= 3
b= 1
c= 2
def fn(a=5,b=10,c=20):
print("a=",a)
print("b=", b)
print("c=", c)
#位置传参和关键字传参可以混合使用
fn(2,c=50)
a= 2
b= 10
c= 50
• 混合使用位置参数和关键字参数的时候必须将位置参数写到关键字参数前面去
def fn(a=5,b=10,c=20):
print("a=",a)
print("b=", b)
print("c=", c)
#位置传参和关键字传参可以混合使用,关键字传参一定放到位置传参后面
fn(c=50,1) #SyntaxError: positional argument follows keyword argument
实参的类型
def fn2(a):
print("a=",a)
fn2(123)
a= 123
也可定义变量,直接传递变量
def fn2(a):
print("a=",a)
b=123
b=False
b=None
b="python"
fn2(b) #什么参数都可以传
a= python
def fn(a):
a[0]=20
#a是一个列表,修改列表中的元素
print("a=",a)
c=[1,2,3]
fn(c)
print("c=",c)
#此时a和c相当于同一个对象,单纯的改对象的值,所以c也会变化
a= [20, 2, 3]
c= [20, 2, 3]
#如果传递的是可变对象,又不希望在函数内部操作,影响函数外部时,考虑使用副本方式
def fn(a):
a[0]=20
#a是一个列表,修改列表中的元素
print("a=",a,id(a))
c=[1,2,3]
fn(c.copy())
print("c=",c,id(c))
a= [20, 2, 3] 4308739272
c= [1, 2, 3] 4308739208
或者使用fn(c[:])方式
def fn(a):
a[0]=20
#a是一个列表,修改列表中的元素
print("a=",a,id(a))
c=[1,2,3]
fn(c[:])
print("c=",c,id(c))
a= [20, 2, 3] 4457759944
c= [1, 2, 3] 4457759880
3. 不定长参数
• 定义函数时,可以在形参前面加一个*,这样这个形参可以获取到所有的实参,它会将所有的实参保存到一个元组中
#定义一个函数求任意2个数的和
def s(a,b):
print(a+b)
s(12,560) #572
直接形参变为多个变量时无法运行
def s(a,b,c):
print(a+b)
s(12,560) #TypeError: s() missing 1 required positional argument: 'c'
#在定义函数的时候,可以在形参前面加一个*,这样这个形参可以获取到所有的形参,
#它会将所有实参保存到一个元组中。
def s(a,b,c):
print(a+b+c)
def fn(*a):
print("a=",a,type(a))
fn()
此时实参数据保存在元组中
a= () <class 'tuple'>
def s(a,b,c):
print(a+b+c)
def fn(*a):
print("a=",a,type(a))
# fn()
fn(1,2,3,4,5)
a= (1, 2, 3, 4, 5) <class 'tuple'>
def s(*a):
#定义一个变量,保存结果
result=0
#遍历元组,将元组中的元素进行累加
for r in a:
result+=r
print(result)
s(12,560,32)
604
def fn2(a,b,*c):
print("a=",a)
print("b=",b)
print("c=",c)
fn2(1,2,3,4,5)
a= 1
b= 2
c= (3, 4, 5)
• 带*号的形参只能有一个,可以和其他参数配合使用
#带*的参数只能有一个
def fn2(a,*b,*c):
print("a=",a)
print("b=",b)
print("c=",c)
fn2(1,2,3,4,5)
#SyntaxError: invalid syntax
#不定长参数不一定都要写在后面,但是注意,带*的参数后面的所有参数,必须以关键字形式来传递。
def fn2(a,*b,c):
print("a=",a)
print("b=",b)
print("c=",c)
fn2(1,2,3,4,5)
#TypeError: fn2() missing 1 required keyword-only argument: 'c'
def fn2(a,*b,c):
print("a=",a)
print("b=",b)
print("c=",c)
fn2(1,2,3,4,c=5)
a= 1
b= (2, 3, 4)
c= 5
• *形参只能接受位置参数,不能接受关键字参数
#TypeError: fn3() got an unexpected keyword argument 'b' b,d,c是关键字参数,无法传参
def fn3(*a):
print("a=",a)
fn3(b=2,d=1,c=3)
• **形参可以接收其他的关键字参数,它会将这些参数统一保存到字典当中。字典的key就是参数的名字,字典的value就是参数的值
#**的形参可以接收其他关键字参数,它会将这些参数统一保存到字典当中
#字典的key就是参数的名字,字典的value就是参数的值
#**的形参只能有一个,并且必须写在所有的参数后面,不能写在中间或开头
#*a处理的是位置参数,**a处理的是关键字参数
def fn3(**a):
print("a=",a)
fn3(b=2,d=1,c=3)
a= {'b': 2, 'd': 1, 'c': 3}
• **形参只有一个,并且必须写在所有参数的后面
4. 参数的解包
• 传递实参时,也可以在序列类型的参数前添加星号,这样它会自动的将序列中元素依次作为参数传递
def fn(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
fn(1,2,3)
a= 1
b= 2
c= 3
def fn(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
#创建一个元组
t=(20,30,40)
fn(t) #TypeError: fn() missing 2 required positional arguments: 'b' and 'c' 少了实参
def fn(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
#创建一个元组
t=(20,30,40)
fn(t[0],t[1],t[2])
a= 20
b= 30
c= 40
def fn(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
#创建一个元组
t=(20,30,40)
#传递实参时候,也可以在序列类型的参数前面添加*,这样它会自动的将序列三种的元素依次作为参数传递
fn(*t)
a= 20
b= 30
c= 40
• 要求序列中的元素的个数必须和形参的个数一致
def fn(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
#创建一个元组
t=(20,30,40,50)
#TypeError: fn() takes 3 positional arguments but 4 were given
fn(*t)
def fn(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
#创建一个字典
d={"a":1,"b":2,"c":3}
fn(**d)
a= 1
b= 2
c= 3