当前位置: 首页 > 面试题库 >

酸洗课法

黄俊誉
2023-03-14
问题内容

我有一个类,该类的实例需要按照用户的指示格式化输出。有一种默认格式,可以覆盖。我是这样实现的:

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_functionsinstance属性破坏了酸洗。

我尝试重写此代码以使用类方法而不是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的腌菜依赖于其名称可以用作全局变量-字典中对方法的引用指向全局名称空间中不可用的名称-
更好说“模块名称空间”-

您可以通过自定义类的酸洗,创建“ setstate”和“ getstate”方法来规避这一问题-
但我认为您会更好,因为格式化功能不依赖于对象或类本身的任何信息(并且即使有某种格式化功能,也可以将其作为参数传递),并在类范围之外定义一个功能。

这确实有效(Python 3.2):

def default_float_format( x):
    return '{:.2%}'.format(x)

class A:

  def __init__(self, params):
    # ...
    # by default printing all float values as percentages with 2 decimals
    self.format_functions = {float: default_float_format}
  def __str__(self):
    # uses self.format_functions to format output
    pass

a = A(1)
pickle.dumps(a)


 类似资料:
  • 问题内容: 我想搜索给定目录中所有图像中的冲浪,并保存它们的关键点和描述符以供将来使用。我决定使用泡菜,如下所示: 当我尝试执行时,出现以下错误: 有人知道吗,这是什么意思,以及如何解决?我正在使用Python 2.6和Opencv 2.3.1 十分感谢 问题答案: 问题是您不能将cv2.KeyPoint转储到pickle文件中。我遇到了同样的问题,并设法通过本质上对关键点进行序列化和反序列化来解

  • 问题内容: 我必须腌制这样的对象数组: 它给出了以下错误: 有办法解决吗? 问题答案: 内置的pickle模块无法序列化几种python对象(包括lambda函数,嵌套函数和在命令行中定义的函数)。 picloud软件包包括一个更强大的pickler,可以对lambda函数进行pickle。 可以使用常规的pickle / cPickle和功能来反序列化PiCloud序列化的对象。 莳萝还提供类似

  • 问题内容: 我最近更改了程序的目录布局:以前,我的所有模块都位于“主”文件夹中。现在,我将它们移动到以该程序命名的目录中,并在其中放置一个包。 现在,我的主目录中只有一个.py文件,用于启动程序,这更加整洁。 无论如何,尝试从程序的早期版本中加载腌制文件失败。我收到“ ImportError:没有名为工具的模块”的信息- 我猜是因为我的模块以前位于主文件夹中,而现在位于whyteboard.too

  • 数据清洗和特征挖掘的工作是在灰色框中框出的部分,即“数据清洗=>特征,标注数据生成=>模型学习=>模型应用”中的前两个步骤。 灰色框中蓝色箭头对应的是离线处理部分。主要工作是 从原始数据,如文本、图像或者应用数据中清洗出特征数据和标注数据。 对清洗出的特征和标注数据进行处理,例如样本采样,样本调权,异常点去除,特征归一化处理,特征变化,特征组合等过程。最终生成的数据主要是供模型训练使用。 灰色框中

  • 我正在使用数据库,并且在数据框架中有一个列,我需要通过外部Web服务调用为每条记录更新该列。在这种情况下,它使用Azure机器学习服务SDK并进行服务调用。当在Spark中不作为UDF运行时,此代码可以正常工作(即。只是python),但是当我尝试将其称为UDF时,它会引发序列化错误。如果我使用lambda和带有rdd的map,也会发生同样的情况。 该模型使用快速文本,并且可以通过正常的超文本传输

  • 大多数纸牌游戏都需要洗牌,也就是让纸牌随机排列。在第10.5节,我们看到了怎样生成随机数,但怎样利用随机数实现洗牌功能却并非显然意见的。 一种可行的方案是,模拟人洗牌的方法,将牌分为两堆,然后通过在每个牌堆中轮流选择的方式实现原牌堆的重新组织。因为一般而言,人并不能做到完美地洗牌,而程序经过大约7次迭代之后,牌堆中纸牌的顺序已经相当随机了。但是计算机程序每次在做完美洗牌的时候有一个令人讨厌的属性—