【问题标题】:what does __getstate_manages_dict__ do?__getstate_manages_dict__ 做什么?
【发布时间】:2020-11-12 07:06:17
【问题描述】:

我一直致力于多处理和 C++ 扩展,但我不太了解 __getstate_manages_dict__ 函数(我知道如何使用它,但我不确定它是如何工作的)。 boost/Python documentation for pickle support 是这样说的:

Boost.Python 扩展类的作者可能提供了一个__getstate__ 方法而没有考虑以下可能性: * 他的类在Python 中用作基类。很可能需要对派生类实例的 dict 进行腌制以正确恢复实例。 * 用户直接将项目添加到实例的__dict__。同样,实例的__dict__ 需要被腌制。

为了提醒用户注意这个非常不明显的问题,安全卫士是 假如。如果定义了 __getstate__ 并且实例的 __dict__ 是 不为空,Boost.Python 测试类是否有属性 __getstate_manages_dict__。如果未定义此属性,则会引发异常:

我见过一些例子,其中对象的__dict____getstate__ 中返回,然后在__setstate__ 中更新。 __dict__ 指的是什么?是派生类对象的__dict__ 属性吗?另外,如果pickle调用__init__创建一个新对象然后设置属性,为什么需要显式处理这个dict?

谢谢

【问题讨论】:

    标签: python c++ oop pickle boost-python


    【解决方案1】:

    我知道如何使用它,但我不确定它是如何工作的

    这是一个布尔值,默认为 False。重点是向 Boost 发出信号,__getstate__/__setstate__ 实现处理类的__dict__ 属性,这样信息就不会在酸洗过程中丢失。

    这个想法是 Boost::Python 实际上无法确定代码是否正确编写,因此您需要跳过这个额外的障碍,这样,如果您没有意识到问题,您会看到一条错误消息- 正如他们所说,to alert the user to this highly unobvious problem

    它没有做任何神奇的事情。可以这么说,它只是为了确认您“阅读了保修”。

    pickle 支持的 boost/Python 文档是这样说的:

    这只是解释为什么考虑 __dict__ 内容很重要的原因 - 即使您不想腌制您在 __init__ 中明确设置的所有属性(例如,因为该类包含引用您打算以其他方式加载的大型资源,或结果缓存,或...)。简而言之,您的类的实例可能包含您不希望它们包含的信息,并且您的 __getstate__ 实现不知道如何处理,除非它考虑到实例的 __dict__ em>。

    因此提供了“实用建议”:“如果需要 __getstate__,请在返回的 Python 对象中包含实例的 __dict__。”

    __dict__ 指的是什么?是派生类对象的__dict__属性吗?

    这是调用__getstate__ 的实例__dict__ 属性。如果该类不覆盖方法,那可能是派生类的实例。或者它可能是基类的一个实例,它可能在类实现之外添加了额外的属性,也可能没有。

    另外,如果pickle调用init创建一个新对象然后设置属性,为什么这个dict需要显式处理?

    见上文。当您获取属性时(以便可以写入 pickle 文件),您需要确保您确实获得了所有必要的属性,否则它们将在恢复时丢失。硬编码的逻辑可能会遗漏一些。

    【讨论】:

    • 啊,我明白了。所以对象有一个属性 dict 包含某些信息,其中一些可能在酸洗时丢失,避免这种情况的最简单方法是使用 getstate 和 setstate 更新 dict?
    • 你没有用他们更新__dict__;您正在使用__dict__ 获取__getstate__ 返回的信息。您可以__setstate__ 中修改self 对象的__dict__ 作为设置属性的一种方式,但以正常方式设置它们更容易。
    猜你喜欢
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 2011-08-23
    • 2011-01-03
    • 2011-04-21
    • 2012-08-27
    相关资源
    最近更新 更多