Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)

函数是用于处理某一个特定功能或任务的,里面的有些信息需要变化,不然就太过死板,我们可以将这些信息通过参数传递进去,这样函数就更加灵活了。

比喻说定义一个求和函数,如果没有参数,那就只能求固定两个数的和了,如果想求其他两数的和,就需要改代码了,而如果我们将要求和的两个数通过参数传递给函数去进行求和计算,这样就方便多了,只需在函数调用的时候,将要求和的数当做参数传给函数即可。

函数参数的好处:增加函数的通用性,针对相同的数据处理逻辑,能够适应更多的数据。

函数的参数:形参和实参

函数的参数是填写在函数名后面的小括号里面的,多个参数之间使用英文逗号隔开。例如:function(arg1, arg2 …)

函数的参数分为形参和实参。

形参:形式参数,定义函数时给出的用于接收用户数据的参数。即定义函数时,函数名后括号里面的变量

形参作用:告诉外界能够传递的参数个数;在函数内部当做变量使用,进行需要的数据处理。

实参:实际参数,调用函数时,小括号里面的参数,用来将数据传递到函数内部使用。即调用函数时,函数名后面的小括号里面传的数据(可以是数字、变量、表达式、字符串、列表、字典、函数名等)。

def fun_add(a,b):    # a,b是形参,定义函数的同时定义的用于接收用户数据的参数,只是一个占位符号罢了,自定义的
    return a+b

num1 = 10
num2 = 20
result = fun_add(num1,num2)   # num1,num2是实参,调用函数时传入的真实的数据。将来做运算的数据
print(result)   # 30

在函数调用时,会将实参赋值给形参,可以理解成把一个值赋给一个变量。

实参和形参的名称可以不一样。

传递的参数类型

在函数调用过程中,进行参数传递,如果传递的参数是不可变对象,在函数体内的修改不会影响实参的值;如果传递的参数是可变对象,在函数体内的修改会影响实参的值。

代码演示:

def fun(arg1,arg2):
    print('arg1:',arg1)
    print('arg2:',arg2)
    arg1 = 999
    arg2.append(100)
    print('arg1:', arg1)
    print('arg2:', arg2)

n = 10
lst = [11,22,33]
print('n:',n)   # n: 10
print('lst:',lst)   # lst: [11, 22, 33]

# 跳到函数定义处,执行函数内的代码
fun(n,lst)
# 函数体执行完成后继续执行下面代码

# 10是不可变对象,在函数体内的修改arg1 = 999不会影响实参n。
print('n:',n)    # n: 10

# 列表是可变对象,在函数体内进行了修改arg2.append(100),实参lst也跟着变了。
print('lst:',lst)   # lst: [11, 22, 33, 100]
图片[1]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

1、位置参数

根据形参对应的位置进行实参传递。即调用函数时,将实参(值)按照函数定义时指定的参数顺序依次填写在函数名后面的小括号里面。

如果采用位置参数,位置实参和位置形参的顺序要一一对应,才能正确的传递信息。形参和实参个数要一样,否则报错 TypeError。

def my_function(name,age):      # name,age是位置形参,必须被传值,否则报错
    str = f'我叫{name},今年{age}。'
    return str

print(my_function('张三',20)) # '张三',20是位置实参,要与形参顺序一一对应。即name = '张三'  age = 20

# 实参和形参的位置要一一对应,才能正确的传递信息
print(my_function(20,'张三')) # 如果这样写的话,传递的信息就变成了name=20,age='张三'。这样很明显不对,没有意义
图片[2]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

2、关键字参数

根据形参名称进行实参传递。使用关键字参数 允许函数调用时,传递的参数和函数定义时的参数顺序不同(可以无序),python 解释器会根据关键字参数名匹配参数值。

函数调用时,通过“key = value”的形式来加以指定参数。使用关键字参数可以让函数更加清晰、容易使用。

def my_function(name,age):
    print(f'我叫{name},今年{age}。')

# python解释器会跟据关键字参数名去匹配参数值,age,name就是关键字参数
# age是形参名称,20是实参值;name是形参名称,'张三'是实参值。
my_function(name = '张三',age = 20) # 我叫张三,今年20。

# 传递的参数和函数定义时的参数顺序可以不同
my_function(age = 20,name = '张三') # 我叫张三,今年20。
图片[3]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

