Вызвать версию метода текущего класса в Python - PullRequest
1 голос
/ 10 мая 2019

У меня есть иерархия наследования двух классов:

class TfIdfSimilarity(SimilarityModel):
    @property
    def corpus(self):
        return self.model[self._corpus]

    @property
    def model(self):
        return TfidfModel(self._corpus, dictionary=self._dict)


class LsiSimilarity(TfIdfSimilarity):
    @property
    def corpus(self):
        tfidf_corpus = super().corpus
        return self.model[tfidf_corpus]

    @property
    def model(self):
        tfidf_corpus = super().corpus
        return LsiModel(tfidf_corpus)

Однако, это вызывает бесконечную ошибку рекурсии, потому что всякий раз, когда я пытаюсь получить LsiSimilarity#model, он вызывает TfIdfSimilarity#corpus, что затемпытается получить доступ к модели и, таким образом, снова вызывает LsiSimilarity#model.

Что я на самом деле хочу, так это чтобы TfIdfSimilarity#corpus только когда-либо вызывал TfIdfSimilarity#model, и никогда не рассматривал его версию дочернего класса.

Возможно ли это в Python?(Python 3) Если нет, как я могу лучше структурировать мою иерархию наследования, в то же время предоставляя тот же API через функции corpus и model (которые используются моей основной логикой).

Ответы [ 2 ]

2 голосов
/ 10 мая 2019

Вы можете вызывать дескрипторы напрямую , получив ссылку на дескриптор из класса и затем вызвав метод __get__ дескриптора:

TfIdfSimilarity.model.__get__(self)

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

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

Вы всегда можете указать, какой метод вы хотите вызвать, используя вместо self.method_xy вызов с SpecificClass.method(self, other_arguments).

Сначала я пропустил значение декоратора свойств и переключился на решение с вызовом __get__ (TfIdfSimilarity.model.__get__(self)), но, поскольку это вызов частного метода, решение мне не понравилось.

Вдохновленный этим Как вызвать свойство базового класса, если это свойство перезаписывается в производном классе? , я нашел метод fget:

Минимальный пример

class Test:
    def __init__(self, text):
        self._text = text

    @property
    def text(self):
        return self._text

class InheritTest(Test):

    @property
    def text(self):
        return "test" + self._text    


test = InheritTest("Test")
print(Test.text.fget(test))
# Test
print(test.text)
# testTest
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...