Python参数详解、python参数类型、位置参数、默认参数、可选参数

文章目录

  • 一、位置参数
  • 二、默认参数(Default Arguments)
  • 三、关键字参数
  • 四、可变位置参数
  • 五、可变关键字参数
  • 六、命名关键字参数/强制关键字参数
  • 七、组合使用
  • 以下内容基于Python3.13进行讲解,对于Python3.x来说下面的内容都是支持的。

    参数类型:
    1、位置参数(Positional Arguments),必填参数
    2、默认值参数(Default Arguments),非必传
    3、可变参数,非必传,不限制参数个数,比如说给多个人发邮件,发邮件的人数不确定
    4、关键字参数(Keyword Arguments),非必传,不限制参数个数,会把传过来的关键字参数,放到一个字典里面,传参的时候必须得用k=v这样子来传
    5、命名关键字参数/强制关键字参数(Keyword-Only Arguments)

    一、位置参数

    也叫必传参数,顺序参数,是最重要的,也是必须在调用函数时明确提供的参数!位置参数必须按先后顺序,一一对应,个数不多不少的传递!

    定义:就是在给函数传参数时,按照顺序,依次传值。

    def add(a,b):
        print('a:{}, b:{}'.format(a,b))
    
    print(add(1,2))
    
    #运行结果:
    D:\App\python\python3.13.0\python.exe D:\WorkSpace-Python\Test\test.py 
    a:1, b:2
    

    在这个例子中,a和 b就是位置参数,而且两个值必传,否则会报错。

    二、默认参数(Default Arguments)

    默认参数允许我们在函数定义时为参数指定默认值。如果调用函数时不传递该参数,将使用默认值。

    def test(name,message='Boy'):
        print('name:{}, message:{}'.format(name,message))
    
    test('Tom') #若不传默认参数,则使用默认值
    test('Alice','Girl')  # 输出:name:Alice, message:Girl
    test('Alice',message = 'Girl') # 输出:name:Alice, message:Girl
    
    #运行结果:
    D:\App\python\python3.13.0\python.exe D:\WorkSpace-Python\Test\test.py 
    name:Tom, message:Boy
    name:Alice, message:Girl
    name:Alice, message:Girl
    

    默认参数使用注意事项
    a. 默认参数必须在位置参数后面,这样才能被解释器正确识别,否则会产生二义性。

    def test(message='Boy',name): # SyntaxError: parameter without a default follows parameter with a default
        print('name:{}, message:{}'.format(name,message))
    

    b. 默认参数一定要指向不变对象!

    def defaultzero(arr = []):  #我们的本意是提供的arr参数为0时 返回只有一个0的arr
        arr.append(0)
        return arr
    print(defaultzero())  #输出:[0]
    print(defaultzero())  #输出:[0, 0] 显然重复调用的时候结果不是我们所期望的
    
    #解决方案 使用None
    def defaultzero1(arr = None):
        if arr == None:
            arr = []
            arr.append(0)
        return arr
    print(defaultzero1()) #输出:[0]
    print(defaultzero1()) #输出:[0] 重复调用的时候,也输出相同
    
    #这说明arr是一个对象
    #事实上Python所有的数据类型其实都是对象
    

    说明:上面的答案可能与你想的不一样,为什么呢?应为在定义默认函数时,arr 为一个可变变量,在函数体被读入内存的时候,默认参数arr指向的空列表对象就会被创建,arr的内存地址不变,每次调用函数都像arr变量中添加0

    结果说明python解释器会将默认参数作为一个公共对象来对待,多次调用含有默认参数的函数,就会进行多次修改。

    因此定义默认参数时一定要使用不可变对象(int、float、str、tuple)。使用可变对象语法上没错,但在逻辑上是不安全的,代码量非常大时,容易产生很难查找的bug。

    三、关键字参数

    关键字参数(Keyword Arguments)是一种在函数调用时使用参数名称来指定参数值的方式,不必按照定义形参的顺序传递参数。

    def person(name, age):
    	print('name:{}, age:{}'.format(name, age))
    
    # 使用关键字参数调用函数
    person(name='张三',age=20) #输出:name:张三, age:20
    person(age=31,name='李四') #输出:name:李四, age:31
    

    使用关键字参数调用函数对参数顺序没有要求。

    既有位置参数又有关键字参数,位置参数必须放到关键字参数前面否则报错

    四、可变位置参数

    可变位置参数:Python函数提供了可变参数,来方便进行参数个数未知时的调用。可变参数将以tuple 元组形式传递。

    定义:可变参数就是传入的参数个数是可变的,可以是0个,1个,2个,……很多个。作用:就是可以一次给函数传很多的参数特征(格式):*args*参数 (即在参数前加*号)】

    def add(a,b):
        return a,b
    
    #上述函数若传入多个参数则需要定义多个变量,可以简化为可变参数形式
    def add1(*args):
    	print('args:{}, type:{}'.format(args,type(args)))
        result = 0
        for n in args:
            result = result + n
        return result
    
    # 调用函数1
    print(add1(1,2,3))
    
    # 调用函数2
    tupleArray=(1,2,3)
    # *tupleArray这种方式很常见,很重要
    print(add1(*tupleArray))  #输出结果:6
    
    # 调用函数3
    listArray=[1,2,3]
    # *listArray这种方式很常见,很重要
    # *listArray表示把listArray这个list中所有元素作为可变参数传进去
    print(add1(*listArray))  #输出结果:6
    
    #运行结果:
    D:\App\python\python3.13.0\python.exe D:\WorkSpace-Python\Test\test.py 
    args:(1, 2, 3), type:<class 'tuple'>
    6
    args:(1, 2, 3), type:<class 'tuple'>
    6
    args:(1, 2, 3), type:<class 'tuple'>
    6
    

    可以发现:*args的本质就是把入参以tuple形式传递
    关于*星号的用法可以参考另一篇博文:《python中的*与**用法详解》

    五、可变关键字参数

    关键字参数非必传。Python的可变位置参数以tuple形式传递,而关键字参数则是以dict形式传递。 即可变参数传递的是参数值,关键字参数传递的是参数名:参数值键值对。

    定义:关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。在调用函数时,可以只传入必选参数:

    def test(name,**kwargs):
        print("name:{}, kwargs:{}, kwargs-type:{}".format(name,kwargs,type(kwargs)))
    
    #案例一:
    test('张三') # 输出:name:张三, kwargs:{}, kwargs-type:<class 'dict'>
    
    #案例二:
    test('张三',age=10) # 输出:name:张三, kwargs:{'age': 10}, kwargs-type:<class 'dict'>
    
    #案例三:
    dictArray = {'city': 'Beijing', 'sex': '男'}
    test('李四', **dictArray ) # 输出:name:李四, kwargs:{'city': 'Beijing', 'sex': '男'}, kwargs-type:<class 'dict'>
    
    #**dictArray表示把dictArray这个dict的所有key-value用关键字参数传入到函数的**kwargs参数,kwargs将获得一个dict。注意kwargs获得的dict是dictArray的一份拷贝,对kwargs的改动不会影响到函数外的dictArray。
    
    
    #运行结果:
    D:\App\python\python3.13.0\python.exe D:\WorkSpace-Python\Test\test.py 
    name:张三, kwargs:{}, kwargs-type:<class 'dict'>
    name:张三, kwargs:{'age': 10}, kwargs-type:<class 'dict'>
    name:李四, kwargs:{'city': 'Beijing', 'sex': '男'}, kwargs-type:<class 'dict'>
    
  • **修饰的参数必须是最后一个
  • **修饰的参数必须以关键字的参数方式传参,Python解释器会将传入的关键字和关键字的值生成一个字典供函数内部使用
  • 六、命名关键字参数/强制关键字参数

    命名关键字参数:强制关键字参数(Keyword-only arguments)是在3.1版本之后引入的,指在函数定义时,使用*后缀来限制函数调用时必须使用关键字参数进行传递,而不允许使用位置参数。

    定义:例如只接收city和sex的参数,其他,不接收。

    def person(*, city, sex):   # 使用分隔符“*”,表示后面的参数必须使用关键字传递
    	print(city, sex)
    
    person(city='USA',sex='男')  # 输出:USA 男
    

    作用:限制要传入的参数的名字,只能传已命名关键字参数
    特征:命名关键字参数需要一个特殊分隔符*,而后面的参数被视为命名关键字参数。

    def person(name, age, *, city, sex):
    	print(name, age, city, sex)
    
    person('John',20,city='USA',sex='男')  # 输出:John 20 USA 男
    #person('John',20,city='USA',birthday='1996-02-11') 报错 TypeError: person() got an unexpected keyword argument 'birthday'
    

    关键字参数和命名关键字参数的区别在于,前者可以传递任何名字的参数,而后者只能传递*后面名字的参数。如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:

    def person(name, age, *args, city, sex):
    	print(name, age,args, city, sex)
    
    person('John',20, *[1,2,3,4],city='USA',sex='男')
    
    #运行结果:
    D:\App\python\python3.13.0\python.exe D:\WorkSpace-Python\Test\test.py 
    John 20 (1, 2, 3, 4) USA 男
    

    七、组合使用

    定义:把以上五种参数组合在一起的参数组合
    排放顺序:在Python中定义函数,可以用必选参数、默认参数、可变参数、命名关键字参数和关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数–>默认参数–>可变参数–>命名关键字参数–>关键字参数。

    可读性是代码的一个很重要的要求,所以尽量避免使用多种参数的组合。

    
    def person(name, age,clas='二班', *args, **kwargs):
    	print('name:{}, age:{}, clas:{}, args:{}, kwargs:{}'.format(name, age,clas,args, kwargs))
    
    person('John',20) #输出:name:John, age:20, clas:二班, args:(), kwargs:{}
    person('John',20,'4班',1,2) #输出:name:John, age:20, clas:4班, args:(1, 2), kwargs:{}
    person('John',20,'4班',1,2,city='USA',sex='男') #输出:name:John, age:20, clas:4班, args:(1, 2), kwargs:{'city': 'USA', 'sex': '男'}
    
    
    def f1(a, b, c=0, *, d, **kw):
        print('a:{},b:{},c:{},d:{},kw:{}'.format(a,b,c,d,kw))
    
    f1(1,2,d=4)  # 输出:a:1,b:2,c:0,d:4,kw:{}
    f1(1,2,3,d=4,e=5) #输出:a:1,b:2,c:3,d:4,kw:{'e': 5}
    

    总结:

    1. 位置实参与关键字实参混合使用时,位置实参必须放在关键字实参前面(语法规定)
    2. 位置形参与默认形参混合使用时,位置形参必须在默认形参的左边
    3. *args**kwargs混合使用时,*args必须写在**kwargs的前面,否则会报语法错误

    ***的使用

    1. ***在函数定义处使用
  • *:把多余的普通实参打包成元组
  • **:把多余的关键字实参打包成字典
    1. ***在函数调用处使用
  • *:对元组或列表进行解包
  • **:对字典进行解包
    1. ***同时在函数定义处和调用处使用
  • 先解包变成位置形参
  • 再将多余的位置形参打包
  • # 示例一
    def func(x, y, z):
    	print(x, y, z)
    
    func(*[1, 2, 3])
    func(*(1, 2, 3))
    func(**{"x": 1, "y": 2, "z": 3})
    
    # 实例二
    def func(x, y, z, *args):
    	print(x, y, z)
    	print(args)
    
    func(5, 6, 7, *[1, 2, 3])
    

    创作不易,欢迎打赏,你的鼓励将是我创作的最大动力。

    作者:五月天的尾巴

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python参数详解、python参数类型、位置参数、默认参数、可选参数

    发表回复