3

strインスタンス変数を追加して、に基づいた単純な派生クラスを作成しようとしていますflag。理解できない理由で、フラグをコンストラクターに渡そうとするとエラーが発生します。

>>> class Strvalue(str):
        def __init__(self, content, flag=None):
                str.__init__(self, content)
                self.flag = flag

>>> Strvalue("No problem")
'No problem'

>>> Strvalue("Problem", flag=None)
Traceback (most recent call last):
  File "<pyshell#113>", line 1, in <module>
    Strvalue("Problem", flag=None)
TypeError: str() takes at most 1 argument (2 given)

成功した呼び出しで、コンストラクターが実際に呼び出されることを確認しました。タイプミスやそのようなものはStrvalueありません。__init__では、何が起こっているのでしょうか。

編集:この質問(および@Martijnの回答)によると、この問題はオーバーライド__new__することでも回避できます。問題は、なぜこれが起こったのかということでした。

4

2 に答える 2

2

サブクラス化するとき__new__の代わりに使用する必要があります。基本的なカスタマイズを参照してください。__init__str

>>> class Strvalue(str):
...     def __new__(cls, content, flag=None):
...         inst = str.__new__(cls, content)
...         inst.flag = flag
...         return inst
... 
>>> Strvalue('foo', True)
'foo'
>>> foo = Strvalue('foo', True)
>>> foo
'foo'
>>> foo.flag
True

コードはオーバーライドしないstr.__new__ため、元のstr.__new__コンストラクターは2つの引数を使用して呼び出され、1つだけを受け入れます。

strオブジェクトは不変であり、で新しいインスタンスを構築します__new__。その後、オブジェクトを変更することはできません。__init__と呼ばれるまでに、はself不変オブジェクトであるため__init__、forstrは意味がありません。メソッドを定義することでき__init__ますが、すでに持っているので__new__、実際には作業を2つのメソッドに分割する必要はありません。

于 2012-09-22T23:49:01.897 に答える
1

__new__の代わりに(または同様に)オーバーライドする必要があります__init__

于 2012-09-22T23:49:06.453 に答える