继承python中的内置`str`类

时间:2019-02-05 09:25:42

标签: python python-3.x oop

我试图继承具有自定义类型的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 :(得分:1)

请勿将关键字参数用作字符串的值。只需使用一个位置参数。函数签名将为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 

我基本上同意那些建议不要遵循一般原则的评论者(这很棘手,别人很难理解您的代码)。但这确实有效。