欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python学习笔记--函数参数的详解

程序员文章站 2024-03-23 19:22:16
...

前言

def add(a, b):
    return a + b

定义一个函数,之后去调用他,可以发现调用的时候传入的参数个数需要和定义的时候匹配,如果不匹配就会报错,无论时参数多了还是少了。

位置参数

>>> def add(a, b):
...     ret = a + b
...     print('{} + {}'.format(a, b, ret))
...     return ret
...
>>> add(1,2)
1 + 2
3

在里可以发现format拼接字段里面,如果时通过format的位置参数传递进来,参数数量不够并不会报错。而函数如果缺少的话就会报错。

在定义函数的时候,在函数里加入的参数就是叫做位置参数。即是按照位置来传入参数。

关键字参数

  • 定义
    若是通过指定关键字传递,参数按照定义时的变量名传递,我们叫做关键字参数
    关键字参数和顺序无关,可以跳来跳去的传参
    位置参数和关键字参数可以混合使用,这里就和format有点像。
>>> def strC(a, b):
...     print('{} + {}'.format(a, b))
...     print('{} + {}'.format('renren', b))
...
>>> a = '人人'
>>> b = 'python'
>>> strC(a,b)
人人 + python
renren + python
  • 限制
    位置参数必须在前面
    因为先传关键字参数会使位置信息混乱。

参数默认值

  • 定义
    定义一个累加函数,base是基数,x是累加数:
>>> def inc(base, x):
...     return base + x
...
>>> inc(3, 1)
4
>>> inc(30, 1)
31

如上每次都加1,如果将1写入函数中就会变成每次都默认加1。但是这个x又希望是可变的,就可以给一个默认值,如下:

>>> def inc(base, x=1):
...     return base + x
...
>>> inc(30)
31
>>> inc(30,2)
32

这里x=1,所赋的值便叫做参数默认值。
参数可以有默认值,当一个参数有默认值时,调用时如果不传递此参数,会使用默认值

  • 限制
    默认值也是有限制的:
>>> def add(x=0, y):
...     return x + y
...
  File "<stdin>", line 1
SyntaxError: non-default argument follows default argument

带默认值的参数必须在不带默认值的参数之后

  • 应用
    对于账户登录等一些不需要经常改变的值使用默认参数就会非常方便了。
    默认参数的意义:定义了一些平时经常使用的参数,调用的时候可以方便的操作。

可变参数

  • 可变位置参数
    先看下format:
>>> '{} {} {} {}'.format(1, 2, 3, 4)
'1 2 3 4'

如果现在需要定义一个求和函数,而这个函数的需求会经常发生变化,参数个数不固定会是一件很麻烦的事。

def sum(x, y):
    return x + y

def sum(x, y, z):
    return x + y + z

这种情况下,可以将参数变成一个list,然后在函数里循环这个list

>>> def sum(lst):
...     ret = 0
...     for x in lst:
...         ret += x
...     return ret
...
>>> sum([1, 2, 3])
6

这样子还是会有一点繁琐,为了更加的方便可以在lst参数前面放一个星号*:

>>> def sum(*lst):
...     print(type(lst))
...     ret = 0
...     for x in lst:
...         ret += x
...     return ret
...
>>> sum(1, 2, 3, 4)
<class 'tuple'>
10

参数前加一个星号,表示这个参数是可变的,也就是可以接受任意多个参数,这些参数将构成一个元组。这样子的参数我们就叫可变位置参数。此时只能通过位置参数传参。

  • 可变关键字参数
>>> def connect(**kwargs):
...     print(type(kwargs))
...     print(kwargs)
...
>>> connect(host='127.168.000.1',port=3306)
<class 'dict'>
{'host': '127.168.000.1', 'port': 3306}

如上,当我们在参数前加了2个星号会得到一个字典,表示这个参数是可变的,可以接受任意多个参数,此时只能通过关键字参数传参。

  • 小结
    所以,可变参数有两种形式:

    • 位置可变参数
    • 关键字可变参数

    区别是什么呢?

    • 位置可变参数
      参数名前加一个星号,参数构成一个元组,传参只能以位置参数的形式
    • 关键字可变参数
      参数名前加两个星号,参数构成一个字典,传参只能以关键字参数的形式
    • 此外,这两种也是可以同时存在的。
>>> def fn(*args, **kwargs):
...     print(args)
...     print(kwargs)
...
>>> fn(1,2,3,a='a',b='b')
(1, 2, 3)
{'a': 'a', 'b': 'b'}
  • 限制
    但是这些都是有限制的,当位置可变参数和关键字可变参数一起使用时,可变位置参数必须在前面。普通参数可以和可变参数一起使用,但是传参的时候必须匹配
#普通参数可以和可变参数一起使用
>>> def fn(x, y, *args, **kwargs):
...     print(x)
...     print(y)
...     print(args)
...     print(kwargs)
...
>>> fn(2, 3)
2
3
()
{}
#如下x是普通变量,在第一个位置参数的时候已经传递了,
#后面通过关键字参数传递的时候解释器就不知道应该给谁了
>>> fn(2, 3, 4, 5,x=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: fn() got multiple values for argument 'x'
#普通参数可以和可变参数一起使用,但是传参的时候必须匹配

位置可变参数可以在普通参数之前,但是在位置可变参数之后的普通参数变成了keyword-only参数
keyword-only参数就是必须要用关键字方式传递

def fn(**kwargs, x):
    print(x)
    print(kwargs)
#当这样写时会直接报错,是不允许的。
#关键字可变参数是不允许在普通参数之前的

再来看一下默认参数和可变位置参数的组合:

>>> def fn(x=5, *args):
...     print(x)
...     print(args)
...
>>> fn(1, 2, 3, 4)
1
(2, 3, 4)
>>> fn()
5
()

这是被允许的,但是只要传入与参数,默认值就会失效。

将默认值参数和可变位置参数调换顺序后结果如下:

>>> def fn(*args, x=5):
...     print(x)
...     print(args)
...
>>> fn(1, 2, 3, 4)
5
(1, 2, 3, 4)
#这里可发现默认值将不会被改变。参数全进入了可变位置参数中。

依次类推都可以去尝试一下。

  • 小结
    通常来说:

    • 默认参数靠后
    • 可变参数靠后
    • 默认参数和可变参数不同时出现

小结

可以说是对python函数的参数应用产生了很多不一样的看法,感到害怕,但是仔细看过之后发现,掌握一些比较实用的即可。