Наследовать встроенный класс `str` в python - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь наследовать модуль str с пользовательским типом, но при этом выдает ошибку.

class MyStr(str):
    def __init__(self, word, idx: int=0):
        super().__init__()
        self._word = word
        self._idx = idx


if __name__ == '__main__':
    x = MyStr(word='Word', idx=1)
    print(x)

Эта ошибка возникает

Traceback (most recent call last):
File "C:/Users/admin/Desktop/xyz.py", line 9, in <module>
   x = MyStr(word='Word', idx=1)
TypeError: 'word' is an invalid keyword argument for this function

Итак, как наследовать str модуль с пользовательскими параметрами.

Я пробовал этот метод для наследования всех методов и атрибутов.

class MyStr(str):

    def __new__(cls, *args, **kwargs):
        return str.__new__(cls)

    def __init__(self, word, idx: int=0):
        super().__init__()
        self._word = word
        self._idx = idx

    @property
    def idx(self):
        return self._idx

    @property
    def word(self):
        return self._word


if __name__ == '__main__':
    ms = MyStr(word='snake', idx=10)
    print(ms)

Так что я ожидаю вывод как: -

Expecting Output:
    Str: snake

But this give this 
    Str: 

1 Ответ

0 голосов
/ 05 февраля 2019

Не используйте аргумент ключевого слова для значения строки.Просто используйте один позиционный аргумент.Сигнатура функции будет MyStr (s, idx = 0), где s - значение строки.

(1) В вашей реализации __new__ не передавайте аргумент ключевого слова.str.__new__ не будет знать, что с ним делать.Оба аргумента будут переданы __init__.

(2) В вашей реализации __init__ просто проигнорируйте первый аргумент.Он уже использовался для инициализации строки функцией str.__new__.Все, что вам нужно сделать, это сохранить аргумент idx в новой переменной.

(3) Просто избавьтесь от свойства .word.У вас уже есть строка, поэтому свойство .word ничего не добавляет.

Новый экземпляр будет вести себя как строка и будет иметь все методы строки.Он также будет иметь свойство idx.

class MyStr(str):
    def __new__(cls, s, idx=0):
        return super().__new__(cls, s)
        # less good style is: str.__new__(cls, s)

    def __init__(self, s, idx: int=0):
        super().__init__()
        self._idx = idx

    @property
    def idx(self):
        return self._idx

if __name__ == '__main__':
    ms = MyStr('snake', idx=10)
    print(ms, ms.idx)
    print(ms.upper())

# Output:
# snake 10
# SNAKE 

Я в основном согласен с теми комментаторами, которые не рекомендовали делать это на общих принципах (это сложно, и ваш код будет непростым для понимания кем-то еще).Но это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...