0

このようなコードスニペットがあります

class A(object):
    class b:
        def print_hello(self):
            print "Hello world"
    b = property(b)

bそして、内部クラス(小文字の名前は気にしないでください) の動作をオーバーライドしたいと考えています。たとえば、次のように、新しいメソッドを追加したり、既存のメソッドを変更したりします。

class C(A):
    class b(A.b):
        def print_hello(self):
            print "Inner Class: Hello world"
    b = property(b)

Cのオブジェクトを として作成しc = C()、呼び出すc.bと、 が得られTypeError: 'property' object is not callable errorます。print_helloこれを渡して拡張内部クラスを呼び出すにはどうすればよいですか? 免責事項:Aクラスのコードを変更したくありません。

更新: 基本クラス 'A' は、オープンソース API の 1 つで見たクラスをシミュレートしようとします。そのため、コア API を変更したくありませんが、自分の要件に合わせて拡張します。

4

3 に答える 3

1

これが失敗する理由は、b = property(b)行Abが定義したクラスではなく、プロパティオブジェクトであるためです。クラスの作成に失敗しないことに少し驚いています。A.b.fget基本クラスとして使用すると機能します。しかし、正解は次のようになります。そうしないでください。Pythonには通常の意味での内部クラスはありません。クラス定義スコープで定義されたクラスは、通常のクラスと同じです。実際、このコードの最終結果はまったく同じです。

class A(object):
    pass

class b(object):
    def print_hello(self):
        print("Hello world")

A.b = property(b)

あなたが何を達成しようとしているのか正確にはわかりません。私が正しく理解していれば、別のクラスのインスタンスを返すプロパティを持つ親クラスがあり、他のクラスのサブクラスのインスタンスを返すプロパティを持つサブクラスが必要です。返されたクラスをサブクラス化するには、そのクラスへの参照を取得して、それをベースとして使用する必要があります。次に、プロパティをオーバーライドして、サブクラスのインスタンスを返すことができます。インスタンスからクラスを検索するプロパティを使用する場合、実際にはプロパティ定義をオーバーライドする必要はありません。

class A(object):
    class B(object):
        def print_hello(self):
            print("Hello from A.B")
    b = property(lambda self: self.B())

class C(A):
    class B(A.B):
       def print_hello(self):
           print("Hello from C.B")

A().b.print_hello()
C().b.print_hello()
于 2010-04-23T09:01:43.937 に答える
1

内部クラスを外部クラスのプロパティとして定義する理由がよくわかりません。(私は Python の専門家ではないので、私が認識していない理由があるかもしれません)。

プロパティがなくてもうまくいくようです:

class A(object):
    class b:
        def print_hello(self):
            print "A Hello world"

class C(A):
    class b(A.b):
        def print_hello(self):
            print "C Hello world"


outer = C()
inner = outer.b()
inner.print_hello() # prints "C Hello world"
于 2010-04-23T08:17:39.800 に答える
0

Aの'b'プロパティにアクセスするたびに、Aインスタンスへの参照がゲッターに渡されます。ゲッターは引数としてbのコンストラクターに渡されます。bの(デフォルトの)コンストラクターは余分な引数をとらないため、これは最初から構造を壊します。

内部の「b」クラスはAの「b」プロパティオブジェクトを継承しているため、Cクラスは機能していないようです。

なぜここに物件が必要なのか知りたいのですが、それは物事を複雑にするだけです。実際、これを削除すると、継承にまったく頼ることなく、インスタンスごとにAの内部の「b」クラスを別のクラスに置き換えることができます。この建設の背後にある意図や目的など、協力するための情報をもう少し教えていただけますか?

于 2010-04-23T08:55:58.987 に答える