-一切皆对象,所以函数也是一个对象,对象是内存中专门用来存储数据的一块区域。
-函数可以用来保存一些可执行的代码,并在有需要时进行多次调用。
1.创建函数,函数名要符合标识符规范
def 函数名( [形参1,形参2,......形参n] ) :
代码块
在函数中保存的代码不会立即执行,需要调用函数,代码才会执行。
def fn():
print('第一个函数')
print(fn)
print(type(fn))
结果:
<function fn at 0x000001884CCB3EB0> 内存地址
<class 'function'>
2.调用函数
def fn():
print('第一个函数')
fn()
fn()
结果:
第一个函数
第一个函数
fn是函数对象,fn()是调用函数
print也是函数对象,print()调用函数
定义函数一般就是要实现某种功能的
3.函数的参数
在定义函数时可以定义数量不等得形参,多个形参之间通过逗号隔开。
定义函数时指定形参。调用函数时来传递实参。
def sum(a,b):
print(a,'+',b,'=',a+b)
sum(10,20)
结果:
10 + 20 = 30
4.定义形参时可以为形参指定默认值 。指定默认值以后,如果用户传递了参数则默认值没有任何作用,如果用户没有传递,则默认值会生效。
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
fn(1,2)
结果:
a= 1
b= 2
c= 20
5.实参的传递方式
位置参数就是将 对应位置的实参 复制给 对应位置的形参。第一个实参赋值给第一个形参,第二个实参赋值给第二个形参,以此类推。
关键字参数可以不按照形参定义的顺序去传递,而直接根据参数名去传递参数。
def fn(a,b,c=20):
print('a=',a)
print('b=',b)
print('c=',c)
fn(b=5,a=4,c=1)
结果:
a= 4
b= 5
c= 1
print('hello',end='')位置参数和关键字参数可以混合使用
混合使用位置参数和关键字参数时,必须将位置参数写到前面。不然会报错!!
函数在调用时,解释器不会检查实参的类型,实参可以传递任意类型的对象,甚至传函数也可以
def fn(a):
a=10 在函数中对形参进行重新赋值,不会影响其他的变量.改变量
print('a=',a)
c=30
fn(c)
print('c=',c)
结果:
a= 10
c= 30
def fn(a): a是一个列表,尝试修改列表中的元素。
a[0]=10 如果形参指向的的是一个对象,当我们通过形参去修改对象时,
print('a=',a) 则会影响到所有指向该对象的变量
c=[1,2,3]
fn(c)
print('c=',c) a和c指向的是同一个对象,可以id(a) id(c)来查看两个id ,改a会影响c,改c会影响a
结果: 改对象
a= [10, 2, 3]
c= [10, 2, 3]
如果不想传对象时,改对象影响到原来的,可以进行传一个对象的副本。
浅复制copy()
fn(c.copy())
或者 fn(c[:]) 列表的切片
结果:
a= [10, 2, 3]
c= [1, 2, 3]
def fn(a,b,c):
print('a=', a)
print('b=', b)
print('c=', c)
def fn2(a):
print('a=',a)
a(1,2,3) 相当于fn(1,2,3)去调用fn()函数
fn2(fn)
结果:
a= <function fn at 0x000001ED67E93EB0>
a= 1
b= 2
c= 3
6.不定长的参数
在定义函数时,可以在形参前面加上一个*,这样这个形参将会获取到所有的实参。
他将会把所有的实参保存到一个元组中。
def fn(*a):
print('a=', a,type(a))
*a会接受所有的位置实参,并会将这些实参统一保存到一个元组中(装包)
fn()
fn(1,2,3,4)
结果:
a= () <class 'tuple'>
a= (1, 2, 3, 4) <class 'tuple'>
求和
def fn(*a):
sum=0
for k in a :
sum+=k
print('sum=', sum,type(a))
fn(1,2,3,4)
结果:
sum= 10 <class 'tuple'>
带星号*的形参只能有一个,但可以和其它参数配合使用
def fn(b,c,*a):
print('a=', a)
print('b=', b)
print('c=', c)
fn(1,2,3,4)
结果:
a= (3, 4)
b= 1
c= 2
注意:可变参数不是必须写在最后,但是注意,带*的参数后的所有参数,都必须以关键字参数的形式传递,不然报错。
def fn(b,*c,a):
print('a=', a)
print('b=', b)
print('c=', c)
fn(1,2,3,a=4)
结果:
a= 4
b= 1
c= (2, 3)
如果在形参的开头直接写一个*,则要求我们所有参数必须以关键字参数形式进行传递
def fn(*,a,b,c):
print('a=', a)
print('b=', b)
print('c=', c)
fn(a=2,b=3,c=6)
结果:
a= 2
b= 3
c= 6
*形参只能接受位置参数,不能接受关键字参数。不然会报错!
**形参可以接受其他的关键字参数,它会将这些参数统一保存到一个字典中。字典的key就是参数的名字,字典的value就是参数的值。**形参也是只能有一个,并且必须写在所有参数的最后。
def fn(b,c,**a):
print('a=', a,type(a))
fn(d=1,b=3,c=6,e=10,f=20)
结果:
a= {'d': 1, 'e': 10, 'f': 20} <class 'dict'>