1. 实参与形参
形参 : 函数定义阶段 , 括号内定义的参数名 ( 变量名 ) , 形参的表现形式只有一种就是参数命 .
实参 : 函数调用阶段 , 括号内传入的参数值 ( 变量值 ) , 实参的表现形式有很多种 ( 核心 : 可以引用到值 ) .
两者之间的关系 :
函数调用阶段 -- > 实参的值绑定给形参名 .
函数调用完毕 -- > 解除绑定 .
def aa ( x, y) :
z = x + y
aa( 10 , 20 )
a = 10
b = 20
aa( a, b)
2. 位置形参与位置实参
位置形参 : 定义函数阶段 , 按照从左到右的顺序依次定义的形参 .
特点 : 形参必须被传值 .
位置实参 : 在函数调用阶段 , 按照从左到右的顺序依次传入的值 .
特点 : 按顺序依次为形参赋值 .
* 形参与实参的数量必须相等 .
def aa ( x, y, z) :
print ( x, y, z)
aa( 1 , 2 , 3 )
aa( 3 , 2 , 1 )
aa ( 3 , 2 ) 少了一个参数错误提示 :
英 : TypeError : aa ( ) missing 1 required positional argument : 'x' .
中 : 英 : 类型错误 : aa()缺少 1 个必需的位置参数:“x” .
aa ( 3 , 2 , 1 , 0 ) 多了一个参数错误提示 :
英 : TypeError : aa ( ) takes 3 positional arguments but 4 were given .
中 : TypeError : aa()接受 3 个位置参数,但给出了 4 个 .
3. 关键字实参
关键字实参 : 在函数调用阶段 , 按name = value的格式传入值.
特点 : 不用记住形参的顺序 , 可打乱顺序赋值 .
* 形参与实参的数量必须相等 .
位置实参与关键字实参一起混用时的使用规则 :
* 1. 关键字实参不能位置参数前 .
* 2. 不能为同一个形参多次赋值 .
* 越简单的格式写在前面 , 越复杂的格式写在后面 .
def bb ( x, y, z) :
print ( x, y, z)
bb( x= 1 , z= 3 , y= 2 )
bb( z= 3 , x= 1 , y= 2 )
def aa ( x, y, z) :
print ( x, y, z)
aa( x= 1 , 2 , z= 3 )
英 : SyntaxError : positional argument follows keyword argument .
中 : 语法错误:位置参数跟在关键字参数后面 .
def aa ( x, y, z) :
print ( x, y, z)
aa( 1 , 2 , 3 , z= 3 )
英 : TypeError : aa ( ) got multiple values for argument 'z' .
中 : 类型错误 : aa ( ) 为参数“z”获取了多个值 .
4. 默认形参
默认形参 : 在函数定义阶段 , 以key = value的形式为形参赋值 , 如果传值 , 以实参值为准 .
特点 : 定义阶段已经为形参赋值 , 在调用阶段可以不用为其传值 .
位置形参和默认形参混用一起混用时的使用规则 :
* 1. 位置形参在前 , 位置实参在后面 .
* 2. 默认形参只在函数定义阶段赋值一次 .
* 3. 默认形参的值推荐指向不可变类型 .
def aa ( x, y= 2 , z= 3 ) :
print ( x, y, z)
aa( 1 )
aa( 1 , 5 , 6 )
4.1 使用场景
def func ( name, age, gender= 'male' ) :
print ( name, age, gender)
func( 'kid' , 18 )
func( 'qz' , 19 )
func( 'qq' , 19 , 'female' )
运行工具窗口显示 :
kid 18 male
qz 19 male
qq 19 female
def add_func ( x, y, is_print= False ) :
if not is_print:
return x + y
print ( x + y)
res = add_func( 1 , 2 )
print ( res)
4.2 注意事项
默认形参注意点 : 默认形参是一个列表的时候 , 使用方法操作时 , 操作同一个列表共用同一个内存空间 .
class A :
def __init__ ( self, a= [ ] ) :
self. a = a
print ( id ( a) , id ( self. a) )
a1 = A( )
a2 = A( )
def aa ( x= [ ] ) :
x. append( 1 )
print ( x, id ( x) )
aa( )
aa( )
aa( )
当定义函数后 , 就会将函数体存到内存中去 , 默认形参 , 也包含在内 .
在调用的时候 , 调用的同一个函数体 , 默认形参没有修改 , 操作的列表的话 , 操作的是函数体中的创建好的空间 .
* 函数体中的列表下次使用 , 肯定不是最初的列表 , 而是被修的列表 .
5. 可变长参数
* 与 * * 搭配参数名使用时有特殊的作用 .
5.1 形参中使用
在位置形参中带 * : 将溢出的位置实参汇总成元组 , 赋值给紧跟 * 其后的变量 .
在关键字形参中带 * * : 将溢出的位置实参汇总成字典 , 赋值给紧跟 * * 其后的变量 .
1. *的使用
def aa ( x, * y) :
print ( x, y)
aa( 1 )
aa( 1 , 2 )
aa( 1 , 2 , 3 )
2. **的使用
def aa ( x, ** y) :
print ( x, y)
aa( 1 )
aa( 1 , a= 1 , b= 2 )
5.2 实参中使用
在位置实参中带 * : 将紧跟 * 其后的序列类型值 ( 能被for遍历的 ) , 解包赋值给多个位置形参 .
在关键字形参中带 * * : 将紧跟 * * 其后的字典类型值 , 解包赋值给多个关键字形参 .
1. *的使用
def aa ( x, y, z) :
print ( x, y, z)
aa( * [ 1 , 2 , 3 ] )
aa( * 'qwe' )
2. **的使用
def aa ( x, y, z) :
print ( x, y, z)
aa( ** { 'x' : 1 , 'y' : 2 , 'z' : 3 } )
5.3 通用搭配
形参中约定俗成的规定 :
* 后面的变量名为 args
* * 后面的变量名为 kwargs
def func ( * args , * * kwargs ) : 可变长参数的长度不固定 , 接收任意长度的的参数 .
def func ( * args, ** kwargs) :
x1, x2 = args
y1, y2 = kwargs. values( )
print ( x1, x2, y1, y2)
func( * ( 10 , 20 ) , ** { 'y' : 30 , 'a' : 40 } )
def func ( * args, ** kwargs) :
print ( 'func' )
func( )
6. 命名关键字参数
命名关键字参数 : 在定义函数时 , 出现在 * 与 * * 之间的参数 , ( 出现在 * 后面 , 看起来像位置参数 , * * 可以不出现 ) .
特点 : 在调用函数时 , 命名关键字参数必须按照key = value的形式传值 , ( 一般出现在面试题中 ) .
def func1 ( * args, x, ** kwargs) :
print ( 'func1' )
func1( x= 1 )
def func2 ( * args, x) :
print ( 'func2' )
func2( x= 1 )
7. 混用规则
混用规则 : 越简单的格式写在前面 , 越复杂的格式写在后面 .
混用顺序 : 位置参数 , 可变长位置参数 , 命名关键字参数 , 关键字参数 , 可变长关键字参数 .
def func1 ( x, * args, y, z= None , ** kwargs) :
print ( x, args, y, z, kwargs)
func1( 0 , y= 1 , z= 2 )