函数调用时,也可以位置传参和关键字传参混合使用,但要注意:位置参数必须在关键字参数前面,但关键字参数之间可以无序。

def student_info(name,age,gender,iphone):
    print(f'你的姓名是{name},年龄{age},性别{gender},电话号码{iphone}')

# 关键字参数和位置参数可以混合使用
student_info('张三',20,gender='男',iphone='15537655678')

# 位置参数顺序要和函数定义时的参数顺序一样,否则信息无意义
student_info(20,'张三',gender='男',iphone='15537655678')

# 位置参数必须在关键字参数前面
# student_info('张三',20,gender='男','15537655678')  # SyntaxError: positional argument follows keyword argument

student_info('张三',20,gender='男',iphone='15537655678')

# 关键字参数不分先后顺序
student_info('张三',20,iphone='15537655678',gender='男')
图片[4]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

命名关键字参数

如果想要限制使用关键字参数的名字,可以使用命名关键字参数。即在函数定义时,使用 “*” 来分隔形参,“*” 后面的参数就是命名关键字参数。

如果定义了命名关键字参数,那么‘*’ 后面的参数,在函数调用时,只能使用关键字传参(key = value)。

def fun(a,b,*,c,d):  # *后面的参数,在函数调用时,只能使用关键字传参
    print(a,b,c,d)

# c和d必须使用关键字传参
# fun(10,20,30,40)    # TypeError: fun() takes 2 positional arguments but 4 were given
fun(10,20,c=88,d=456)   # 10 20 88 456
图片[5]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

如果命名关键字中有默认值,调用时,可以不给这个参数传值。

def fun(a,b,*,c=9999,d):  # *后面的参数是命名关键字参数
    print(a,b,c,d)

# 如果命名关键字参数中有默认值,可以不传这个参数的值
fun(10,20,d=456)   # 10 20 9999 456
图片[6]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

3、默认值参数(缺省参数)

函数在定义时,给形参设置一个默认值,调用函数的时候可以不传该默认参数的值。使用默认值参数,可以避免调用函数时忘记传参导致的错误。

注意:无论是函数定义还是函数调用,位置参数必须在默认值参数前面。

调用函数的时候,只有在与默认值不符的时候才需要传递实参。所以在程序编写时,通常将不经常改变的参数设置为默认值参数。如果为默认值参数传值,则会修改默认参数值。

例如购买剃须刀的一般都是男性,存储用户信息的时候就可以把性别‘gender’这一项设置默认值为男性‘male’。

# gender就是一个默认值参数,写法和关键字参数一样:key = value
def student_info(name,age,gender='male'):
    print(f'你的姓名是{name},年龄{age},性别{gender}。')

# 不给默认值参数传参,则使用默认值
student_info('张三',20)

# 如果给默认值参数传参,则会修改默认参数值
student_info('星星',18,'female')
图片[7]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

4、不定长参数(可变参数)

如果我们不确定在函数调用的时候会传递多少个参数(包括不传参),可以采用不定长参数。而传递的参数类型无非就是位置参数和关键字参数两种。

1)个数可变的位置参数(包裹位置参数)*

定义函数的时候,若无法确定传递的位置实参的个数,可以在参数名前添加 ‘*’,定义一个个数可变的位置形参(例如:def fun(*args),args是自己取的名字,可以叫其他的名字)。而这个形参会将传进的所有参数收集,然后根据传进参数的位置合并为一个元组。这是一个组包(收集零散数据组成一个整体)的过程。

在函数调用时,使用位置传参。

# 个数可变的位置形参
def fun(*args):   # args变量将传进的所有参数收集,根据传进参数的位置合并为一个元组
    print(args)   # 把传递的参数打印输出

# 可以不传参
fun()           # ()
fun(99)         # (99,)
fun(76,345)     # (76, 345)
fun(9,32,21)    # (9, 32, 21)
图片[8]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

实参为列表时

a、对于个数可变的位置参数,如果传递的实参是一个列表的话,可以使用 ‘*’ 将列表中的每个元素都转换为位置实参传入

def fun(*args):
    print(args)

lst = [10,20,30,40]

fun(*lst)    # 等价于 fun(10,20,30,40)
图片[9]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

如果不使用 “*” 来传递列表的话,会把列表当做是一个位置参数。

def fun(*args):
    print(args)

