代码之家  ›  专栏  ›  技术社区  ›  wvxvw

为什么Python中的线性化会产生这种奇怪的结果?

  •  0
  • wvxvw  · 技术社区  · 6 年前

    考虑这种简化的情况:

    class Decoder:
        def __str__(self):
            return self.__bytes__().decode('ascii')
    
    class Comment(Decoder, bytes):
        def __bytes__(self):
            return b'#' + self
    

    用法:

    Comment(b'foo')
    

    打印:

    b'foo'
    

    而不是预期的:

    #foo
    

    无论中的顺序 Comment.mro() (即我可以交换 Decoder bytes 在supeclass列表中), Decoder.__str__() 从未调用。

    有什么好处?

    2 回复  |  直到 6 年前
        1
  •  2
  •   chepner    6 年前

    Comment(b'foo') 呼叫 Comment.__new__ ,未定义,解析为 Decoder.__new__ bytes.__new__ ,具体取决于在定义中列出它们的顺序 Comment

    的MRO 议论 议论 ,则, bytes ,则, Decoder ,则, object 。但是,实际调用的函数有:

    1. 注释__新建__ ,以创建新对象。由于未定义该函数,我们将调用 字节__新建__ ,已定义。它实际上只是调用 object.__new__(Comment, b'foo') ,给你最后的目标。

    2. 陈列 的返回值 议论 ,口译员试图调用 Comment.__repr__ Comment.__str__ 。同样,函数没有定义,因此它会返回到 bytes.__repr__ ,给出观察结果。

        2
  •  0
  •   Ilya Miroshnichenko    6 年前

    如果使用打印功能,则会得到预期的结果,但如果从控制台查看结果,则会看到 __repr__ 方法如果您需要,可以通过这种方式调用 self.__str__() 从…起 __报告__

    >>msg = Comment(b'foo')
    >>msg
    b'foo'
    >>print(msg)  # or str(msg)
    '#foo'
    

    在那里你可以看到它是如何工作的 docs