Effective Python – 例75 – 在debug時輸出repr字串

使用print()時通常是輸出所謂human readable字串,但有時會反而會造成困擾

print(5)
#5
print('5')
#5

int_value = 5
str_value = '5'
print(f'{int_value} == {str_value} ?')
#5 == 5 ?

我們可能分不清這個變數是字串’5’還是數值「5」。

另外有些字元可能不是printable,故print會看不到東西。

這時候可以改用rerp(),會改成所謂的printable representation的輸出。

a = '\x07'
print(a)
#
print(repr(a))
#'\x07'

Python有一個eval()可以把representation轉回成變數,但要知道eval()很容易造成問題,不該輕易使用。

b = eval(repr(a))
assert a == b

print(repr(5))
#5
print(repr('5'))
#'5'
print(f'{int_value}r != {str_value}r')
#5r != 5r

一些自訂的object預設的print()輸出可能會不如預期

class OpaqueClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y


obj = OpaqueClass(1, 'foo')
print(obj)

<main.OpaqueClass object at 0x037C9088>

我們可以用__repr__來設計repr()的預設行為,另外format string也可以用{}r來輸出
printable representation

class BetterClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return f'BetterClass({self.x!r}, {self.y!r})'


obj = BetterClass(2, 'bar')
print(obj)

BetterClass(2, ‘bar’)

class BetterClass2:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return f'BetterClass2({self.x!r}, {self.y!r})'
    def __str__(self):
        return f'in __str__ {self.x}, {self.y}'
    

obj = BetterClass2(3, 'bar')
print(obj)
print(repr(obj)

in __str__ 3, bar

BetterClass2(3, ‘bar’)

另外__str__可以設計print()的行為。

若__str__沒有修改,但有__repr__修改,print()會呼叫它。

obj = OpaqueClass(4, 'baz')
print(obj.__dict__)

{‘x’: 4, ‘y’: ‘baz’}

若不能修改物件,我們可以改用__dict__來得到物件的成員所組成的dict

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料