这是检查Python类型的一个很好的理由吗?

时间:2010-09-17 08:26:05

标签: python typechecking

我知道在Python中检查类型很糟糕,你可能永远不会这样做。但我似乎无法找到这个缺点。

class O(object):         
    def __init__(self, name):
        '''Can only be called in derived classes.'''
        if type(self) is O:
            message = "%(class)s cannot be instantiated, it must be derived."
            raise TypeError, message % { "class" : O }
        self.name = name

    def fn(self):
        '''Must be populated in derived classes.'''
        raise NotImplementedError

现在,如果有人试图实例化O,我从未想过要实例化的类,他们立即知道。

这还是不好的形式吗?

3 个答案:

答案 0 :(得分:5)

看看Abstract Base Classes,因为如果这是你真正想做的事情,它们将提供更细粒度的控制子类的实例化。

总而言之,这可能是一个有效的用途,因为你没有阻止 me 想要的任何东西传递给你的代码,但我仍然不认为它是pythonic 。您告诉 无法实例化您的课程。如果我想要怎么办?

使用ABC,它看起来像:

import abc

class O(object):
    __metaclass__ = abc.ABCMeta     
    def __init__(self, name):
        self.name = name

    @abc.abstractmethod
    def fn(self):
        pass

这样做的好处是不会破坏fn方法上的super。正如您使用raise NotImplementedError一样,您正在破坏多重继承。如果一个类派生自两个类,它们是子类O并且都调用super(因为它们应该允许多重继承),那么它将创建你引发的异常。

所以现在,你不只是告诉我,我无法实例化你的类,你告诉我,当你从类中继承时,我不能使用多重继承。

答案 1 :(得分:5)

根本不检查,我们都是成年人。只需添加一条注释,O不应直接实例化,作为注释和/或文档。

就像有人会调用一个需要int作为参数的方法来代替string一样。如果程序崩溃,他们搞砸了。否则,您需要为几乎所有内容添加类型检查。

答案 2 :(得分:1)

您尝试使用上述代码实现的目标是什么。

在这种情况下,self属于O类型,并且总是会导致异常升级。

请看这个片段以便更好地理解它

class O(object):         
    def __init__(self, name):
        self.name = name      

o = O("X")

print type(o)
print isinstance(o, O)
if type(o) is O:
    print "Yes"

这将输出

<class '__main__.O'>
True
Yes