3

親のinitメソッドを呼び出す複数のスーパークラスを持つサブクラスで問題が発生しています。バインドされていない__init__親のインスタンスが必要であるというエラーが表示されますが、子のインスタンスが取得されました。StackOverflow に関する他のいくつかの質問は、これが複数回定義されている親クラスからのものであることを指摘しており、インタープリターに入力された単純なスクリプトで確認しました。

注:これは私が質問しているコードではありません。これは、Base クラスが再定義され、継承されたクラスが正しく機能しなくなるという問題を説明するための例です。

>>> class Base(object):
...     def __init__(self):
...             print "Base!"
... 
>>> class Inherited(Base):
...     def __init__(self):
...             Base.__init__(self)
...             print "Inherited"
... 
>>> class Base(object):
...     def __init__(self):
...             print "Base!"
... 
>>> Inherited()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: unbound method __init__() must be called with Base instance as first argument (got Inherited instance instead)
>>> 

私の質問は、基本クラスが複数回定義されないようにするにはどうすればよいですか? 私が取り組んでいるプロジェクトには複数のファイルとインポートがあるため、すべてをリファクタリングしてファイルを 1 回だけ含めることは困難です。

4

2 に答える 2

3

この振る舞いは私には非常に怪しいようです。同じモジュールを異なる方法でインポートしても、クラス ( Base) は同じクラス オブジェクトを参照します。インポートによってこの状況に陥る可能性は低いようです。

ただし、回避策の 1 つは次を使用することsuperです。

class Base(object):
    def __init__(self):
            print "Base!"

class Inherited(Base):
    def __init__(self):
            super(Inherited,self).__init__()
            print "Inherited"

class Base(object):
    def __init__(self):
            print "Base!"

Inherited()

super__init__現在のモジュールの名前空間で基底クラスの代わりになった他のクラスではなく、実際に基底クラスを呼び出していることを確認します。

于 2012-12-17T13:53:12.380 に答える
3

上記で特定した問題は、クラス定義としてInheritedの元の定義 (最初に定義したもの) のサブクラスBaseが、読み取られるときに処理されるためです。

ただし、実行時に__init__は、2 番目の定義のBaseが使用されます。このクラスは、それ自体のインスタンスを想定していますが、代わりに の最初の定義のインスタンスを受け取りますBase

このように入力すると、インタープリターはそれらが同じクラスであることを知る方法がありません。しかし、ファイルからインポートする場合、Python はファイルが 2 回インポートされたときにクラスが同じであることを認識できるほど賢いため、この問題は発生しません。

あなたのコードで何か他のことが起こっているので、あなたのユースケースにもっと具体的に見ることが役に立ちます. この問題は、複数のモジュールで同じ名前のクラスを定義し、それらを同じ名前空間にインポートした場合にのみ発生します。

于 2012-12-17T13:56:16.493 に答える