【问题标题】:Python's dependency injection, and custom picklerPython 的依赖注入和自定义pickler
【发布时间】:2019-05-02 22:49:38
【问题描述】:

我正在尝试序列化具有外部依赖关系的类。

类的创建方式是它在其init函数中接收一个配置,并创建一个接收该配置并将其分配给self的对象。

我想要完成的是,我想序列化类,并且根据创建的上下文,我希望能够注入不同的配置。

class Foo:
  def __init__(self, some_value, config):
    self.some_value = some_value
    self.some_service = SomeService(config)

在这种情况下,我想要的是序列化 self.some_value,而不是 self.some_service(也不是配置,因为它已更改)。

那么,正确的模式是什么?我看过 getstate/setstate dunder,它非常适合仅序列化类的一部分,但在 unpickling 时不注入配置。我本来希望 Unpickler 在这种情况下能够完美地工作,但它看起来并不像它(并且似乎出于某种原因只适用于文件?数据在 redis 数据库中序列化,所以没有文件)。我也宁愿没有服务定位器,但注入配置而不是获取。

澄清: 问题不在于如何使用泡菜或泡菜。问题更多是模式的选择。我在对象中有外部依赖项(由self.some_service = SomeService(config) 表示)。

有两种方法可以在 unpickling 时重建该对象:

  • 使用自定义 Pickler/Unpickler 来检测外部依赖实例,序列化它的哈希值,然后在 unpickling 时,给它当时需要的任何实例
  • 创建检测服务的 get/setstate dunder 函数,但不对其进行序列化。

两者各有利弊,但我想知道推荐哪一个。 unpickling 时 unpickler 可以具有外部依赖项,并在 unpickling 时将其重新分配给对象,但这似乎是一个“沉重”的解决方案。使用 get/setstate dunder 需要让类知道如何获取外部依赖项,这似乎有点“神奇”(类获取外部服务而不是将它们提供给类)。

【问题讨论】:

  • Pickle with custom classes 的可能副本(otherinformationtopic 上。也许this 给出了如何使用它的想法)。您还应该研究可以在创建时转储/重新加载以将状态存储在 vars 中的 JSON 结构。
  • 我认为这个问题不是重复的(即使在阅读了所有给出的信息之后)。我的问题是我有一个引用不可腌制服务的实例。我不/不能腌制那些,但是当我解封时,新实例需要将其服务引用设置为这些服务。

标签: python dependency-injection pickle


【解决方案1】:

我最终得到的解决方案本质上有点像服务定位器:我解开实例,然后调用自定义 install_dependencies(injector)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-04
    • 2014-01-30
    • 2013-07-14
    • 1970-01-01
    • 2016-05-05
    • 1970-01-01
    • 2012-11-12
    • 2011-08-26
    相关资源
    最近更新 更多