Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 工厂模式选择的静态方法_Python_Factory Pattern - Fatal编程技术网

Python 工厂模式选择的静态方法

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

我想在python代码中为两种不同的文件格式创建一个工厂模式。 定义一个静态方法来选择我的新类,而不在基类中定义initnew可以吗

比如:

    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):