我想在我的python代码中使用一个工厂模式来获得两种不同的文件格式。 可以定义一个静态方法来选择我的新类,而不在基类中定义 init 或 new 吗?
类似的东西:
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')
调用Field(fileName)后,是否可以动态分配新类,而无需调用任何方法?
下面的答案确实解决了我的问题,但我最终得到了一个带超级的递归循环,你能帮我指出问题吗?
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)
答案 0 :(得分:0)
您的工厂模式代码看起来不错。
对于“一旦调用Field(fileName)就动态分配新类”,您可以这样做:
def Field(fileName):
if '.grb' in fileName:
return FieldGrib(fileName)
if '.nc' in fileName:
return FieldnetCDF(fileName)
else:
raise ValueError('File format not supported')
或者如果由于某种原因确实需要Field
作为类,可以使用__new__
,如下所示(确保Field为new-style class,即如果使用Python 2,则继承{ {1}}):
object
答案 1 :(得分:-1)
关于你的第二个问题,我不相信可以在不使用新的情况下做你想做的事情,除非你可以把它变成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类上的继承类,因为它们是从工厂类返回的类。
编辑2:
您不能从工厂类继承,因为当您调用super时,它将再次运行 new ,进入递归循环。工厂类只是一个工厂。它不应该继承任何东西。它只是决定返回哪个类。 FieldGrib和FieldGrib应该从包含所需功能的类继承,而不是从Field继承。如果字段仅用于创建其他内容,则可以创建名为
的私有Field类class _Field(object):
包含您想要的功能并且可以继承。它不应该被直接调用。
这会将FieldGrab变成
class FieldGrib(_Field):