[英]Python class factory ... or?
我们在 C# 中有一个数据库库,我们可以这样使用:
DatabaseConnection conn = DatabaseConnection.FromConnectionString("...");
该库隐藏了不同数据库引擎之间的许多差异,例如 SQL 函数名称、参数名称和规范等。
在内部, DatabaseConnection
类是一个抽象类,实现了一些基本方法,但FromConnectionString
方法运行在处理实际差异的已注册专用类型列表中,并构造正确类的对象。 换句话说,我没有取回 DatabaseConnection 对象,而是取回了 MSSQLDatabaseConnection 或 OracleDatabaseConnection 对象,它们当然是从 DatabaseConnection 继承的。
连接字符串包含有关此连接适用于哪种数据库引擎和版本的信息。
我想在 Python 中创建一个类似的库。 制作可以像这样构造的东西的正确方法是什么?
conn = DatabaseConnection("...")
或使用类方法?
conn = DatabaseConnection.FromConnectionString("...")
第一个甚至是可能的,也就是说......构造一个这样的对象并取回其他东西,一个专门的对象,取决于传递的字符串中的数据?
好吧,让我问一个不同的问题......这样做的pythonic方法是什么?
我基本上也希望在 Python 中拥有 DatabaseConnection 基类,实现通用方法,并专门研究派生类,并在某处拥有基于连接字符串构造并返回正确类型的对象的方法或函数。
这在 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)
对不起,这太冗长了,但我想说清楚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.