pylint и abc - абстрактный метод

import abc


class Human(object):
    __metaclass__ = abc.ABCMeta

    config = {
        'num_ears': 2,
        'num_hands': 2,
    }

    def __init__(self):
        self.config = dict(self.config.items() + self.derived_config.items())

    @abc.abstractproperty
    def derived_config(self):
        pass

    # logic that does stuff with self.config


class Clown(Human):

    derived_config = {
        'funny': True,
        'smile': True,
    }

    def __init__(self, *args, **kwargs):
        self.derived_config = dict(self.derived_config.items() + self.implementation_config.items())

        super(Clown, self).__init__(*args, **kwargs)

    @abc.abstractproperty
    def implementation_config(self):
        pass

    # logic that does stuff with self.config


class OneHandedClown(Clown):

    implementation_config = {
        'smile': False,
        'num_jokes': 20,
        'num_hands': 1,
    }


if __name__ == '__main__':
    s = OneHandedClown()
    print s.config     # {'funny': True, 'num_hands': 1, 'num_jokes': 20, 'num_ears': 2, 'smile': False}

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

Но pylint завершается со следующей ошибкой:

W: 39, 0: Method 'derived_config' is abstract in class 'Human' but is not overridden (abstract-method)

NB:

  • pylint не жалуется на абстрактное свойство implementation_config, но шаблон тот же (за исключением того, что OneHandedClown является конечным листом).
  • pylint делает жалобу, если я удалю переменную классаmplementation_config в OneHandedClown

Как я могу убедиться, что lint проходит без использования pylint-disable, и в то же время использовать абстрактное свойство, чтобы убедиться, что контракт наследования является явным?


person yangmillstheory    schedule 16.08.2014    source источник
comment
это ошибка, о которой следует сообщать в системе отслеживания проблем pylint (bitbucket.org/logilab/pylint/issues< /а>)   -  person sthenault    schedule 25.08.2014


Ответы (1)


Я нашел решение, но не ответ.

...


class Clown(Human):

    clown_config = {
        'funny': True,
        'smile': True,
    }

    @property
    def derived_config(self):
        return dict(self.clown_config.items() + self.implementation_config.items())


    @abc.abstractproperty
    def implementation_config(self):
        pass

    # logic that does stuff with self.config


...

В частности, почему установки переменной класса implementation_config достаточно для реализации абстрактного свойства в Clown, а предыдущей реализации derived_config в Clown недостаточно для реализации соответствующего абстрактного свойства в Human?

person yangmillstheory    schedule 17.08.2014