我知道在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,我从未想过要实例化的类,他们立即知道。
这还是不好的形式吗?
答案 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