我目前正在用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__
的参数。有没有其他方法可以传递它?我可以使用某种过程本地商店吗?
答案 0 :(得分:0)
你有几个选择。最好的方法是将配置实例作为参数传递给 init 。正如丹尼尔罗斯曼所指出的那样“明确胜过隐性”。或者,您可以设置包含配置实例的全局变量,并可在需要时访问该变量。但显然应该避免全局变量。最后,您可以使用单例模式,尽管这在很多方面比全局变量好一些。单身人士在这里描述:
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
如果您不想将配置实例传递到 init ,则可能需要使用单例。但是要记住它虽然与全局变量有类似的问题。虽然它在全局命名空间中不可见,但对任何单例实例的任何修改都将在其使用的任何地方修改其值。因此,应用程序的完全不同部分现在捆绑在一起,并且可能以难以查看和调试的方式以可能的方式进行交互。如果您的程序的两个部分之间需要关系,那么明确地将其添加到比将其传递给 init 的合作伙伴更好,然后使用更隐蔽的界面(如此)。 / p>
答案 1 :(得分:0)
您可以尝试使用whs.commons.abc。它提供了Session抽象。您可以创建自己的Session类,在其中可以实现at_begin和at_end挂钩,然后您可以通过Session.use
(从Session
导入whs.commons.abc.session
进行装饰来注册它。现在,在您的应用程序开始时,使用Session()。begin()以及您需要的任何参数(它们将在程序结束时传递给at_begin
kwargs)和Session().end()
。 Session对象已经是Singleton,因此您可以使用它来存储配置数据(可能是单个Config对象?)。
不幸的是,这个软件包没有在线文档,但你可以解压缩它的源代码并检查那里有哪些模块以及这些模块中的内容(我认为文档字符串非常好)。