使用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
class MyOutput():
def __init__(self, fd):
self.formatTime()
self.out = fd
self.newLine = True
def formatTime(self):
return time.strftime("%H:%M:%S ", time.localtime())
def write(self, s):
if self.newLine:
self.out.write(self.formatTime())
self.newLine = False
self.out.write(s)
if s.endswith("\n"):
self.newLine = True
def flush(self):
self.out.flush()
sys.stdout = MyOutput(sys.stdout)
print "Program begin."
mylist = [5, 4, 3, 2, 1]
print "prev: ", mylist
mylist.sort()
print "after: ", mylist
time.sleep(3)
print "Program end."
运行效果如下图:
本文部分内容来源于:
http://xiaoxia.org/?p=4270