Python 函数(3)


本篇总结函数参数匹配(argument match)的题目

背景

对此函数的使用者而言,关注点有少数单:
1、函数所提供的接口,即,输入的题目;
2、函数的出口;

输入--->函数--->输出

于函数本身而言,关注点有三个:
1、输入,包括输入的格式、输入的始末、校验等;
2、如何处理输入;
3、提供什么的输出;

输入--->处理--->输出

可见,使用者不体贴函数的处理过程,只关心输入和输出,而函数则非体贴使用者是何人,只关注输入。
那,可以窥见,函数提供输入实际是提供接口,所以函数输入设计的本来面目是接口设计。
如果接口设计还要有何不可分为两有的:形式设计以及情节设计。其中,形式设计应哎呀花样之输入的题目,内容设计则应输入是什么的题目

本篇要讨论的函数参数匹配问题属于形式设计。


好了,形而上的摆了平等堆积物,下面开始正题。

1. 参数匹配

率先来只C++的例子:
而,有函数如下:

int  record( string name, unsigned int age, string email)
{
     // 处理过程
      return 0;
}

欠函数所提供的接口也 string name, unsigned int age, string email
这就是说只要下例,使用函数:

record("Joe", 20, "Joe@email.com");    // 正确形式
record(20, "Joe", "Joe@email.com");    // 错误形式
record("Joe@email.com", 20, "Joe");    // 语法正确,但是内容错误

当使用 record(20, "Joe", "Joe@email.com");
会出现谬误。如果采用IDE那么,这里会见提示错误信息;如果未是利用IDE,那么以编译时,也会生照应的错误信息提示。错误的缘由是数据类型不般配

也就是说,在C++中,参数的相当时是依照顺序来进展的。即:
string name = "Jone"unsigned int age = 20string email = "Joe@email.com"
对静态强类型语言,当出现string name = 20的相当时,就见面现出数据类型不匹配的左(不考虑模板的状况)。

差不多,常见的编程语言,函数的默认参数匹配方式都采用各个匹配方式。Python也无差。但是Python也供了其它的参数匹配方式:
岗位匹配(顺序匹配<默认使用这种方法>)
要字相当
默认值
但变换参数

2. 职匹配

Python的职务匹配实例如下:

# 函数定义
>>> def record(name, age, email):
...     record_name = name
...     record_age  = age
...     record_email= email
... 
# 函数使用
>>> record('Joe', 20, 'Joe@email.com')    #
>>> record(20, 'Joe', 'Joe@email.com')      #形式正确,内容错误

对动态语言,上例被第二种调用,并从未路不般配的题材。只是情失实而已。由此也引出了第一字相当

3. 要害字相当

在上述例子中第二种植调用方式因此会出现问题,原因在:
是因为使用职务匹配,所以为了保险输入内容对,调用时,必须清楚参数的职务(或者顺序)。
使用关键字相当就非有这种题材。
抑或事先押例子:

# 函数定义
>>> def record(name, age, email):
...     record_name = name
...     record_age  = age
...     record_email= email
... 
# 函数使用
>>> record(name = 'Joe', age = 20, email = 'Joe@email.com')    #
>>> record(age = 20, name = 'Joe', email = 'Joe@email.com')    #

足见到,要害字相当职位匹配的极端特别区别在于:关键字相当,在调用函数时,加入了真切参与形参的附和信息。
这样做的益处在叫,调用者只需要明白调用时欲输入的参数名称即可,不用理会该顺序。另外,从语义的角度来拘禁,这种办法在发挥上为愈分明,因为调用时,十分理解的描绘清楚了:
age = 20name = 'Joe'email = 'Joe@email.com'
程序的可读性非常大。

4. 默认值

对函数的调用者而言,调用时所要的参数越少,意味着使用起来吧愈来愈简单。但是,有时候,为了功能的灵巧,同时用保留足够的准备参数。这些预备参数需要出以下特征:

  1. 如调用时不设定,则为默认值;
  2. 设调用时设定,则利用设定值;

