接受python函数中的不同类型?

时间:2013-05-09 16:58:33

标签: python function object types

我有一个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的方式......

5 个答案:

答案 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