使用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