1. 程式人生 > >【再回首Python之美】【類-特殊方法】__str__()和__repr__()的區別和重寫覆蓋

【再回首Python之美】【類-特殊方法】__str__()和__repr__()的區別和重寫覆蓋

注:使用方法直接跳看:使用總結

__str__(self)和__repr__(self)是類的特殊方法,和類的__init__(self)類似,都是可以重寫覆蓋的。

6種使用方法

            >>>f

            >>>f.__repr__()

            >>>f.__str__()

            >>>print f

            >>>print f.__repr__()

            >>>print f.__str__()

區別和結果總結:

    1)一個普通的類

        上面幾種方法的結果輸出一樣:都是類物件的地址資訊。

        詳見下面RoundFloat_com類

    2)只重寫覆蓋了__repr__()的類

        上面幾種方法的結果輸出一樣:都是呼叫重寫的__repr__()

        詳見下面RoundFloat_override_repr類

    3)只重寫覆蓋了__str__()的類

         上面幾種方法的結果輸出有兩類:一個是類物件地址資訊和呼叫重寫的__str__() 

        >>> f,>>> f.__repr__(),>>> print f.__repr__()這三個輸出類物件的地址資訊

        >>>f.__str__(),>>>print f,>>>print f.__str__()這三個呼叫重寫的__str__()

         詳見下面RoundFloat_override_str類

     4)同時重寫了__repr__()和__str__()的類

         上面幾種方法的結果輸有兩類:一個是呼叫重寫的__repr__(),一個是呼叫重寫的__str__()

         >>> f,>>> f.__repr__(),>>> print f.__repr__()呼叫重寫的__repr__()

         >>> f.__str__(),>>> print f,>>> print f.__str__()呼叫重寫的__str__()

         詳見下面RoundFloat_override_both類

結果:

       >>>f                         優先呼叫順序:重寫的__repr__()--->預設的__repr__()。

       >>>f.__repr__()         優先呼叫順序:重寫的__repr__()--->預設的__repr__()。

       >>>print f.__repr__() 優先呼叫順序:重寫的__repr__()--->預設的__repr__()。


       >>>print f                優先呼叫順序:重寫的__str__()--->重寫的__repr___()--->預設的__str__()。

       >>>f.__str__()            優先呼叫順序:重寫的__str__()--->重寫的__repr__()--->預設的__str__()。

       >>>print f.__str__()    優先呼叫順序:重寫的__str__()--->重寫的__repr__()--->預設的__str__()。

根據以上關係可知,得到以下關係:

        >>>f

        >>>f.__repr__()

        >>>print f.__repr__()            這三個只和__repr__()相關

        >>>print f、

        >>>f.__str__()、

        >>>print f.__str__()               這三個和__str__()、__repr__()相關,呼叫時優先考慮重寫的__str__()

使用總結:

    只重寫__str__()並設定__repr__ = __str__,就可以保證上面使用方法的結果都是呼叫重寫的__str__()。

>>> 
>>> class RoundFloat_override_str_reset_repr(object):
    def __init__(self, value):
        try:
            assert isinstance(value, float), "Value must be a float."
            self.value = round(value,2)
        except:
            print "param error!"
    def __str__(self):
        return 'invoke __str__():%f' % self.value

    __repr__ = __str__

    
>>> f = RoundFloat_override_str_reset_repr(8.8888)
>>> f
invoke __str__():8.890000
>>> f.__repr__()
'invoke __str__():8.890000'
>>> f.__str__()
'invoke __str__():8.890000'
>>> print f
invoke __str__():8.890000
>>> print f.__repr__()
invoke __str__():8.890000
>>> print f.__str__()
invoke __str__():8.890000
>>> 

Python Shell端測試結果

>>> 
>>> class RoundFloat_com(object):
    def __init__(self, value):
        try:
            assert isinstance(value, float), "Value must be a float."
            self.value = round(value, 2)
        except:
            print "param error!"

>>> f = RoundFloat_com(1.666)
>>> f
<__main__.RoundFloat_com object at 0x0000000002D60400>
>>> f.__repr__()
'<__main__.RoundFloat_com object at 0x0000000002D60400>'
>>> f.__str__()
'<__main__.RoundFloat_com object at 0x0000000002D60400>'
>>> print f
<__main__.RoundFloat_com object at 0x0000000002D60400>
>>> print f.__repr__()
<__main__.RoundFloat_com object at 0x0000000002D60400>
>>> print f.__str__()
<__main__.RoundFloat_com object at 0x0000000002D60400>
>>> 
>>> 
>>>  
>>> 
>>> 
>>> class RoundFloat_override_repr(object):
    def __init__(self, value):
        try:
            assert isinstance(value, float), "Value must be a float."
            self.value = round(value, 2)
        except:
            print "param error!"
    def __repr__(self):
        return 'invoke __repr__() %f' % self.value

>>> f = RoundFloat_override_repr(2.666)
>>> f
invoke __repr__() 2.670000
>>> print f
invoke __repr__() 2.670000
>>> f.__repr__()
'invoke __repr__() 2.670000'
>>> f.__str__()
'invoke __repr__() 2.670000'
>>> print f
invoke __repr__() 2.670000
>>> print f.__repr__()
invoke __repr__() 2.670000
>>> print f.__str__()
invoke __repr__() 2.670000
>>> 
>>> 
>>> 
>>> 
>>>  
>>> class RoundFloat_override_str(object):
    def __init__(self, value):
        try:
            assert isinstance(value, float), "Value must be a float."
            self.value = round(value, 2)
        except:
            print "param error!"
    def __str__(self):
        return 'invoke __str__():%f' % self.value

>>> f = RoundFloat_override_str(3.666)
>>> f
<__main__.RoundFloat_override_str object at 0x0000000002D60518>
>>> print f
invoke __str__():3.670000
>>> f.__repr__()
'<__main__.RoundFloat_override_str object at 0x0000000002D60518>'
>>> f.__str__()
'invoke __str__():3.670000'
>>> print f
invoke __str__():3.670000
>>> print f.__repr__()
<__main__.RoundFloat_override_str object at 0x0000000002D60518>
>>> print f.__str__()
invoke __str__():3.670000
>>> 
>>> 
>>> 
>>> 
>>> 
>>> class RoundFloat_override_both(object):
    def __init__(self, value):
        try:
            assert isinstance(value, float), "Value must be a float."
            self.value = round(value,2)
        except:
            print "param error!"
    def __repr__(self):
        return 'invoke __repr__():%f' % self.value
    def __str__(self):
        return 'invoke __str__():%f' % self.value

>>> f = RoundFloat_override_both(4.666)
>>> f
invoke __repr__():4.670000
>>> print f
invoke __str__():4.670000
>>> f.__repr__()
'invoke __repr__():4.670000'
>>> f.__str__()
'invoke __str__():4.670000'
>>> print f
invoke __str__():4.670000
>>> print f.__repr__()
invoke __repr__():4.670000
>>> print f.__str__()
invoke __str__():4.670000
>>> 
>>> 
>>> 
>>> 
>>> 

(end)