【问题标题】:Inherit builtin `str` class in python在python中继承内置的`str`类
【发布时间】:2019-02-05 09:25:42
【问题描述】:

我正在尝试使用自定义类型继承 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: 

【问题讨论】:

  • 你需要实现__new__,这是首先调用的。
  • @jonsharpe 我像这样使用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,但没有任何反应。
  • 什么意思“什么都没发生”?您不再收到错误消息(这可能是一件好事)?您可能看不到任何东西,因为您的实例看起来像一个空字符串。
  • 如果您不向str.__new__ 传递任何参数,您的所有MyStr 实例都将为空字符串。
  • 这并不能说明您描述的问题,为什么您认为ms 没有继承方法?正如我和@Aran-Fey 所提到的,您对__new__ 的使用正在构建一个empty 字符串(带有一些额外的属性)。另请注意,如果word 是您实际希望字符串具有的值,则无需将其存储为属性。

标签: python python-3.x oop


【解决方案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 

我基本上同意那些建议不要在一般原则上这样做的评论者(这很棘手,你的代码对其他人来说不容易理解)。但它确实有效。

【讨论】:

    猜你喜欢
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 2011-08-01
    • 2010-12-12
    • 2011-08-28
    • 1970-01-01
    • 2016-03-31
    相关资源
    最近更新 更多