Python 基于子类确定行为

Python 基于子类确定行为,python,subclassing,arcpy,Python,Subclassing,Arcpy,使用Python2.6,我正在尝试以越来越多的格式(xls、csv、shp、json、xml、html表格数据)处理表格,并将内容输入到ArcGIS数据库表格中(请留下来,这更多是关于流程中Python部分而不是GIS部分)。在当前的设计中,我的基类格式化目标数据库表,并用源格式的内容填充它。这些子类目前被设计为将内容馈送到字典中,以便基类可以处理内容,而不管源格式是什么 问题是,我的用户可能会将这些格式中的任何一种的文件或表输入到脚本中,因此子类最好在运行时确定。我不知道如何做到这一点,除了通

使用Python2.6,我正在尝试以越来越多的格式(xls、csv、shp、json、xml、html表格数据)处理表格,并将内容输入到ArcGIS数据库表格中(请留下来,这更多是关于流程中Python部分而不是GIS部分)。在当前的设计中,我的基类格式化目标数据库表,并用源格式的内容填充它。这些子类目前被设计为将内容馈送到字典中,以便基类可以处理内容,而不管源格式是什么

问题是,我的用户可能会将这些格式中的任何一种的文件或表输入到脚本中,因此子类最好在运行时确定。我不知道如何做到这一点,除了通过运行一个真正涉及如果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")
我对duck类型和多态性的理解表明,这不是解决问题的方法,但我很难找到更好的设计。这方面的帮助会有所帮助,但我真正想要的是如何将
x.ext
y.ext
转换为确定子类(以及输入处理)的分支


如果有帮助的话,让我们假设
foo.xls
bar.xml
具有相同的数据,因此
x.d
y.d
最终将具有相同的项,例如
{'name':'Somegrad','lat':52.91025,'lon':47.88267}

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

您走对了方向。使用您的子类:

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

在每个子类中写入方法以解析适当的数据类型,并使用基类(输入)将数据写入数据库。

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

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时没有定义子类。您可能会遇到麻烦,但简单的工厂很容易。

欢迎使用SO!一定要看一看详细的问题、答案和评论的标记可能性。这就是问题所在:我想避免让我的读者做任何编码。理想情况下,他们只需要使用一个类似GUI的表单,其中他们需要填充的唯一字段是文件名和路径。关于这个好模式的一点说明是@tdelaney利用字典结构(
input\u implementations
)作为他/她的实现数据库。或者,如果所有类都在模块中,则可以在模块上使用
inspect.get_members()
或其他方法动态生成此列表。另一个线程: