DB-Connections类在Python中作为Singleton

Ale*_*Emm 7 python database singleton

所以在python中对单身人士有很多仇恨.我通常看到有一个单身通常是不好的,但是那些有副作用的东西,比如使用/查询数据库呢?为什么我可以为每个简单查询创建一个新实例,当我可以重新使用已经再次设置的当前连接时?什么是pythonic方法/替代?

谢谢!

aba*_*ert 6

通常,您有某种对象表示使用数据库的事物(例如,实例MyWebServer),并且您将数据库连接作为该对象的成员.

如果您将所有逻辑放在某种函数中,请将该函数的连接局部化.(这在许多其他语言中并不常见,但在Python中,通常有很好的方法可以在单个生成器函数中包含多阶段有状态工作.)

如果您将所有数据库内容分散到各处,那么只需使用全局变量而不是单例.是的,全局变量很糟糕,但单身人士同样糟糕,而且更复杂.在一些情况下,它们很有用,但非常罕见.(对于其他语言来说不一定如此,但它适用于Python.)摆脱全局的方法是重新考虑你的设计.很有可能你有效地使用模块作为(单例)对象,如果你仔细考虑,你可能会想出一个好的类或函数来包装它.


显然只是将所有的全局变量都移动到类属性中,@classmethod而只是在不同的命名空间下给你全局变量.但将它们转移到实例属性和方法是另一回事.这会给你一个你可以传递的对象 - 如果需要的话,你可以拥有一个对象(或者在某些情况下甚至可以为0),附加一个锁,序列化等等.

在许多类型的应用程序中,你仍然会得到一个单独的实例 - 每个Qt GUI应用程序只有一个MyQApplication,几乎每个Web服务器都有一个MyWebServer,等等.无论你怎么称呼它,这实际上是一个单例或全球的.如果你愿意,你可以将所有东西都移动到那个神对象的属性中.

但仅仅因为你可以这样做并不意味着你应该这样做.你仍然有函数参数,局部变量,每个模块中的全局变量,其他(非巨石)类以及它们自己的实例属性等,你应该使用适合每个值的任何东西.

例如,假设您为每个连接到您的新客户端MyWebServer创建一个新ClientConnection实例.您可以MyWebServer.instance.db.execute在想要执行SQL查询时使连接写入...但您也可以只传递self.dbClientConnection构造函数,然后每个连接都可以self.db.execute.那么,哪一个更好?好吧,如果你采用后一种方式,它会使你的代码更容易扩展和重构.如果要跨4个数据库进行负载平衡,则只需在一个位置(MyWebServer每个初始化ClientConnection)更改代码而不是100(每次ClientConnection访问数据库时).如果要将单片Web应用程序转换为WSGI容器,则ClientConnection除了构造函数之外,您不必更改任何代码.等等.