代码改变世界

美妙的Python又来了

2005-06-22 02:08  FantasySoft  阅读(2921)  评论(6编辑  收藏  举报

       今天继续去了解小蟒蛇的可爱特性,在函数定义和调用方面,有三个地方让我觉得蛮有意思的。
       第一个有意思的地方是缺省实参, 也就是在Python中定义函数,你可以为参数设定缺省值(默认值),这个特性在C和C++
中也是有的,但是在Java中却没有,至于C#中有没有,就不清楚了。如下所示:     

def  test(a, b, c=3):
        print a, b, c

        当你调用test函数的时候,你可以这样调用test("abc", "def"), 这样是等价于test("abc", "def", 3)的。在设定参数的缺省值的时候,必须遵循的一个原则就是带缺省值的参数必须要放在没有缺省值的后面,也就是说像def test(a=3, b, c)这样的函数定义是错误的。而这个原则也适用于C和C++。使用缺省参数的好处是显而易见的,如果一个参数在大多数的情况都使用某一个确定的值,你就没有必要在每次函数调用中都不厌其烦的把这个值写了一遍又一遍了。虽然Python在缺省实参的使用上延续了C和C++的规则,但是它仍然有着自己的创新之处。还是上面的test函数,你是可以这样调用的test(c=2, b=4, a=5),是不是很灵活呢?这正好说明了在函数调用的时候,参数与参数值就是一个key/value pair(键值对),而键值对在Python当中就是Dictionary类型,Dictionary类型本身是无序的,那么哪个参数在前,哪个参数在后就无关紧要了。
   
        第二个是随机参数表,也就是你可以定义一个函数,而它不管你传递多少个参数都照单全收。不用惊讶,看看下面简单的代码吧

def test(*arg):
       print arg

你可以这样调用:test(1, 2, 3),也可以这样调用:test("abc", 2, 3, [1, 2, 3])。所有传递给test的实参都会存储在arg这个tuple当中。是不是觉得很特别呢?其实,这也不是什么新鲜的特性了,在C和C++当中可以使用省略号来指定函数参数表,也就是说在C和C++中,你可以定义一个没有参数列表的函数,就像这样void foo(...),而这个函数是可以接收任意多个实参的。也许你从来都没有在C和C++中定义过以省略号作为参数表的函数,但是你一定使用过一个这样使用省略号定义的函数,它就是printf。printf的定义是int printf(const char* ...); 通常你可以这样调用:printf("Hello, world"); 同时也可以这样 printf("Hello, %s", yourName); 第二种调用方式就包含了两个实参,%号代表第二个参数,s则表示参数类型是字符串。
        在随机参数表方面, Python在充分遵循C和C++的原则之余,仍然发挥着其独有的创意。如上所述,由于
可以使用类似test(c=2, b=4, a=5)的调用方式, Python也有一个特殊符号来应对这样的函数调用。如下所示

 def test(**arg):
        print arg

arg实际上就是一个Dictionary,当你这样调用的时候:test(c=2, b=4, a=5),arg的内容就是{'c':2, 'b':4, 'a':5}。
       最后一个就是打包和解包实参。上面所说的两点让函数定义变得更加的简洁和方便,至少你不再需要定义一个带着长长的参数表的函数了。但是这仅是函数定义啊,如果我要向一个函数传递十个参数,不是还要在调用的时候写上一大串吗? 别急,Python是不会顾此失彼的。以第一个定义的test函数为例,它需要至少两个参数,那么我们可以定义一个List或者Tuple,把实参都放到里面去——打包实参。然后在函数调用的时候,通过*号从List或者Tuple中将实参取出来传递给函数——解包实参。如下如示:

def  test(a, b, c=3):
        print a, b, c

args = [2, 4, 5]
test(*args)               # test(*args) 等价于 test(2, 4, 5)

       Python又让我再一次领略到了它的灵活和巧妙,还有汲取百家之长的谦逊。 这些,你感受到了吗?