【问题标题】:Is it common/good practice to test for type values in Python?在 Python 中测试类型值是否常见/良好的做法?
【发布时间】:2011-03-20 15:20:23
【问题描述】:

在以 OOP 方式工作时,在 Python 中经常测试类型值吗?

class Foo():
    def __init__(self,barObject):
        self.bar = setBarObject(barObject)

    def setBarObject(barObject);
        if (isInstance(barObject,Bar):
            self.bar = barObject
        else:
            # throw exception, log, etc.

class Bar():
    pass

或者我可以使用更宽松的方法,例如:

class Foo():
    def __init__(self,barObject):
        self.bar = barObject

class Bar():
    pass

【问题讨论】:

    标签: python oop introspection


    【解决方案1】:

    不,事实上,在您的第二种方法中,测试类型值是非常普遍的。这个想法是您的代码的客户端(即使用您的类的其他程序员)应该能够传递具有所有适当方法或属性的任何类型的对象。如果它不是某个特定类的实例,那很好;您的代码永远不需要知道其中的区别。这被称为 duck typing,因为有一句格言“如果它像鸭子一样嘎嘎叫,像鸭子一样飞,它还不如是一只鸭子”(好吧,这不是真正的格言,但我明白了我认为它的要点)

    您会在标准库中经常看到这一点,其中包含处理文件输入或输出的任何函数。他们不需要实际的file 对象,而是采用实现read()readline() 方法(取决于函数)或write() 的任何内容进行编写。事实上,您经常会在文档中看到这一点,例如tokenize.generate_tokens,我今天早些时候刚好看到:

    generate_tokens() 生成器需要一个参数,readline,它必须是一个可调用对象,它提供与内置文件对象的readline() 方法相同的接口(参见File Objects 部分)。对函数的每次调用都应以字符串形式返回一行输入。

    这使您可以使用StringIO 对象(如内存中的文件)或更古怪的东西(如对话框)来代替真实文件。

    在您自己的代码中,只需访问您需要的对象的任何属性,如果它是错误类型的对象,您需要的属性之一将不存在,并且会引发异常。

    【讨论】:

    • 第二个。另请参阅EAFP:请求宽恕比请求许可更容易。
    • 这很有趣。毕竟,我们应该享受 python 的特性而不是防御它们。
    【解决方案2】:

    我认为检查 input 的类型是个好习惯。可以合理地假设,如果您要求用户提供一种数据类型,他们可能会给您另一种,因此您应该编写代码来防范这种情况。

    但是,检查程序独立于输入生成的输入类型似乎是浪费时间(编写和运行程序)。与强类型语言一样,检查类型对于防范程序员错误并不重要。

    所以基本上,只检查输入而不是其他,这样代码才能顺利运行,用户不必想知道为什么他们得到了异常而不是结果。

    【讨论】:

    • 这可能是其他语言的好建议,但它不是 Python 中的常见做法。请参阅上面大卫的回答。
    • 非常重要的评论。继续测试输入。程序员错误和用户错误之间的区别很重要。谢谢。
    • 我不确定;我从 MIT OCW 学过 Python,MIT 的教授们总是谈论“防御性编码”,即使在 Python 中也是如此
    • @msw:什么概括?如果假设用户可能会给出错误的输入,我会不同意
    • @Rafe:在python的上下文中,防御性编码意味着要么检查您打算访问的方法/属性是否确实存在,或者(更pythonic)假设它确实存在并捕获@ 987654321@ 如果没有。这与检查对象的类型不同。
    【解决方案3】:

    如果您对类型检查的替代方法是包含异常处理的 else,那么您真的应该考虑将鸭子类型向上一层,使用输入所需的方法支持尽可能多的对象,并在 try 中工作。 然后,您可以排除(并且尽可能具体地除外)。 最终的结果不会与您在那里的结果不同,但更加通用和 Pythonic。

    关于实际问题需要说的所有其他内容,无论是否常见/良好做法,我认为 David 的回答都非常出色。

    【讨论】:

      【解决方案4】:

      我同意上面的一些答案,因为我通常从不检查从一个函数到另一个函数的类型。

      但是,正如其他人所提到的,应检查用户接受的任何内容,对于此类事情,我使用正则表达式。使用正则表达式验证用户输入的好处在于,您不仅可以验证数据格式是否正确,还可以将输入解析为更方便的形式,例如将字符串解析为字典。

      【讨论】:

        猜你喜欢
        • 2014-03-11
        • 1970-01-01
        • 2013-04-04
        • 2016-04-29
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多