0

クラスを作成するコードがあるとします。

class Item:
    def __init__(self, param1):
        do something with param1

ここで、そのクラスから継承し、その初期化関数を継承するオブジェクト ItemChild があるとします。つまり、Item の__init__関数を呼び出すコードがあります。しかし、その関数でもっと多くのことを行いたいとしましょう。また__init__、より多くのパラメーター (param1、param2、param3、および param4) で動作するようにしたいとします。親の__init__関数への呼び出しが混乱するようです。なぜなら、params 1-3 を ItemChild のインスタンスに渡すと、どのパラメーターが param1 であるかがわからないからです。これを回避する方法はありますか、または初期化メソッドの継承はそのメソッドに限定されており、拡張できませんか?

4

3 に答える 3

3

実際には逆に動作します -ItemChild__init__メソッドが最初に呼び出され、 に適切なものだけを転送できますItem:

class Item:
    def __init__(self, param1):
        print "Item.__init__ doing something with param1"
        # do something with param1


class ItemChild(Item):
    def __init__(self, param1, param2, param3):
        print "Starting ItemChild.__init__"
        super(ItemChild, self).__init__(param1)
        print "ItemChild.__init__ doing something with params 2 and 3"
        # do something with param2 and param3

呼び出す場合ItemChild(1, 2, 3)の流れは次のとおりです。

Starting ItemChild.__init__
Item.__init__ doing something with param1
ItemChild.__init__ doing something with params 2 and 3

いいえ:

Item.__init__ doing something with param1
Starting ItemChild.__init__
ItemChild.__init__ doing something with params 2 and 3

もちろん、super呼び出しを再配置して、他のことを行う前または後に実行することもできます。または、親の動作を実行させたくない場合は、呼び出しを完全に除外することもできます。

于 2013-01-08T22:06:25.027 に答える
3

このようなシナリオを処理する適切な方法は次のとおりです。

class Item(object):
    def __init__(self, param1):
        # do something with param1

class ItemChild(Item):
    def __init__(self, param1, param2, param3, param4):
        super(ItemChild, self).__init__(param1)
        # do something with params

新しいスタイルのクラスでのみ機能するため、Item継承objectは重要であることに注意してください。super()

コメントで述べたように、3.x では への引数を含める必要はなく、super()単に を使用できますsuper().__init__(param1)

于 2013-01-08T22:08:01.800 に答える
2

いいえ、必要に応じて子の引数を委任するだけ__init__です。

class Parent(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Child(Parent):
    def __init__(self, w, x, y, z):
        Parent.__init__(self, x, y)
        self.w = w
        self.z = z

p = Parent(1, 2)
# p.x == 1
# p.y == 2
c = Child(1, 2, 3, 4)
# c.w = 1
# c.x = 2
# c.y = 3
# c.z = 4

super他の例で述べたように使用することもできます。ほとんどの場合、それは主に個人的な好みの問題ですが、より高度なクラスの設計を開始すると、違いが重要になります。 superクラスの親のメソッドを MRO 順に検索し、__init__()必要に応じて協調的に呼び出します。スーパークラスの__init__()メソッドを直接呼び出すと、明示的な制御のためにいくつかの自動機能が犠牲になります。また、 では、子が発見するsuperすべてのメソッドが互換性のある署名を持つように注意する必要があります。そうしないと、例外が発生します。__init__()

于 2013-01-08T22:05:16.753 に答える