Хорошая семантика, подкласс или подражание? - PullRequest
2 голосов
/ 10 мая 2011

Я уже некоторое время использую python, и я счастлив использовать его в большинстве форм, но мне интересно, какая форма более питоническая. Правильно ли эмулировать объекты и типы или лучше наследовать или наследовать от этих типов. Я вижу преимущества для обоих, а также недостатки. Какой правильный способ сделать это?

Метод подклассов

class UniqueDict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)

    def __setitem__(self, key, value):
        if key not in self:
            dict.__setitem__(self, key, value)
        else:
            raise KeyError("Key already exists")

Метод эмуляции

class UniqueDict(object):
    def __init__(self, *args, **kwargs):
        self.di = dict(*args, **kwargs)

    def __setitem__(self, key, value):
        if key not in self.di:
            self.di[key] = value
        else:
            raise KeyError("Key already exists")

Ответы [ 3 ]

3 голосов
/ 10 мая 2011

Ключевой вопрос, который вы должны задать себе здесь:

«Как должен измениться мой класс, если изменится« родительский »класс?»

Представьте, что к dict добавлены новые методы, которые вы не переопределяете в своем UniqueDict.Если вы хотите выразить, что UniqueDict - это просто небольшой вывод в поведении из поведения dict, то вы перейдете с наследованием , так как вы получите изменения вбазовый класс автоматически.Если вы хотите выразить, что UniqueDict похоже на dict, но на самом деле не , вам следует перейти в режим 'эмуляция' .

1 голос
/ 10 мая 2011

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

0 голосов
/ 10 мая 2011

Я бы выбрал подкласс, и по этой причине я бы сослался на мотивацию PEP 3119 :

Например, если спрашивать, является ли этот объект изменяемой последовательностьюcontainer? ', можно искать базовый класс' list ', или можно искать метод с именем' getitem '.Но обратите внимание, что хотя эти тесты могут показаться очевидными, ни один из них не является правильным, так как один генерирует ложные отрицания, а другие ложные положительные.

Общепринятым решением является стандартизация тестов и их группировкаформальная договоренность.Это проще всего сделать, связав с каждым классом набор стандартных тестируемых свойств, либо с помощью механизма наследования, либо с помощью других средств.Каждый тест несет с собой набор обещаний: он содержит обещание об общем поведении класса и обещание относительно того, какие другие методы класса будут доступны.

Короче говоря, иногдажелательно иметь возможность проверять свойства сопоставления, используя isinstance.

...