一直没怎么搞懂各种参数,看了官方文档后感觉清楚一些了
1.形参和实参的区别
参数分为形参(parameter) 和实参(argument)
Parameters are defined by the names that appear in a function definition, whereas arguments are the values actually passed to a function when calling it. Parameters define what kind of arguments a function can accept. For example, given the function definition:
def func(foo, bar = None, **kwargs):
pass
foo
、 bar
和 kwargs
是 func
的形参。 不过在调用 func
时,例如:
func(42, bar=314, extra = somevar)
42
、 314
和 somevar
则是实参。
2.argument(实参)
在调用函数时传给 function (或 method )的值。argument分为两种:
- keyword argument(关键字参数):
在函数调用中前面带有标识符(例如name =
)或者作为包含在前面带有**
的字典里的值传入。举例来说,3 和 5 在以下对complex()
的调用中均属于关键字参数:
complex(real = 3, imag = 5)
complex(**{'real': 3, 'imag': 5})
- positional argument(位置参数):
不属于关键字参数的参数。位置参数可出现于参数列表的开头以及/或者作为前面带有*
的iterable
里的元素被传入。举例来说,3
和5
在以下调用中均属于位置参数:
complex(3, 5)
complex(*(3, 5))
3.parameter(形参)
function (或方法)定义中的命名实体,它指定函数可以接受的一个 argument (或在某些情况下,多个实参)。有五种形参:
- positional-or-keyword:位置或关键字,指定一个可以作为 位置参数 传入也可以作为 关键字参数 传入的实参。这是默认的形参类型,例如下面的
foo
和bar
:
def func(foo, bar=None): ...
- positional-only:仅限位置,指定一个只能通过位置传入的参数。 仅限位置形参可通过在函数定义的形参列表中它们之后包含一个
/
字符来定义,例如下面的posonly1
和posonly2
:
def func(posonly1, posonly2, /, positional_or_keyword): ...
- keyword-only:仅限关键字,指定一个只能通过关键字传入的参数。仅限关键字形参可通过在函数定义的形参列表中包含单个可变位置形参或者在多个可变位置形参之前放一个
*
来定义,例如下面的kw_only1
和kw_only2
:
def func(arg, *, kw_only1, kw_only2): ...
- var-positional:可变位置,指定可以提供由一个任意数量的位置参数构成的序列(附加在其他形参已接受的位置参数之后)。这种形参可通过在形参名称前加缀
*
来定义,例如下面的args
:
def func(*args, **kwargs): ...
- var-keyword:可变关键字,指定可以提供任意数量的关键字参数(附加在其他形参已接受的关键字参数之后)。这种形参可通过在形参名称前加缀
**
来定义,例如上面的kwargs
。
形参可以同时指定可选和必选参数,也可以为某些可选参数指定默认值。
4.总结
以上是官方文档的分法。
总结一下,其实就两种参数:
positional 和 keyword:
- positional根据位置顺序依次传入,可不定长(前加
*
,对parameter和argument均是如此,以tuple的形式组织多个数据,进行传入和接收),可设为positional-only(后加, \,
隔开) - keyword根据键值传入,可不定长(前加
**
,对parameter和argument均是如此,以dict的形式组织多个数据,进行传入和接收),可设为keyword-only(前加, *,
隔开)
定义或调用 函数/方法时,参数(定义时为parameter,调用时为 argument,这里统称为参数)的顺序是先positional,再keyword,可设置默认值(没设置就是必选参数(意即必须设置的参数),设置了就是可选参数(意即可以选择不去设置它))
举个小栗子
如果调用函数时这样写
def sum(start, end, stride):
res = 0
for i in range(start, end+1, stride):
res += i
return res
print(sum(start = 1, end = 10, 2)) # 1 + 3 + 5 + 7 + 9
表面上好像没问题,但实际运行会发现SyntaxError: positional argument follows keyword argument
发生语法错误,说你错把 positional 放在了 keyword 之后。
修改一下
def sum(start, end, stride):
res = 0
for i in range(start, end+1, stride):
res += i
return res
print(sum(stride = 2, start = 1, end = 10)) # 1 + 3 + 5 + 7 + 9
得到25
,正确运行。
这也说明kerword argument在传入时是不受position限制的。而此处函数中定义的三个parameter,就是属于官方文档中的第一类parameter——positional-or-keyword,具体是什么取决于你怎么传。
ok总算是搞得比较清楚了,喜欢的点个赞,关注一下吧😘