Это хорошая причина для проверки типов в Python? - PullRequest
2 голосов
/ 17 сентября 2010

Я знаю, что проверка типов в 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 ]

5 голосов
/ 17 сентября 2010

Не проверяйте вообще, мы все здесь взрослые. Просто добавьте примечание, что O не следует создавать непосредственно, как комментарий и / или в документации.

Это так же, как если бы кто-то вызывал метод, для которого вместо параметра int требуется *1004*. Если программа вылетает, они облажались. В противном случае вам нужно будет добавить проверки типов практически ко всему.

5 голосов
/ 17 сентября 2010

Посмотрите на Абстрактные базовые классы , поскольку они обеспечат более точный контроль над тем, как создаются экземпляры подклассов, если это то, что вы действительно хотите сделать.

В целом, это может быть допустимым использованием, потому что вы не препятствуете me передавать все, что I хочет в ваш код, но я все равно не буду считать его пифоническим. Вы говорите мне , что Я не может создать экземпляр вашего класса. Что если я захочу?

Используя ABC, это выглядит так:

import abc

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

    @abc.abstractmethod
    def fn(self):
        pass

Преимущество в том, что вы не разбиваете супер на методе fn. Как у вас с raise NotImplementedError, вы нарушаете супер для множественного наследования. Если класс наследуется от двух классов, которые подкласс O и оба вызывают super (как они должны учитывать множественное наследование), то он создаст исключение, которое вы вызываете.

Итак, теперь вы не просто говорите мне, что я не могу создать экземпляр вашего класса, вы говорите, что я не могу использовать множественное наследование при создании подклассов из вашего класса.

1 голос
/ 17 сентября 2010

Чего вы пытаетесь достичь с помощью приведенного выше кода.

В этом случае 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
...