2007-07-17

 

Python Cookbook 2.13 使用类C++的流操作语法

需求:

你喜欢C++操作I/O的方式,使用操作符(不同的对象对输入其的数据有不同的处理)来处理,也想在Python这样做.

讨论:

Python允许你重载操作符,通过重写特定的方法(特定方法指那些命名中以两个下划线开始和结束的方法).要使用<<做为输出,就像C++中那样,需要定义一个输出流操作类并定义函数__lshift__:

class IOManipulator(object):
    def _ _init_ _(self, function=None):
        self.function = function
    def do(self, output):
        self.function(output)
def do_endl(stream):
    stream.output.write ('\n')
    stream.output.flush( )
endl = IOManipulator(do_endl)
class OStream(object):
    def _ _init_ _(self, output=None):
        if output is None:
            import sys
            output = sys.stdout
        self.output = output
        self.format = '%s'
    def _ _lshift_ _(self, thing):
        ''' the special method which Python calls when you use the <<
            operator and the left-hand operand is an OStream '''
        if isinstance(thing, IOManipulator):
            thing.do (self)
        else:
            self.output.write(self.format % thing)
            self.format = '%s'
        return self
def example_main( ):
    cout = OStream( )
    cout<< "The average of " << 1 << " and " << 3 << " is " << (1+3)/2 <<endl
# emits The average of 1 and 3 is 4
if _ _name_ _ == '_ _main_ _':
    example_main( )

封装Python的类文件对象来模拟C++操作是比较容易的,本节讲了如果用<<来实现插入操作.本节也实现了一个IOManipulator类(向C++中一样)来实现对流的任意插入操作,也预定义了endl(猜猜从哪里来的?)来实现换行和刷新缓冲区.
在类OStream的实例中,我们保留了一个format属性, 并在每次调用sys.stdout.write后,将其值设置为默认的'%s',这样做是因为你可以构造自己需要的流输出格式,如:

def do_hex(stream):
    stream.format = '%x'
hex = IOManipulator(do_hex)
cout << 23 << ' in hex is ' << hex << 23 << ', and in decimal ' << 23 << endl
# 输出 23 in hex is 17, and in decimal 23

有些人喜欢C++的cout<<something写法,有些人不喜欢.在Python中,我们可以使用更简单和可读的代码:

print>>somewhere, "The average of %d and %d is %f\n" % (1, 3, (1+3)/2)

这是Python方式的写法(和C很像).一切都取决于你更多使用C++还是C.不过无论怎样,本节都给出了选则方案,即使你不会使用本节讨论的内容,也能从其中看到在Python中进行操作符重载是很简单和方便的.

Comments: 发表评论



<< Home

This page is powered by Blogger. Isn't yours?