如何避免对未使用属性的Python对象进行类型检查?

4 投票
4 回答
795 浏览
提问于 2025-04-16 15:31

我在这里看到了一些关于在Python中进行类型检查的回答,包括一般的类型检查、针对数字的类型检查,以及针对字符串的类型检查。大多数人似乎都认为在Python中(版本小于2.6)应该永远不进行类型检查,因为有一种叫做鸭子类型的概念。我的理解是,鸭子类型是通过使用对象的属性来确定类型的。那么,如果我根本不使用任何属性,我该怎么办呢?

我有一个简单的函数,它根据传入的参数来判断常量,这个参数应该是一个数字。我会抛出一个异常,内容是

class outOfBoundsError(ValueError):
    """
    Specified value is outside the domain.
    """

并告诉他们我收到的数字太大了。我想让这个消息更具体。但是如果传入的参数是一个字符串(比如'charlie'),它依然会认为这个参数大于我指定的数字(并抛出我的异常)。我是不是应该在代码里加一行像argument + 2这样的无用代码,以便引发一个类型错误?

注意:我对ABCs(抽象基类)一无所知,但我觉得它们对我来说不适用,因为我们能用的最新Python版本是2.5 :(。

4 个回答

1

你可以先确认一下你所期待的数据类型是否是你支持的类型。也就是说:

def foo(arg):
    if not isinstance(arg, int):
        raise TypeError
    ...

如果你只支持整数,那这样做是没有问题的。

2

我对这个问题的真实看法是:

大多数人似乎都说,在Python(<2.6)中不应该进行类型检查,因为有“鸭子类型”这个概念。

我的看法是:这完全是胡说八道。

如果需要进行类型检查,这其实是很常见的做法。

不要听信所有人的话,也不要不加过滤地接受每一个说法。

6

一个常见的用Python解决这个问题的方法是尝试把你得到的东西转换成你需要的东西。比如说,如果你需要一个整数:

def getconstants(arg):
    try:
        arg = int(arg)
    except:
        raise TypeError("expected integer, or something that can be converted to one, but got " + repr(arg))

int这个类型的构造函数知道怎么处理很多内置类型。此外,那些可以转换成int类型的类型,可以实现一个叫__int__()的特殊方法,这样它们就可以在这里使用。如果用户传入的是一个字符串,只要这个字符串里全是数字,那也是可以的。

你提到的进行一些只能在数字类型上执行的操作(比如加2)也是类似的,这在很多情况下都能很好地工作,但如果是可以转换成目标类型的字符串,就会出问题,所以我觉得类型转换的方法更好。

其实你可能不需要在这里用try/except,因为如果int()无法进行转换,它会抛出TypeErrorValueError错误,但我觉得TypeError更合适,因为你主要关心的是对象的类型,所以我选择捕获这个异常,并始终抛出TypeError

撰写回答