lst = [10,20,30,40]

fun(lst)    # 等价于 fun([10,20,30,40])
图片[10]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

b、如果形参是普通参数(位置参数或默认值参数)且有多个,在传递列表时,需要使用 “*” 将列表中的每个元素都转换为位置实参传入,且形参个数和列表元素个数必须相同,否则控制台会报错:

def fun(a,b,c):
    print('a =',a)
    print('b =',b)
    print('c =',c)

lst = [78,32,65]
# fun(lst)    # TypeError: fun() missing 2 required positional arguments: 'b' and 'c'
fun(*lst)
图片[11]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

2)个数可变的关键字参数(包裹关键字传递)**

定义函数时,若无法确定传递的关键字实参的个数,可以在参数名前添加 ‘**’,来定义一个个数可变的关键字形参(例如:def fun(**kargs),kargs是自己取的名字,可以叫其他的名字)。形参 kargs 将所有的关键字参数收集,合成一个字典保存着。这是一个组包(收集零散数据组成一个整体)的过程。

在函数调用时,使用关键字传参。

# 个数可变的关键字形参
def fun(**kargs):   # kargs收集所有传进的关键字参数,打包成一个字典
    print(kargs)

fun()
fun(a = 99)         # {'a': 99}
fun(a = 76,b = 345)     # {'a': 76, 'b': 345}
fun(a = 9,b = 32,c = 21)    # {'a': 9, 'b': 32, 'c': 21}
图片[12]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

实参为字典时

a、如果形参是个数可变的关键字参数,在传递字典时,要使用 “**” 将字典中的元素转换为关键字参数传入

def fun(**kargs):
    print(kargs)

dct = {'a': 100,'b': 888,'c': 562}
fun(**dct)
图片[13]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

注意:如果传递字典的时候,不使用 “**” ,那这个字典就会被当做是一个普通的位置参数。

# 如果形参只有个数可变的关键字参数,传递字典时,不带**,会报错
# 因为不带**,字典就只是一个普通的位置参数了
def fun(**kargs):
    print(kargs)

dct = {'a': 100,'b': 888,'c': 562}
fun(dct)

# 添加一个位置形参
def fun(a,**kargs):
    print(a,kargs)

dct = {'a': 100,'b': 888,'c': 562}
fun(dct)    # {'a': 100, 'b': 888, 'c': 562} {}
图片[14]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

b、如果形参有多个,那么在传递字典时,就需要使用 “**” 将字典中的每个键值对转换成关键字实参传入:

def fun(a,b,c):
    print('a =',a)
    print('b =',b)
    print('c =',c)

dct = {'a': 100,'b': 888,'c': 562}
fun(**dct)   # 等价于 fun(a=100,b=888,c=562)
图片[15]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

注意:如果在定义函数的过程中,既要有个数可变的位置形参,也要有个数可变的关键字形参(如果组合使用,就相当于该函数可以接收任意个数任意类型的参数),那么,个数可变的位置形参必须放在个数可变的关键字形参前面。否则报错。

def fun(*args,**kargs):
    print(args,kargs)

fun(10,20,a = 99)         # (10, 20) {'a': 99}
fun(20,43,21,65,a = 76,b = 345)     # (20, 43, 21, 65) {'a': 76, 'b': 345}
图片[16]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

函数参数综合使用

参数可以混合使用,但定义函数时形参有一个顺序:位置参数,默认值参数,个数可变的位置参数,命名关键字参数,个数可变的关键字参数。

'''
a:位置形参
b:默认值形参
args:个数可变的位置参数
c:命名关键字参数(调用时,只能使用关键字实参进行传参)
d:命名关键字参数(调用时,只能使用关键字实参进行传参)
kargs:个数可变的关键字参数
'''

def fun(a,b=100,*args,c=9999,d,**kargs):  # *后面的参数,在函数调用时,只能使用关键字传参
    print(f'a = {a}')
    print(f'b = {b}')
    print(f'args = {args}')
    print(f'c = {c}')
    print(f'd = {d}')
    print(f'kargs = {kargs}')

fun(10,20,22,33,44,55,c=21,d=100,name='张三',age=22)
图片[17]-Python函数的参数类型详解(形参和实参、位置参数、关键字参数、默认值参数、不定长参数)-尤尤'blog

函数调用时,位置实参必须在关键字实参前面。

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容