【问题标题】:Implementing a configuration object实现配置对象
【发布时间】:2014-02-01 06:53:06
【问题描述】:

我目前正在用 Python 编写一个内部抽象层,以帮助我们的开发人员与我们的内部数据存储进行对话,而无需让他们了解细节。

抽象层的某些部分需要各种连接和配置(如路径、数据库连接等),由于我们希望尽可能保持灵活性,我们决定抽象出细节。为此,我创建了一个 Configuration 类,它有一堆未实现的方法来获取内部所需的详细信息:

class Configuration:

    def get_mongo_client(self):
        """
        :returns: a :py:class:`pymongo.MongoClient` instance that should be used \
        for talking to the database
        """
        raise NotImplementedError()

    # more getters...

现在,假设我有一个 Users 类,它在内部需要一个 Configuration 实例。使它可用的最佳方法是什么?我真的很想*避免Configuration 作为__init__ 的参数。还有其他方法可以传递吗?我可以使用某种流程本地存储吗?

【问题讨论】:

  • “显式优于隐式”...
  • 你为什么不想要它在__init__
  • 这不能回答您的问题 - 但面对同样的问题,我意识到将共享功能尤其是因为它与数据库相关作为内部 (REST) 公开更简单API。这不仅使集成变得轻而易举,而且作为额外的好处,它使跟踪数据存储的使用不再是问题。需要考虑的事情。

标签: python


【解决方案1】:

您有几个选择。最好的方法可能是将配置实例作为参数传递给 init。正如丹尼尔·罗斯曼(Daniel Roseman)在上面指出的那样“显式胜于隐式”。或者,您可以设置一个包含配置实例的全局变量,并且可以在需要的地方访问。但显然应该避免使用全局变量。最后,您可以使用单例模式,尽管这在许多方面都比全局变量好一点。这里描述了单例:

http://en.wikipedia.org/wiki/Singleton_pattern

但基本上,它允许您在需要使用其信息的任何地方创建 Configuration 对象的新实例,但由于它的创建方式,您将获得对具有相同内部数据的相同 Configuration 实例的引用。

比如:

    def SingletonConfiguration():
    # implementation

    config = SingletonConfiguration()
    config.Setup()
    # Do any configuration ended of instance

   class UseConfig():
       def __init__():
           a = SingletonConfiguration() # will return same config instance as was
                                        # previously setup
           a.getconfig()

更多关于python中单例的信息可以在这里看到:

Python and the Singleton Pattern

如果您不想将 Configuration 的实例传递给 init,那么单例可能是要走的路。请记住,尽管它与全局变量有类似的问题。虽然它在全局命名空间中不可见,但对任何单例实例的任何修改都会在任何使用它的地方修改其值。因此,您的应用程序的完全不同的部分现在被捆绑在一起,并且可能以难以查看和调试的方式以可能不好的方式进行交互。如果您的程序的两个部分之间需要关系,那么最好像将伙伴传递给 init 那样显式添加它,然后使用像这样的更隐蔽的接口。

【讨论】:

    【解决方案2】:

    您可以尝试使用whs.commons.abc。它提供了 Session 抽象。您可以创建自己的 Session 类,在其中您可以实现 at_begin 和 at_end 钩子,然后您可以通过使用Session.use 装饰来注册它(从whs.commons.abc.session 导入Session)。现在,在您的应用程序开始时使用 Session().begin() 和您需要的任何参数(它们将被传递给 at_begin kwargs)和程序结束时的 Session().end()。 Session 对象已经是一个 Singleton,因此您可以使用它来存储配置数据(可能作为单个 Config 对象?)。

    不幸的是,这个包没有在线文档,但你可以解压它的源代码并检查那里有哪些模块以及这些模块中有什么(我认为那里的文档字符串非常好)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多