函数参数详解

形参与实参
形参即形式参数,就是在定义函数时括号中指定的参数,本质就是一个名字
实参即实际参数,指的是在调用函数的时候传入的参数,是一个实际的值
在调用函数时就会自动把形参(变量名)和实参(值)进行绑定
函数调用结束之后绑定关系就解除了

def func1(a,b):#a,b就是形参 a=1,b=2
print(a)
print(b)
func1(1,2)#1,2就是实参


位置参数
根据调用阶段 参数分为两类 形参和实参
所以对应的位置参数也有位置形参和位置实参
位置,其实指的是顺序,从左往右来定义的参数就是位置(顺序)参数
需要注意的是:
位置形参的数量与位置实参的数量必须一致,不能多传,也不能少传
实参会按照传入的位置一次赋值给形参
位置形参 位置实参
def func(a,b,c):#abc都是位置形参
print(a,b,c)
func(1,2,3)#1,2,3都是位置实参


def register(name,password,sex):
print('mynameis% my passwordis%my age is%') %(name,password,sex)
register('rose','123','woman')

关键字参数
关键字实参
在调用函数时,指名道姓的为形参赋值就称为关键字参数
其优点是:
可以打破传入蚕食的顺序 可以不与形参顺序相同
注意:
1.不管以什么样的方式传值,每一个形参都必须被传值
2.关键字参数必须位于未知参数的后面
3.不能为同一个参数传多次值
4.使用关键字传参时,实参的名字必须与形参的名字匹配

到底是位置参数还是关键字参数 由实参决定

def func(a,b,c):
print(a)
print(b)
print(c)
#func(1,2,c=3)与位置参数没区别
#func(c=1,2,3)语法错误 关键字参数出现在了未知参数前面
#func(a=1,b=2,c=3) 可以打破位置参数的顺序限制

def register(name,pwd):
print('name is',name)
print('password is',pwd)
register(pwd='123',name='bgon')

可以不用完全按照顺序来传值
open ('今日内容',encoding='utf-8')

默认形参
在定义时,就已经为形参制定了一个值,那这个形参就称之为默认形参
特点:
在调用时,可以不用为默认形参传值,这样在函数体中使用默认形参时,使用时就是默认值
当然也可以传值,这样的话内部使用的就是你传入的值
使用场景:
当函数中的某一形参经常出现重复的值时,就可以将其定义为默认形参
可以简化调用代码
需要注意
1.默认形参必须放在非默认形参后面
2.默认形参的值在定义时就已经固定了
3.不应该将默认形参的默认值设置为一个可变类型
会导致 每次函数调用都共用同一个默认参数,我们应该将函数设计为一个独立的功能,每次调用互不干扰
只能是int float str tuple

def reg1(name,sex,hobby=['play','music']):
print(name,sex)
print(hobby)
reg1('bgon','man',['play','music','movie'])
reg1('cgon','man',['music','sleep'])

def reg1(name,sex,hobby):
print(name,sex)
print(hobby)
reg1('bgon','man',['play','music','movie'])
reg1('cgon','man',['music','sleep'])


可变长参数指的是,可以传任意个数的实参
传入实参是为了给形参来使用,那就意味着,必须让形参也具备可以接受任意个数的参数的能力
也就是*和**
带*的形参
带*的形参表示可以接受任意个数的实参,这些接受到的实参会被打包成元组类型
形参的名字可以随意,但是建议用args 是arguments的缩写
iterable 可迭代的 只要是可以被for in 循环使用的都是可迭代 字符串 列表 元组 字典 集合
带*的实参
在实参前面加*,会自动将*后的值,打散('abc'打散 成了'a','b','c')
带*的实参 不能接受关键字的实参

def func(*abc):
print(abc)
pass
func(1)
func(1,2)
func(1,2,3)

位置形参与可变长形参混合使用***
当可变长形参,出现在了位置形参的前面时,那么后面的位置形参必须以关键字实参来传入
def func(*args,a,b):
print(a,b,args)
func(1,2,3,a=4,b=5)
当可变长形参出现在位置形参后面,会先按照顺序给前面的位置形参赋值,最后剩余的就赋值给可变长args
def func(a,b,*args):
print(a,b,args)
func(1,2,3,4,5)

**的使用
形参中如果带有**,会把关键字实参打包成字典类型传入
只能接收多出来的关键字实参
**不能接受位置实参

def func(**b):
print(b)
func(1)

先为前面的位置形参赋值,后续的多余的关键字参数赋值给**
def func(a,c,**b):
print(a,c)
print(b)
func(1,s=100,c='abc')



实参中带**,会把**后的字典(也必须是字典类型)打散,成关键字实参(**{'a':1}) 打散为a=1
def func(name,sex):
print(name,sex)
func(**{'name':'rose",'sex':'woman'})#func(name='rose')


# print(**{'name':'rose"}) 错误

*和**可以为函数预留扩展空间,后期可以根据需求增加参数,而且旧的函数调用方式也不会出现问题
简单的说就是提高函数的扩展性

写一个带有可变长的位置形参函数
def func(name,pwd,*kwargs) #******
if name == 'bgon' and pwd =='123':
if 'phone' in kwargs:
if kwargs['phone']=='110'
print('登陆成功!')
else:
print('传入手机号验证!')
else:
print('登录失败!')

func('bgon','123',phone='110')

# 该方式可以接受任意个数的位置实参和关键字实参,
# 但要注意顺序,位置实参必须在关键字之前

def inner(name,sex,age):
print(name,sex,age)

def outer(*args,**kwargs):
print(args)
print(kwargs)
inner(*args,**kwargs) # inner(1,2,3,a=10,b=20)

outer(1,2,3,100,a=10,b=20)

# 上述写法 可以将outer接收到的所有参数 原模原样的传给inner函数
posted @ 2019-01-11 14:48  777ijBGly-  阅读(328)  评论(0编辑  收藏  举报