开发者

Is this a good reason to check types in Python?

I know that checking types in Python is bad and you should probably never do it. But I can't seem to find the disadvantage to this.

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 mus开发者_JAVA技巧t be derived."
            raise TypeError, message % { "class" : O }
        self.name = name

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

Now if someone tries to instantiate O, a class I never meant to be instantiated, they know immediately.

Is this still bad form?


Look at Abstract Base Classes as they will provide more fine grained control over how the subclasses are instantiated if this is something that you really want to do.

All in all, this might be a valid use because you are not preventing me from passing whatever I want to your code but I still wouldn't consider it pythonic. You are telling me that I can't instantiate your class. What If I want to?

Using ABC's, it looks like:

import abc

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

    @abc.abstractmethod
    def fn(self):
        pass

This has the advantage of not breaking super on the fn method. As you have it with the raise NotImplementedError, you are breaking super for multiple inheritance. If a class derives from two classes that subclass O and both call super (as they should to allow for multiple inheritance) then it will create the exception that you raise.

So now, you are not just telling me that I can't instantiate your class, you are telling me that I can't use multiple inheritance when subclassing from your class.


Don't check at all, we're are all adults here. Just add a note that O shouldn't be instantiated directly, either as a comment and/or in the documentation.

It's the same as if someone would call a method that requires an int as its parameter with a string instead. If the program crashes, they screwed it up. Otherwise you would need to add type checks to just about everything.


What is that you are trying to achieve with the above code.

In this case self is of type O and will always result in raising the exception.

Look at this snippet to understand it a little better

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"

This will output

<class '__main__.O'>
True
Yes
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