我有一個類,其實例需要按照用戶的指示格式化輸出。有一個默認格式,可以覆蓋。我這樣實現它:酸洗類方法
class A:
def __init__(self, params):
# ...
# by default printing all float values as percentages with 2 decimals
self.format_functions = {float: lambda x : '{:.2%}'.format(x)}
def __str__(self):
# uses self.format_functions to format output
# ...
a = A(params)
print(a) # uses default output formatting
# overriding default output formatting
# float printed as percentages 3 decimal digits; bool printed as Y/N
a.format_functions = {float : lambda x: '{:.3%}'.format(x),
bool : lambda x: 'Y' if x else 'N'}
print(a)
可以嗎?讓我知道是否有更好的方法來設計這個。我不得不挑剔這個類的實例。但是隻有模塊頂層定義的函數才能被醃製; lambda
功能是不可取消的,所以我的format_functions
實例屬性打破了酸洗。
我試圖重寫這個使用一個類的方法,而不是lambda函數,但仍沒有運氣出於同樣的原因:
class A:
@classmethod
def default_float_format(cls, x):
return '{:.2%}'.format(x)
def __init__(self, params):
# ...
# by default printing all float values as percentages with 2 decimals
self.format_functions = {float: self.default_float_format}
def __str__(self):
# uses self.format_functions to format output
# ...
a = A(params)
pickle.dump(a) # Can't pickle <class 'method'>: attribute lookup builtins.method failed
注意,這裏酸洗即使我不覆蓋不起作用默認值;只是我分配self.format_functions = {float : self.default_float_format}
的事實打破了它。
怎麼辦?我寧願不污染命名空間並通過在模塊級定義default_float_format
來打破封裝。
順便說一句,爲什麼在這個世界上pickle
創造了這個限制?這對於最終用戶來說當然感覺像是一種無端的和實質性的痛苦。
我不介意,但如果另一個類需要不同的默認值呢?然後,我將在模塊級別擁有'default_float_format_for_class_A','default_float_format_for_class_B'等。它們不是更好的類方法(或靜態方法)嗎?另外,如果'pickle'可以與類方法一起工作,爲什麼不在標準的'pickle'模塊中完成呢?這有什麼缺點嗎? – max 2012-02-27 19:27:57