我有一个Python函数,它在XML文件上做了很多重要的工作。
使用此函数时,我需要两个选项:将XML文件的名称传递给它,或者将预先解析的ElementTree实例传递给它。
我希望该函数能够确定其变量中给出的内容。
示例:
def doLotsOfXmlStuff(xmlData):
if (xmlData != # if xmlData is not ET instance):
xmlData = ET.parse(xmlData)
# do a bunch of stuff
return stuff
调用此函数的应用可能只需要调用一次,或者可能需要多次调用它。多次调用它并每次解析XML都是非常低效和不必要的。创建一个完整的类只是为了包装这个函数似乎有点矫枉过正,最终需要一些代码重构。例如:
ourResults = doLotsOfXmlStuff(myObject)
必须成为:
xmlObject = XMLProcessingObjectThatHasOneFunction("data.xml")
ourResult = xmlObject.doLotsOfXmlStuff()
如果我必须在许多小文件上运行它,每次都会创建一个类,这似乎效率低下。
有一种简单的方法来简单地检测变量的类型吗?我知道很多Pythoners会说“你不应该检查”,但这里有一个很好的例子。
在其他强类型语言中,我可以通过方法重载来实现这一点,但这显然不是Pythonic的方式......
答案 0 :(得分:1)
这是一种相当正常的模式(例如Python function that accepts file object or path)。只需使用isinstance
:
def doLotsOfXmlStuff(xmlData):
if not isinstance(xmlData, ET):
xmlData = ET.parse(xmlData)
...
如果你需要进行清理(例如关闭文件),那么递归调用你的函数就可以了:
def doLotsOfXmlStuff(xmlData):
if not isinstance(xmlData, ET):
xmlData = ET.parse(xmlData)
ret = doLotsOfXmlStuff(xmlData)
... # cleanup (or use a context manager)
return ret
...
答案 1 :(得分:1)
“鸭子打字”的原则是你不应该太在意对象的具体类型,而应该检查是否支持你感兴趣的API。
换句话说,如果通过xmlData参数传递给函数的对象包含一些指示已解析的ElementTree的方法或属性,那么您只需使用这些方法或属性...如果它没有必要属性然后你可以自由地通过一些解析。
因此您希望使用结果ET的函数/方法/属性吗?您可以使用hasattr()
来检查。或者,您可以使用try: ... except AttributeError:
块将您的调用包装到任何此类功能。
我个人认为if not hasattr(...):
有点清洁。 (如果它没有我想要的属性,那么将名称重新绑定到已经准备,解析的内容,无论我需要什么)。
这种方法优于isinstance()
,因为它允许您的功能用户将引用传递给自己的类中的对象,这些对象通过组合而不是继承来扩展ET。换句话说,如果我在我自己的类中包装一个类似ET的对象,并公开必要的功能,那么我应该能够将引用传递给你的函数,让你只需将我的对象看作是一个“鸭子”,即使它不是鸭子的后代。如果您需要羽毛,帐单和蹼足,那么只需检查其中一个并尝试使用其余部分。我可能是一个装有鸭子的黑匣子,我可能已经提供了洞,脚,鸭嘴和羽毛都可以穿过。
答案 2 :(得分:0)
您可以使用isinstance来确定变量的类型。
答案 3 :(得分:0)
您是否可以尝试使用if语句检查类型并确定从那里运行的内容?
if type(xmlData).__name__=='ElementTree':
#do stuff
else:
#do some other stuff
答案 4 :(得分:0)
我认为您可以只比较数据类型:
if (xmlData.dtype==something):
call Function1
else:
call Function2