根据子类确定行为

时间:2013-08-14 22:43:39

标签: python subclassing arcpy

使用Python 2.6,我正在尝试处理各种格式的表(xls,csv,shp,json,xml,html表数据),并将内容提供到ArcGIS数据库表中(请留下我,这更多的是关于python部分的过程而不是GIS部分)。在当前设计中,我的基类格式化目标数据库表并使用源格式的内容填充它。子类目前设计用于将内容提供给字典,以便基类可以处理内容,无论源格式是什么。

问题是我的用户可能会将这些格式中的任何一种格式的文件或表格输入到脚本中,因此最好在运行时确定子类。除了运行一个真正涉及的if-elif-elif -...块之外,我不知道如何做到这一点。结构类型如下:

class Input:
  def __init__(self, name): # name is the filename, including path
    self.name = name
    self.ext = name[3:]
    d = {} # content goes here
    ... # dictionary content written to database table here

# each subclass writes to d
class xls(Input):
  ...

class xml(Input):
  ...

class csv(Input):
  ...

x = Input("c:\foo.xls")
y = Input("c:\bar.xml")

我对鸭子打字和多态性的理解表明这不是解决问题的方法,但我很难找到更好的设计。这方面的帮助会有所帮助,但我真正关心的是如何将x.exty.ext转换为确定子类(以及输入处理)的fork。

如果有帮助,我们假设foo.xlsbar.xml具有相同的数据,因此x.dy.d最终会有相同的项目,例如{{ 1}}。

3 个答案:

答案 0 :(得分:1)

这个问题通常通过了解子类的工厂函数来解决。

input_implementations = { 'xls':xls, 'xml':xml, 'csv':csv }

def input_factory(filename):
    ext = os.path.splitext(filename)[1][1:].lower()
    impl = input_implementations.get(ext, None)
    if impl is None:
        print 'rain fire from the skies'
    else:
        return impl(filename)

从基类本身(Input('file.xyz'))更难做到,因为在定义Input时没有定义子类。你可能会变得棘手,但简单的工厂很容易。

答案 1 :(得分:0)

如果每个派生类包含一个可以解析的可能文件扩展名列表怎么样?然后,您可以尝试将输入文件的扩展名与其中一个进行匹配,以决定使用哪个子类。

答案 2 :(得分:0)

你走在正确的轨道上。使用您的子类:

x = xls("c:\foo.xls")
y = xml("c:\bar.xml")

在每个子类中编写方法来解析相应的数据类型,并使用基类(Input)将数据写入数据库。