【发布时间】:2012-02-27 18:42:34
【问题描述】:
我有一个类,其实例需要按照用户的指示格式化输出。有一个默认格式,可以被覆盖。我是这样实现的:
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)
没事吧?如果有更好的设计方法,请告诉我。
不幸的是,我需要腌制这个类的实例。但是只有在模块顶层定义的函数才能被pickle; 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 会创建这个限制?对于最终用户来说,这无疑是一种无端的痛苦。
【问题讨论】:
标签: python methods python-3.x pickle