Python 基于子类确定行为
使用Python2.6,我正在尝试以越来越多的格式(xls、csv、shp、json、xml、html表格数据)处理表格,并将内容输入到ArcGIS数据库表格中(请留下来,这更多是关于流程中Python部分而不是GIS部分)。在当前的设计中,我的基类格式化目标数据库表,并用源格式的内容填充它。这些子类目前被设计为将内容馈送到字典中,以便基类可以处理内容,而不管源格式是什么 问题是,我的用户可能会将这些格式中的任何一种的文件或表输入到脚本中,因此子类最好在运行时确定。我不知道如何做到这一点,除了通过运行一个真正涉及如果elif-elif-。。。块结构类似于这样:Python 基于子类确定行为,python,subclassing,arcpy,Python,Subclassing,Arcpy,使用Python2.6,我正在尝试以越来越多的格式(xls、csv、shp、json、xml、html表格数据)处理表格,并将内容输入到ArcGIS数据库表格中(请留下来,这更多是关于流程中Python部分而不是GIS部分)。在当前的设计中,我的基类格式化目标数据库表,并用源格式的内容填充它。这些子类目前被设计为将内容馈送到字典中,以便基类可以处理内容,而不管源格式是什么 问题是,我的用户可能会将这些格式中的任何一种的文件或表输入到脚本中,因此子类最好在运行时确定。我不知道如何做到这一点,除了通
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()
或其他方法动态生成此列表。另一个线程: