重载python运算符"<<"作为C ++ iostream

时间:2015-11-08 14:08:03

标签: python iostream operator-keyword

我正在阅读 python cookbook 2nd ,一个样本在&#34; chap 2.13使用C ++ - 就像iostream语法“,我试着理解< em> self 在代码中工作。

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)
# my understanding, all above is about make a newline and flush sys.stdout,

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):
        if isinstance(thing, IOManipulator):
            thing.do(self) 
            # It make no sense to me, why the function belongs to 
            # another class's instance need call (self)
        else:
            self.output.write(self.format % thing)
            self.format = '%s' # <- is it necessary? seems to be not.
        return self  # <- why return a "self" here? 
        # If comment this line out, 
        # python raise a TypeError when execute to the "<< 1"
        # TypeError: unsupported operand type(s) for <<: 'NoneType' and 'int'

def example_main():
    cout = OStream()
    cout << "The average of " << 1 << " and " << 3 << " is " << (1+3)/2 << endl

if __name__ == '__main__':
    example_main()
# emits:
#> The average of 1 and 3 is 2
&#34>自我&#34;是<__main__.OStream object at 0x7fc28cd92410>,我知道它是OStream类的一个实例,也许可以作为C指针。

1 个答案:

答案 0 :(得分:2)

我会回答你在评论中提出的问题:

if isinstance(thing, IOManipulator):
    thing.do(self) 
    # It make no sense to me, why the function belongs to 
    # another class's instance need call (self)

您将self(输出流)传递给thing(这将是IOManipulator,例如endl操作),以便IOManipulator class可以在输出流上执行函数(参见下面的IOManipulator.do)。

def do(self, output):
    self.function(output)

对于最大的混淆,此代码段中的第一个self不是您在self中传递给它的OStream!您传递给self的{​​{1}}设置为thing.do变量。

output

您可以在此处返回return self # <- why return a "self" here? 实例,以便进行连锁操作。请注意,python将行OStream解析为a << b << c(a << b) << c部分需要返回其更新后的自我,以便能够对其进行(a << b)并且有意义。如果您对<< c发表评论,最终会得到return self,因为该函数会返回None << c

None

我不确定作者对此的意图,似乎没必要。行self.format 也可以写为self.output.write(self.format % thing)

作为旁注:这可能是一个如何实现新运算符的示例,但是这个特定的运算符非常非pythonic:它会导致非常丑陋和令人困惑的代码。在现实世界中,尝试使用语言已有的功能。