相关阅读
Python专栏https://blog.csdn.net/weixin_45791458/category_12403403.html?spm=1001.2014.3001.5482
函数定义就是定义一个用户自定义的函数对象,它的语法的BNF范式如下所示,有关BNF范式的规则,可以参考之前的文章。
funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")"
["->" expression] ":" suite
decorators ::= decorator+
decorator ::= "@" assignment_expression NEWLINE
parameter_list ::= defparameter ("," defparameter)* "," "/" ["," [parameter_list_no_posonly]]
| parameter_list_no_posonly
parameter_list_no_posonly ::= defparameter ("," defparameter)* ["," [parameter_list_starargs]]
| parameter_list_starargs
parameter_list_starargs ::= "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]]
| "**" parameter [","]
parameter ::= identifier [":" expression]
defparameter ::= parameter ["=" expression]
funcname ::= identifier
函数定义是一个可执行语句。它的执行将当前本地命名空间中的函数名绑定到一个函数对象(该函数的可执行代码的包装器)。此函数对象包含对当前全局命名空间的引用,作为调用函数时要使用的全局命名空间。
其中参数列表的第一种情况是由/分隔的两部分,其中前半部分是至少一个可以带默认值的形参,被称作defparameter,但它们有位置实参限制,即只能使用位置传递参数,后半部分是无位置限制的参数列表。在另一种情况下,参数列表也可以只有无位置限制的参数列表。
无位置限制的参数列表的第一种情况是,至少一个defparameter和后面的带星参数列表。在另一种情况下,参数列表也可以只有带星参数列表。
带星参数列表的第一种情况是,一个"*"加可选的带单星形参,后面有若干个defparameter,在这之后,还可以有一个"**"加带双星形参。在另一种情况下,参数列表也可以只有一个"**"加带双星形参。带单星形参和带双星形参不能给予默认值,它们分别被用来接收多余的位置实参和关键词实参。
注意,以上说的形参都是用逗号分隔的,且参数列表的最后可以加一个逗号。此外,如果一个形参具有默认值,则后续所有在形参列表中第一个"*" 或 "**" 之前的形参也必须具有默认值 --- 这个句法限制并未在语法中明确表达。(当后面不存在"*" 或 "**" 时,则所有后面的形参也必须具有默认值)。*之后的形参只能通过关键词实参传入,与/前的情况相反。
下面列出了几种合法的函数定义。
def fun(a, b, c=1, d=0):
pass # c和d有默认值
def fun(a, b, /, c=1, d=0):
pass # a和b只能通过位置实参传入,c和d有默认值
def fun(a, b, c, d):
pass
def fun(a, b, /, c, d):
pass # a和b只能通过位置实参传入
def fun(a, b, *c, **d):
pass # c和d用来接收多余的位置实参和关键词实参
def fun(a, b, /, *c, **d):
pass # a和b只能通过位置实参传入,c和d用来接收多余的位置实参和关键词实参
def fun(a, b, *c, d, **e):
pass # 带*参数后可以有若干个形参,d只能通过关键词传入,c和d用来接收多余的位置实参和关键词
# 实参
def fun(a=1, b=0, /, *c, **d):
pass # a和b只能通过位置实参传入,且有默认值,c和d用来接收多余的位置实参和关键词实参
def fun(a, b=1, *c, d, **e):
pass # d只能通过关键词传入,且不必须有默认值
def fun(a, b, **d):
pass # d用来接收多余的关键词实参
def fun(a, b, *c, d=1, **e):
pass # 带*参数后可以有若干个形参,d只能通过关键词传入且有默认值,c和d用来接收多余的位
# 置实参和关键词实参
def fun(a, b, *c, d=1, f, **e):
pass # 带*参数后可以有若干个形参,d只能通过关键词传入且有默认值,f只能通过关键词传入
#(这里可以没有默认值,因为是第二个*或**,c和d用来接收多余的位置实参和关键词实参