Python类工厂..或

本文关键字:工厂 Python | 更新日期: 2023-09-27 17:47:21

我们在 C# 中有一个数据库库,我们可以像这样使用:

DatabaseConnection conn = DatabaseConnection.FromConnectionString("...");

该库隐藏了不同数据库引擎之间的许多差异,例如 SQL 函数名称、参数名称和规范等。

在内部,DatabaseConnection类是实现一些基本方法的抽象类,但FromConnectionString方法通过处理实际差异的已注册专用类型列表运行,并构造正确类的对象。换句话说,我没有返回 DatabaseConnection 对象,而是返回 MSSQLDatabaseConnection 或 OracleDatabaseConnection 对象,这些对象当然是从 DatabaseConnection 继承的。

连接

字符串包含有关此连接适用于哪种类型的数据库引擎和版本的信息。

我想在 Python 中创建一个类似的库。制作可以这样构造的东西是正确的方法吗?

conn = DatabaseConnection("...")

还是使用类方法?

conn = DatabaseConnection.FromConnectionString("...")

是第一个甚至可能,那就是...像这样构造一个对象并返回其他东西,一个专门的对象,取决于传递的字符串中的数据?

好吧,让我问一个不同的问题...这样做的pythonic方法是什么?

我基本上也想在 Python 中使用 DatabaseConnection 基类,实现常用方法,并专注于派生类,并在某处有一个基于连接字符串构造并返回正确类型的对象的方法或函数。

Python类工厂..或

这在 Python 中是可能的,但可能不是最好的方法。 类工厂模式本质上是没有第一类的语言的解决方法。 由于 Python 确实有第一类类,因此您可以将类存储在变量中,并直接使用该类来创建实例。 若要更改创建的类,请在变量中存储不同的类。

例如:

class class1:
  def greet(self):
    print "hi"
class class2:
  def greet(self):
    print "hello"
maker = class1
obj1 = maker()
maker = class2
obj2 = maker()
obj1.greet() # prints "hi"
obj2.greet() # prints "hello"

Python 不在乎你为什么返回类型。

def DatabaseConnection( str ):   
    if ( IsOracle( str ) ):   
        return OracleConnection( str )  
    else: 
        return SomeOtherConnection( str )

第一个是绝对可能的,在我看来是可取的。 在python中,构造函数背后真的没有太多的魔力。 出于所有意图和目的,它们就像任何其他功能一样。 我已经多次使用此设计模式来指示不应直接实例化类,例如:

def DatabaseConnectionFromString(connection_string)
    return _DatabaseConnection(connection_string)
def DatabaseConnectionFromSomethingElse(something_else)
    connection_string = convert_something_else_into_string(something_else)
    return _DatabaseConnection(connection_string)
class _DatabaseConnection(object):
    def __init__(self, connection_string):
        self.connection_string = connection_string

当然,这是一个人为的例子,但这应该给你一个大致的想法。

编辑:这也是继承在python中不那么不受欢迎的领域之一。 您也可以这样做:

DatabaseConnection(object):
    def __init__(self, connection_string):
        self.connection_string = connection_string
DatabaseConnectionFromSomethingElse(object)
    def __init__(self, something_else):
        self.connection_string = convert_something_else_into_string(something_else)

对不起,这太啰嗦了,但我想说清楚。