用python的内置函数print时,大家会发现它是支持任意多个参数,也就是说,print的调用参数是不固定的。例如:
print "你好"
print "我是",name
print "现在是", time , " 你在干什么呢", name , "!"
这得益与python的“可变参数”,在Python里,可以使用*和**来设置可变参数,它们的区别是*传递一个参数元组,**传递一个参数字典,二者可以同时混合使用。混合使用时要加些小心,因为python中他们的次序是重要的。参数归为4类,不是所有的类别都需要。他们必须按下面的次序定义,不用的可以跳过。
1)必须的参数
2)可选的参数
3)过量的位置参数
4)过量的关键字参数
def funName(a, b=None, *c, **d):
这个次序是必须的,因为*args和**kwargs只接受那些没有放进来的其他任何参数。没有这个次序,当你调用一个带有位置参数的函数,python就不知道哪个值是已声明参数想要的,也不知道哪个被作为过量参数对待。
也要注意的是,当函数能接受许多必须的参数和可选的参数,那它只要定义一个过量的参数类型即可。看下面的例子:
代码如下 | 复制代码 |
def add(a, b, c): return a + b + c >>> add(1, 2, 3) 6 >>> add(a=4, b=5, c=6) 15 >>> args = (2, 3) >>> add(1, *args) 6 >>> kwargs={'b': 8, 'c': 9} >>> add(a=7, **kwargs) 24 >>> add(a=7, *args) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: add() got multiple values for keyword argument 'a' >>> add(1, 2, a=7) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: add() got multiple values for keyword argument 'a' |
注意这个例子的最后几行,特别留意当传递一个元组作为可变参数时,是否要显式的传递关键字参数。因为python使用次序规则来扩展过量的参数,那位置参数要放在前面。这个例子中,最后两个调用是相同的,python不能决定那个值是给a的。
下面举一个例子来模仿print的实现:
代码如下 | 复制代码 |
>>> import sys >>> def myprint(*argv): sys.stdout.write(" ".join([str(i) for i in argv]) + "n") >>> print "I believe", 2012, "is the end of the world." I believe 2012 is the end of the world. >>> myprint("I believe", 2012, "is the end of the world.") I believe 2012 is the end of the world. >>> print "tuple:", (1, 2, 3), "list:", [1, 2, 3], "dict:", {"begin":-2012, "end":2012} tuple: (1, 2, 3) list: [1, 2, 3] dict: {'begin': -2012, 'end': 2012} >>> myprint("tuple:", (1, 2, 3), "list:", [1, 2, 3], "dict:", {"begin":-2012, "end":2012}) tuple: (1, 2, 3) list: [1, 2, 3] dict: {'begin': -2012, 'end': 2012} |
print默认是输出到stdout中,在终端运行的程序,无重定向的情况下,print输出到控制台。如果要做代码里实现把print的输出写入到log文件中,可以通过修改stdout的文件对象来实现。同理,重定位标准输入和标准错误输出分别修改stdin和stderr的文件对象即可。
下面的例子捕捉所有print的输出,让输出的每一行前增加一个时间的显示:
代码如下 | 复制代码 |
import sys, time |