Python:函数调用的实参

news/2024/11/19 18:19:34/

相关阅读

Python专栏icon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12403403.html


        调用就是附带可能为空的一系列参数来执行一个可调用对象 (例如函数),它的语法的BNF范式如下所示,有关BNF范式的规则,可以参考之前的文章。

call                 ::=  primary "(" [argument_list [","] | comprehension] ")"
argument_list        ::=  positional_arguments ["," starred_and_keywords]["," keywords_arguments]| starred_and_keywords ["," keywords_arguments]| keywords_arguments
positional_arguments ::=  positional_item ("," positional_item)*
positional_item      ::=  assignment_expression | "*" expression
starred_and_keywords ::=  ("*" expression | keyword_item)("," "*" expression | "," keyword_item)*
keywords_arguments   ::=  (keyword_item | "**" expression)("," keyword_item | "," "**" expression)*
keyword_item         ::=  identifier "=" expression

        其中,primary是原型,代表编程语言中最紧密绑定的操作,它的具体可以为几种形式,可以是一个简单的函数名标识符。原型必须求值为一个可调用对象(用户定义的函数,内置函数,内置对象的方法,类对象,类实例的方法以及任何具有 __call__() 方法的对象都是可调用对象)。 所有参数表达式将在尝试调用前被求值。

        参数列表是用()包围的可选项,可以是argument_list也可以是一个生成器推导式。常用的是argument_list,它可以有三种情况:

        第一种是位置实参列表,后面是可选的加*实参和关键词实参列表,最后是可选的加**实参和关键词实参列表。

        第二种是加*实参和关键词实参列表,后面是可选的加**实参和关键词实参列表。

        第三种是只有加**实参和关键词实参列表。

        一个可选项为在位置和关键字参数后加上逗号而不影响语义。

        如果存在关键字实参,它们会先通过以下操作被转换为位置实参。首先,为形式参数创建一个未填充空位的表。 如果有N个位置实参,则它们会被放入前N个空位。 然后,对于每个关键字实参,使用标识符来确定其对应的空位(如果标识符与第一个形式参数名相同则使用第一个空位,依此类推)。 如果空位已被填充,则会引发TypeError异常。否则,将实参值放入空位,进行填充(即使表达式为None,它也会填充空位)。当所有实际参数处理完毕时,尚未填充的空位将用来自函数定义的相应默认值来填充。(函数一旦被定义,其默认值就会被计算;因此,当列表或字典这类可变对象被用作默认值时将会被所有未指定相应空位参数值的调用所共享;这种情况通常应当被避免。)如果任何一个未填充空位没有指定默认值,则会引发TypeError异常。在其他情况下,已填充空位的列表会被作为调用的形式参数列表。

        如果任何关键字实参没有与之对应的形式参数名称,将会引发TypeError异常,除非有一个形式参数使用了**expression句法,该形式参数将接受一个包含了多余关键字实参的字典(使用关键字作为键而参数值作为与键对应的值),如果没有多余关键字实参,则它为一个(新的)空字典。

        如果函数调用中出现了*expression句法,expression必须求值为一个的迭代类型。 来自该可迭代对象的元素会被当作解析为位置实参。 对于f(x1, x2, *y, x3, x4)调用,如果y求值为一个序列y1, y2, ..., ym,则它就等价于一个带有M+4个位置参数f(x1, x2, *y, x3, x4)的调用。

        这样做的一个后果是虽然*expression句法可能出现于显式的关键字实参之后,但它会在关键字参数(以及任何**expression参数 -- 见下文)之前被处理为位置实参。 因此:

def f(a, b):print(a, b)f(b=1, *(2,)) # 一般情况下,位置参数不能在关键词参数后,但由*中解析的位置参数除外
输出:2 1     # 2会被解包并作为位置实参填充形参af(a=1, *(2,)) # 2被解包并作为位置实参填充形参a,之后关键词实参a=1又填充了a,因此报错
输出:Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: f() got multiple values for keyword argument 'a'f(1, *(2,))
输出:1 2


http://www.ppmy.cn/news/1112866.html

相关文章

TypeScript基础内容(1)

目录 一&#xff1a;TypeScript 变量声明 类型断言&#xff08;Type Assertion&#xff09; TypeScript 是怎么确定单个断言是否足够 类型推断 变量作用域 二&#xff1a;TypeScript 运算符 算术运算符 关系运算符 逻辑运算符 短路运算符(&& 与 ||) 位运算符…

KMP算法(C++)

KMP算法与BF算法不一样的在于&#xff0c;当主串与子串不匹配时&#xff0c;主串不回溯&#xff0c;选择了子串回溯&#xff0c;大大提高了运算效率。 借用了next1【】数组&#xff0c;让子串回溯。get_next函数求next1【】数组&#xff0c;get_next函数的实现难点在于下列几行…

[C++基础] 变量、关键字、运算符、位操作篇

一、变量篇 1 全局变量和静态变量有什么异同&#xff1f; 相同&#xff1a;都在静态存储区分配空间&#xff0c;生命周期与程序生命周期相同。 **区别&#xff1a;**全局变量的作用域是整个程序&#xff0c;它只需要在一个源文件中定义&#xff0c;就可以作用于所有的源文件。…

HTML <video> 标签

实例 一段简单的 HTML5 视频: <video src="movie.ogg" controls="controls"> 您的浏览器不支持 video 标签。 </video>定义和用法 <video> 标签定义视频,比如电影片段或其他视频流。 浏览器支持 元素ChromeIEFirefoxSafariOpera&l…

linux安装常见的中间件和数据库

文章目录 一、数据库二、redis三、tomcat四、nginx五、mq六、es七、nacos八、neo4j&#xff08;图数据库&#xff09;九、fastdfs其他 一、数据库 linux环境上使用压缩包安装mysql【数据库】Mysql 创建用户与授权 二、redis redis是没有账号的&#xff0c;只能设置密码Linux…

python经典百题之寻找完数

题目&#xff1a;一个数如果恰好等于它的因子之和&#xff0c;这个数就称为“完数”。例如61&#xff0b;2&#xff0b;3.编程 找出1000以内的所有完数。 方法一&#xff1a; 思路&#xff1a;利用两个循环分别枚举每个数和它的因子&#xff0c;如果发现一个数的因子之和等于…

repo 命令

repo命令是Google开发的用于管理Android版本库的一个工具。 repo命令并不是用于取代git&#xff0c;而是用Python对git进行了一定的封装&#xff0c;简化了对多个Git版本库的管理。 repo init -u -b -m <manifest 文件名称> repo sync 相当于 git clone 获取 git remote…

第27节——useMemo

一、概念 useMemo 是 React 中的一个钩子&#xff0c;它可以帮助你避免在不必要的情况下重新渲染组件。它通过对比当前状态和前一个状态&#xff0c;决定是否重新计算或记忆一个值。 接收两个参数&#xff0c;第一个参数是个函数&#xff0c;第二个是依赖项。返回一个****mem…