2

Unicode をサブクラス化すると、3.3 より前の Python では非推奨の警告が発生し、Python 3.3 ではエラーが発生する状況に遭遇しました。

# prove that unicode.__init__ accepts parameters
s = unicode('foo')
s.__init__('foo')
unicode.__init__(s, 'foo')

class unicode2(unicode):
    def __init__(self, other):
        super(unicode2, self).__init__(other)

s = unicode2('foo')

class unicode3(unicode):
    def __init__(self, other):
        unicode.__init__(self, other)

s = unicode3('foo')

興味深いことに、警告/エラーは最初の 3 行では発生しませんが、代わりに 8 行目と 14 行目で発生します。Python 2.7 での出力は次のとおりです。

> python -Wd .\init.py
.\init.py:8: DeprecationWarning: object.__init__() takes no parameters
  super(unicode2, self).__init__(other)
.\init.py:14: DeprecationWarning: object.__init__() takes no parameters
  unicode.__init__(self, other)

コードは、問題を例示するために単純化されています。実際のアプリケーションでは、単に super を呼び出すだけではありません__init__

最初の 3 行から、Unicode クラスが実装__init__し、そのメソッドが少なくとも 1 つのパラメーターを受け入れることがわかります。ただし、サブクラスからそのメソッドを呼び出したい場合、呼び出すかどうかに関係なく、そうすることができないようsuper()です。

unicode.__init__Unicode インスタンスを呼び出しても問題ないのに、Unicode サブクラスを呼び出せないのはなぜですか? unicode クラスをサブクラス化する場合、作成者は何をする必要がありますか?

4

1 に答える 1

4

unicode問題は不変であるという事実に起因すると思われます。

インスタンスの作成後は、unicode変更できません。そのため、初期化ロジックは、(インスタンスが存在した後にのみ呼び出される__new__) メソッドではなく、(インスタンスの作成を行うために呼び出される) メソッドに含まれます。__init__

不変型のサブクラスには同じ厳密な要件がないため、必要に応じて実行できますunicode2.__init__が、呼び出しunicode.__init__は不要です (おそらく、とにかく実行すると思われることは実行されません)。

より良い解決策は、おそらく独自の__new__方法でカスタマイズされたロジックを実行することです。

class unicode2(unicode):
    def __new__(cls, value):
        # optionally do stuff to value here
        self = super(unicode2, cls).__new__(cls, value)
        # optionally do stuff to self here
        return self

__setattr__必要に応じて、常に例外を発生させるメソッドをクラスに与えることで、クラスを不変にすることもできます( __slots__per-instance を省略してメモリを節約するプロパティをクラスに与えることもできます__dict__)。

于 2013-02-09T01:28:23.520 に答える