python可变參数调用函数问题
一直使用python实现一些想法,近期在使用python的过程中出现这样一个需求,定义了一个函数。第一个是普通參数。第二个是默认參数,后面还有可变參数,在最初学习python的时候,都知道非keyword可变參数和keyword可变參数两种,调用的方式或许多种多样,这里主要提出一个比較隐含的问题。并将各种可能出现的情况进行了探讨。
函数声明格式
python尽管不支持函数重载,可是通过对函数參数的众多特性的支持基本弥补了。
函数声明的通式例如以下:
def func(argv1,argv2...[,argv_d = default1,...]\
[,*var_argv][,**var_key_argv])
这是python函数声明的通式。首先是普通參数若干个。也能够没有,接着是带默认值的參数。然后是非keyword可变參数,最后是keyword可变參数。这为python提供的强大函数调用奠定了基础。
函数调用
正是在函数调用的过程中遇到了问题。为了说明。我定义了一个例如以下的函数进行说明:
def f1(a,b=1,*var): print a,'\t',b,'\t',var
def f2(a,b=1,**var): print a,'\t',v,'\t',var
首先普通參数能够使用按位置的方式调用,同一时候能够使用按形參keyword调用。默认值參数也是使用位置方式匹配或者keyword调用。实比例如以下:
这里没有使用后面的可变參数。一切都没有问题。
问题是。本人遇到的一个需求是,默认參数须要就是使用默认值调用。同一时候还有可变參数,并且是非keyword參数,那么调用时就会出现以下的情况:
能够看到,通过非keyword可变參数传入參数之后。python会默认把非keyword可变參数的前面若干个(这里是1个)当做默认參数,这里是由于我没有提供默认參数b的值,正是这个原因,在我的程序中一直没发现。
后来自习思考一下。发现Python解释器做出这种决定还是有一定的道理的,由于非keyword可变參数是默认參数之后的若干个參数。而在调用的时候由于没有传入默认參数的值。Python无法推断究竟从哪里開始是可变參数,因此在没有传入默认參数的值时,就依次从非keyword參数(调用者觉得的)中依照顺序抽取去当做默认參数的值,这从側面论证了非keyword可变參数在python内部是和普通參数默认參数一并处理的。
尽管上述调用有些极端,可是确实会出现这种需求,那么能够使用keyword可变參数进行替换,上述问题就能够攻克了,由于解释器是能够差别keyword參数和默认參数的,调用例如以下:
在使用keyword可变參数时,另一个重要问题就是,keyword參数的键值不能有普通參数或者默认參数的參数名反复,这从側面论证了,python对keyword调用和keyword可变參数在内部都是经过同一个字典保存的,因此不能有反复的键。调用例如以下:
上述遇到的问题是在实际操作过程中遇到的,一般从各种教程、书本学习python都仅仅是说明上述的函数声明和调用的方式。可是差点儿没有这种实际操作中可能遇到的点点滴滴,因此学习不论什么东西最好的方式就动手,这个真理永远不会变啦!
python可变參数调用函数问题的更多相关文章
- OC可变參数的函数实现va_start、va_end、va_list的使用
一.简单介绍 我们常常在编程的时候看见类似这种代码,如图1.1 图1.1 或者是这种可变參数,如图1.2 图1.2 二.基本知识介绍 在学习怎样写这样的格式的函数前,先简介几个经常使用的宏: 下面摘自 ...
- C语言利用va_list、va_start、va_end、va_arg宏定义可变參数的函数
在定义可变參数的函数之前,先来理解一下函数參数的传递原理: 1.函数參数是以栈这样的数据结构来存取的,在函数參数列表中,从右至左依次入栈. 2.參数的内存存放格式:參数的内存地址存放在内存的堆栈段中, ...
- c 语言函数可变參数的处理
/************************************************************************* > File Name: va_list.c ...
- Effective JavaScript Item 22 使用arguments来创建接受可变參数列表的函数
本系列作为Effective JavaScript的读书笔记. 在Item 21中,介绍了结合apply方法实现的可变參数列表函数average,它实际上仅仅声明了一个数组作为參数,可是利用apply ...
- Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表
本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...
- iOS 处理方法中的可变參数
## iOS 处理方法中的可变參数 近期写了一个自己定义的对话框的demo,想模仿系统的UIAlertView的实现方式.对处理可变參数的时候,遇到了小问题,于是谷歌了一下.写下了处理问题的方法.记录 ...
- java 可变參数
我们在某些特定的需求环境下,可能要对某一个方法中的參数进行一些操作,并且这些方法中的參数是不规定的,那么问题来了,我们该怎么办呢? java事实上就为我们考虑了这样的情况,那就是使用可变參数 可变參数 ...
- java之 ------ 可变參数和卫条件
可变參数:适用于參数个数不确定.类型确定的情况,java把可变參数当做数组处理. 可变參数必须位于最后一项.当可变參数个数多于一个时,必将有一个不是最后一项,所以仅仅支持有一个可变參数. 可变參数的书 ...
- Printf可变參数使用
參考文档: http://bbs.csdn.net/topics/70288067 Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源 本文的二 ...
随机推荐
- nutz配置druid监控
druid 提供了一个web端的监控页面, 搭建起来不算麻烦, 建议添加. 打开web.xml, 在nutz的filter之前, 加入Web监控的配置 <filter> <filte ...
- 根据截至日期格式获取倒计时&&时间戳转日期格式
//时间戳转日期格式,传入时间戳必须为数字类型function currentDate(shijianchuo) { var date = new Date(shijianchuo); var y = ...
- JavaSE-17 泛型
学习要点 泛型接口 泛型类 泛型方法 多参数泛型类 泛型类的继承 泛型的定义 允许在定义类.接口.方法时使用类型形参,类型形参将会在声明变量.创建对象或者调用方法时候动态指定. 泛型接口 1 定义 ...
- js 页面图片等元素在普通元素中滚动动态加载技术
/*! * 2012-01-13 v1.1 偏移值计算修改 position → offset * 2012-09-25 v1.2 增加滚动容器参数, 回调参数 * 2015-11-17 v1.3 只 ...
- js 右键菜单
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 网络共享服务器 samba
之前给自己centos 服务器配置了一下samba网络共享,主要是在windwos上编程,然后方便代码同步到linux上进行编译,现在大概记录一下过程,免得下次又忘记了 首先获取root权限 :su ...
- VSCODE插件开发:用户输入输出
阅读这篇文章之前,假设你已经具有开发helloworld的插件的能力. vscode.window 简介 vscode.window 负责当前激活窗口的输入输出,比如展示信息,和用户输入等功能都是用v ...
- Go:数组
package main import "fmt" func main() { // 定义数组的方式 var array1 [3]int array2 := [3]int{} fm ...
- Linux中CentOS网络配置以及与Xshell建立远程连接
为centos配置网络 (1)第一步 点开虚拟机的设置,如下图做相关的设置: 网络连接要选择桥接模式,其他的勾选就按照上图的即可,勾选完成点击确定. (2)第二步 点击VMware的编辑选项,找到“虚 ...
- 树莓派 -- i2c学习
硬件平台 RaspberryPi-3B+ Pioneer600外扩版 i2c芯片为DS3231,adddress 0x68 首先来看一下i2ctool的使用 i2ctool 使用 https://i2 ...