Python 工厂模式选择的静态方法
我想在python代码中为两种不同的文件格式创建一个工厂模式。 定义一个静态方法来选择我的新类,而不在基类中定义init或new可以吗 比如:Python 工厂模式选择的静态方法,python,factory-pattern,Python,Factory Pattern,我想在python代码中为两种不同的文件格式创建一个工厂模式。 定义一个静态方法来选择我的新类,而不在基类中定义init或new可以吗 比如: Class Field(fileName): @static method def chooseClass(fileName): if '.grb' in fileName: return FieldGrib(fileName) if '.n
Class Field(fileName):
@static method
def chooseClass(fileName):
if '.grb' in fileName:
return FieldGrib(fileName)
if '.nc' in fileName:
return FieldnetCDF(fileName)
else:
raise valueError('File format not supported')
在调用字段(fileName)时,是否可以在不调用任何方法的情况下动态分配新类
下面的答案确实解决了我的问题,但我最终得到了一个带super的递归循环,你能帮我指出这个问题吗
class Field(object):
def __new__(cls, fieldFile):
if '.grb' in fieldFile:
return FieldGrib(fieldFile)
else:
raise ValueError('no support for other formats')
def __init__(self, fieldFile):
print fieldFile
class FieldGrib(Field):
def __init__(self, fieldFile):
# read Field, opening fieldFile if required
super(FieldGrib, self).__init__(fieldFile)
您的工厂模式代码看起来正常
对于“在调用字段(文件名)后立即动态分配新类”,您只需执行以下操作:
def Field(fileName):
if '.grb' in fileName:
return FieldGrib(fileName)
if '.nc' in fileName:
return FieldnetCDF(fileName)
else:
raise ValueError('File format not supported')
或者,如果出于某种原因确实需要将字段
作为一个类,则可以按如下方式使用\uuu new\uuuu
(确保字段是一个,即,如果使用Python 2,则继承对象
):
关于你的第二个问题,我认为不使用new就不可能做你想做的事情,除非你同意将其作为fferri描述的功能。如果您想要维护类结构,那么可以这样做
Class Field(object):
def __init___(self):
pass
def __new__(cls, filename):
if '.grb' in fileName:
return FieldGrib(fileName)
if '.nc' in fileName:
return FieldnetCDF(fileName)
else:
raise valueError('File format not supported')
class FieldGrib(Object_To_Inherit_From)
def __init__(self, fileName):
super().__init__(fileName)
self.fileName = fileName
...etc.
编辑:
如果要维护基类中的函数,可以更改FieldGrib类和FieldnetCDF类上的继承类,因为它们是从factory类返回的
编辑2:
无法从factory类继承,因为调用super时,它将再次运行new,进入递归循环。工厂类就是工厂。它不应该继承任何东西。它只是指示返回哪个类。FieldGrib和FieldGrib应从包含所需功能的类继承,而不是从Field继承。若字段仅用于创建其他内容,那个么可以创建一个名为
class _Field(object):
包含所需功能并可从中继承的。但是不应该直接调用它
这将把FieldGrab变成
class FieldGrib(_Field):
谢谢你的快速回复。这很简单,但我想保留我的基类,因为有些方法对于这两个子类是通用的。还有别的办法吗?@I.K.我用另一种解决方案更新了我的答案
class FieldGrib(_Field):