函数即变量

函数在定义的过程中,有一个函数名和函数体,在函数体中定义了函数的功能和对应的返回值,而对于全局来看,函数名是存放在栈区的一个变量名,而函数体代码则是定义在堆区的一个值,函数名和函数体之间还是通过函数名指向函数体的内存地址进行映射引用的,这就好比是声明一个变量x=10,x就是变量的名称,10就是值,还是栈区和堆区之间的映射关系。所以这么来看,函数的定义,就是在全局namespace中定义了一个变量,该变量和其他普通的数据类型变量没有太大的不通,普通数据类型变量指向的是值的内存地址,函数名指向的是函数体代码的内存地址。

变量能够通过传参等方式进行使用,本质上就是将值的内存地址,传递到函数中,作为实际参数进行使用,基于这个原则,函数名也可以做为参数,传递到其他函数中使用,也可以作为某一个函数的返回值,只不过返回的也是一个内存地址。

函数的运行,也就是函数名+()进行运行,如果将函数名作为参数或者是返回值,那么一样的也可以使用这种方式。

比如一个信用卡服务的代码,信用卡有三个功能,注册、付款和转账,首选需要定一个3个函数,分别代表这三个功能,在循环开始时,需要问用户,要使用哪个功能,然后根据用户输入的代码去执行相应的功能,如果功能较少,通过if elseif等方式就能实现,但是如果后续要增加多个这种功能,每次添加都需要修改整个if else功能,维护起来比较费劲。有一种简单的方法,通过字典来实现,字典中key为服务功能编号,值为对应的函数名,用户输入的服务编号只要在字典的key中,直接调用该key对应的值的代码即可,这个地方就可以通过变量---》函数名---》函数调用完美实现。

 

函数参数之不定长度的参数,args和kwargs。

在函数定义过程中,考虑函数的以后扩展性和健壮性,通常函数调用的时候,需要按照函数定义时设置的参数数量进行传参,如果传递的参数的数量多余定义的数量,函数调用就会失败,为了避免后续函数扩展时对所有调用的地方都进行修改,则需要考虑在函数定义的时候,如果函数调用传递的参数数量多与定义的数量,该用什么去存储这些多余的参数,这个时候就出现了args和kwargs。其中args是是相对于函数调用时,多余的位置实参来说的,多余的位置实参,会以元组的形式,组成一个元组,传递到函数中的形式参数*args中,kwargs是相对于关键字参数来说的,组成方式是字典。

 

在函数定义时,args和kwargs作为形式参数,会带上*和**,而在实际使用时,是不用带*的,直接使用args和kwargs这俩变量名即可,其中args是一个元组,kwagrs是一个字典,如果使用*args,则是表示将该元组的内容全部解压释放出来,分解成单个元素使用,例如字典[1,2,3,4]这是一个元素,而*[1,2,3,4]则代表的是1,2,3,4共4个元素,同理,kwargs也可以进行解压打散。

posted @ 2020-10-07 11:27  波波波波波  阅读(356)  评论(0编辑  收藏  举报