Python のスーパー引数

Abid Ullah 2023年6月21日
  1. Python のスーパー引数
  2. Super Uses Inheritance コンセプト
  3. Python でのスーパー引数の正確な使用法
  4. Super を使用して Python 多重継承のコンストラクターに引数を渡す
Python のスーパー引数

この記事の主題は、Python の super 引数を正しく使用することです。 また、super と継承の概念、super 引数を使用したコードの適切な例、および基本クラスの概念についても学習します。

Python のスーパー引数

Python では、super は別のクラスのメソッドを呼び出します。 クラスが別のクラスから継承される場合、親クラス、基本クラス、またはスーパークラスと呼ばれます。

親クラスに直接行き、そのメソッドを呼び出すので、 super を使用するのは非常に簡単です。

super には引数を渡すことができます。 クラスとクラス インスタンスの 2つの引数を取ります。

コード例:

class A:
    def roo(self):
        return "roo() from A"


class B(A):
    def roo(self):
        print("roo() from B")
        return super().roo()


class C(A):
    def roo(self):
        print("roo() from C")
        return super().roo()


class D(B, C):
    def roo(self):
        print("roo() from D")
        return super(C, self).roo()


a = A()
b = B()
c = C()
d = D()
print(a.roo())
print(b.roo())
print(c.roo())
print(d.roo())

出力:

roo() from A
roo() from B
roo() from A
roo() from C
roo() from A
roo() from D
roo() from A

Super Uses Inheritance コンセプト

オブジェクト指向プログラミングの概念に慣れていない場合、継承はなじみのないものに思えるかもしれません。 オブジェクト指向プログラミングでは、継承とは、属性と動作を別のクラスから再実装せずに派生 (または継承) するクラスの機能を指します。

これらの概念を理解するための便利な方法は、コードを見ることです。そのため、いくつかの形状を記述するクラスをいくつか作成しましょう。

コード例:

class Rectangle_Shape:
    def __init__(self, len, wid):
        self.length = len
        self.width = wid

    def area(self):
        return self.length * self.width

    def perimeters(self):
        return 2 * self.length + 2 * self.width


class Square_Shape:
    def __init__(self, len):
        self.length = len

    def area(self):
        return self.length * self.length

    def perimeters(self):
        return 4 * self.length


s = Square_Shape(4)
print(s.area())
r = Rectangle_Shape(3, 5)
print(r.area())

このクラスには、Rectangle_ShapeSquare_Shape の 2つの対応するクラスがあります。

出力:

16
15

この例は、相互に関連する 2つの形状を示しています。正方形は長方形の一種です。 コードはその関係を反映していないため、本質的にコードが繰り返されます。

継承を使用すると、記述するコードの量を減らすと同時に、長方形と正方形の間の実世界の関係を反映できます。

コード例:

class Rectangle_Shape:
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

    def perimeters(self):
        return 2 * self.length + 2 * self.width


# Making the Square_Shape class that initiates the Rectangle_Shape class
class Square_Shape(Rectangle_Shape):
    def __init__(self, len):
        super().__init__(len, len)


s = Square_Shape(4)
print(s.area())

この場合、super()Rectangle_Shape クラスの init() を呼び出します。これは、コードを書き直すことなく Square_Shape クラスで使用されます。

出力:

16

例に示すように、Rectangle_Shape が親クラスで、Square_Shape が子クラスです。

Python でのスーパー引数の正確な使用法

クラス MN、および O のコードは以下のとおりです。

class M:
    def __init__(self):
        print("M initiated successfully")


class N(M):
    def __init__(self):
        super().__init__()
        print("N initiated successfully")


class O(N):
    def __init__(self):
        super(O, self).__init__()
        print("O initiated successfully")


o = O()

上記のコードが想定しているように、すべてのクラスは直接の親である init() メソッドをオーバーロードします。 super() は属性を必要としないため、引数なしで使用するだけで十分です。

出力:

M initiated successfully
N initiated successfully
O initiated successfully

クラス M2Ninit() メソッドをジャンプさせ、代わりに Minit() メソッドを実行させたいとします。 クラスの直接の親が N であるにもかかわらず、init() メソッドは N ではなく M から継承する必要があります。

ここにクラス M2 があります。 その実行を見てみましょう。

class M:
    def __init__(self):
        print("M initiated successfully")


class N(M):
    def __init__(self):
        super().__init__()
        print("N initiated successfully")


class O(N):
    def __init__(self):
        super(O, self).__init__()
        print("O initiated successfully")


class M2(N):
    def __init__(self):
        super(N, self).__init__()
        print("other O initiated successfully")


m2 = M2()

上記のコードから、今度は属性を super() メソッドに渡して正しいスーパークラスを選択すると想定できます。 m2 = M2() を実行した結果、次の出力が得られます。

M initiated successfully
other O initiated successfully

直接の親である __init__() メソッドを呼び出す代わりに、代わりに Minit() Python メソッドを呼び出しました。

super()[name] などのこれらのステートメントまたは演算子を使用した暗黙的なルックアップの場合、super() は定義されていません。

さらに、super() は、ゼロ引数形式以外の内部メソッドの使用に限定されません。 引数が 2つの形式を使用すると、引数が正確に識別され、適切な参照が作成されます。

クラス定義では、コンパイラがクラスとインスタンスを取得するために必要な詳細を入力するため、ゼロ引数のみが機能します。

Super を使用して Python 多重継承のコンストラクターに引数を渡す

一般にさまざまな継承を扱う場合、基本クラスは複数の継承用に設計する必要があります。

2つのクラスのパラメーター名が似ている場合があります。 その場合、キーと値のペアを **kwargs から削除したり、*args から削除したりすることはできません。

オブジェクトとは異なり、引数を吸収/無視する Base クラスを定義することが可能です。

コード例:

class Base(object):
    def __init__(self, *args, **kwargs):
        pass


class P(Base):
    def __init__(self, *args, **kwargs):
        print("P")
        super(P, self).__init__(*args, **kwargs)


class Q(Base):
    def __init__(self, *args, **kwargs):
        print("Q")
        super(Q, self).__init__(*args, **kwargs)


class R(P):
    def __init__(self, arg, *args, **kwargs):
        print("R", "arguments=", arg)
        super(R, self).__init__(arg, *args, **kwargs)


class S(Q):
    def __init__(self, arg, *args, **kwargs):
        print("S", "arguments=", arg)
        super(S, self).__init__(arg, *args, **kwargs)


class T(R, S):
    def __init__(self, arg, *args, **kwargs):
        print("T", "arguments=", arg)
        super(T, self).__init__(arg, *args, **kwargs)
        print("MRO---", [x.__name__ for x in T.__mro__])


t = T(10)

出力:

T arguments= 10
R arguments= 10
P
S arguments= 10
Q
MRO--- ['T', 'R', 'P', 'S', 'Q', 'Base', 'object']

これが機能するには、BaseMRO の最後から 2 番目のクラスでなければならないことに注意することが重要です。

Python プログラミング言語は、オブジェクト指向プログラミングのための幅広い機能を提供します。 そのセットでは、super 関数の引数は、特に正しく使用された場合に重要な役割を果たします。

この記事が、Python で super 関数の引数を使用する方法をよりよく理解するのに役立つことを願っています。

著者: Abid Ullah
Abid Ullah avatar Abid Ullah avatar

My name is Abid Ullah, and I am a software engineer. I love writing articles on programming, and my favorite topics are Python, PHP, JavaScript, and Linux. I tend to provide solutions to people in programming problems through my articles. I believe that I can bring a lot to you with my skills, experience, and qualification in technical writing.

LinkedIn

関連記事 - Python Argument