如此,使得函数的易用性与灵活性同时得到保险。默认值参数哪怕落实了这样的效力。
举例:

>>> def record(name, age, email="xxx@email.com"):
...     print name, age, email
... 
>>> record('Joe', 20, 'Joe@gmail.com')
Joe 20 Joe@gmail.com
>>> record('Joe', 20)                 
Joe 20 xxx@email.com

5. 可是转换参数

为何要而换参数

假若现在急需如此一个函数:输入两个字符串,输出两单字符串拼起来的字符串。

>>> def str_add(str1, str2):
...     return str1 + str2
... 
>>> str_add("I am ", "Joe ")
'I am Joe '

输入两独字符串的例证很轻实现,那么问题来了… ….
万一要求输入3个字符串呢?4单?5只?…
…总不可知一个函数一个函数的描写下来吧。

小结一下,很爱发觉无论是输入是几单字符串,所犯的操作都是拿所输入的字符串拼起来。这个上,可易参数就派上用场了。
优先看例子:

>>> def str_add(*str):                        # 定义可变参数
...     print reduce(lambda x,y:x+y,str)      # 将str中的所有变量相加
... 
>>> str_add("I am ", "Joe")
I am Joe
>>> str_add("I am ", "Joe, ","my email is ","Joe@gmail.com")
I am Joe, my email is Joe@gmail.com
>>> 

达成例被,采用可转换参数的函数str_add好支持不肯定个数的字符串输入,输出这些字符串拼接之后的字符串。

由此可见:
唯独易参数的意义在,能够使函数处理参数不必然,操作有共性的需求。而所谓的然而换参数举凡赖,参数的个数是可以变的。

概念可变换参数
自办明白怎么而动用可易参数后,我们来说一下点的事例中凡是如何定义可变换参数的。
率先,我们应用Tuple可以实现一个功效跟可变参数相同的函数。

>>> def str_add(str):
...     print reduce(lambda x,y:x+y, str)
... 
>>> words = ("I am ", "Joe")     #创建一个Tuple对象
>>> str_add(words)
I am Joe

相对而言这个事例和上面的事例可以发现,在本例中,需要超前布局一个Tuple对象,然后再用这目标传入函数。
实质上,上等同节约之例子中str_add函数内部 *str接过到吗是Tuple对象。

在Python中如果List对象或者Tuple目标下*来修饰作为实参传入函数时,会以那个化可变参数列表传入函数。
按照下面的例子:

>>> def str_add(*str):
...      print reduce(lambda x,y:x+y,str)
... 
>>> words = ("I am ", "Joe")
>>> str_add(*words)              #在Tuple对象words前加*作为实参传入函数
I am Joe

然转换参数在形式上有三三两两种:

  1. 对于List对象或者Tuple对象,在变量前加*
  2. 对于Dict对象,在变量前加**

在Python中称加*的变量为Non-keyword Variable
Arguments
,称加**的变量为keyword Variable Arguments

脚为起一个可换参数使用的整例子

>>> def foo(name, age, *args, **kwargs):
...     print name, age, args, kwargs
... 
>>> info = ["Joe@gmail.com","male"]
>>> addition = {"location":"Beijing","prof":"software"}
>>> foo("Joe",20, *info, **addition)        #List对象info前加*,Dict对象addition前加**
Joe 20 ('Joe@gmail.com', 'male') {'prof': 'software', 'location': 'Beijing'}
>>> foo("Joe",20, "Joe@gmail.com","male",location="Beijing",prof="software")    
Joe 20 ('Joe@gmail.com', 'male') {'prof': 'software', 'location': 'Beijing'}

总一下:
Python的函数参数匹配提供了多计,非常灵活,使用的时节就是可以单独行使有平栽方式,也可以混使用多种办法。