はじめに
この実験では、Python のクラスとオブジェクトについて学びます。クラスはオブジェクトを作成するためのテンプレートです。オブジェクトはクラスのインスタンスです。
学習目標
- 名前とオブジェクト
- スコープと名前空間
- インスタンスオブジェクト
- メソッドオブジェクト
- 継承
- プライベート変数
この実験では、Python のクラスとオブジェクトについて学びます。クラスはオブジェクトを作成するためのテンプレートです。オブジェクトはクラスのインスタンスです。
Python でクラスを定義するには、class
キーワードの後にクラス名を記述します。
クラス定義には __init__
メソッドを含める必要があります。これは、クラスからオブジェクトが作成されるときに呼び出される Python の特殊メソッドです。
新しい Python インタープリタを開きます。
python3
以下は、円を表すクラスの例です。
class Circle:
def __init__(self, radius):
self.radius = radius
__init__
メソッドは radius
パラメータを受け取り、それをオブジェクトの radius
属性に割り当てます。
クラスからインスタンスオブジェクトを作成するには、クラス名の後に括弧を付けて呼び出します。これを「インスタンス」と呼ぶのは、クラスの具体的な実例であるからです。
circle1 = Circle(5)
これにより、半径が 5
の Circle
型のインスタンスオブジェクト circle1
が作成されます。インスタンスオブジェクトは、オブジェクトに固有のデータを格納するために使用できます。たとえば、各 Circle
オブジェクトは異なる半径を持つことができます。
前のステップで定義した __init__
メソッドは、オブジェクトが作成されると自動的に呼び出され、オブジェクトの radius
属性は値 5
で初期化されます。
__init__
メソッドは、オブジェクトの初期状態を設定するためによく使用されます。たとえば、オブジェクトの属性を初期化したり、外部リソースへの接続を設定したりします。オブジェクトが作成されると自動的に呼び出されるため、自分で呼び出す必要はありません。
__init__
メソッドは通常のメソッドであり、任意の名前を付けることができることに注意してください。ただし、クラスの初期化メソッドであることを明確にするために、__init__
を使用することが推奨されています。
オブジェクトの属性にアクセスするには、ドット表記を使用します。たとえば、circle1
オブジェクトの半径にアクセスするには、次のコードを使用できます。
print(circle1.radius) ## Output: 5
属性に新しい値を割り当てることで、オブジェクトの属性を変更することができます。たとえば、circle1
オブジェクトの半径を変更するには、次のコードを使用できます。
circle1.radius = 10
print(circle1.radius) ## Output: 10
メソッドは、クラス内で定義された関数で、オブジェクトの属性に格納されたデータに対して操作を行うために使用されます。Python では、メソッドは def
キーワードの後にメソッド名とパラメータのリストを記述して定義されます。
以下は、Circle
クラス内で定義された area
メソッドの例です。
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
area
メソッドは、円の半径に基づいてその面積を計算します。これは、メソッドが呼び出されたオブジェクトの半径を参照する self.radius
属性を使用して行われます。
オブジェクトに対してメソッドを呼び出すには、ドット表記の後にメソッド名と括弧を付けます。たとえば、circle1
オブジェクトに対して area
メソッドを呼び出すには、次のコードを使用できます。
circle1 = Circle(15)
print(circle1.area()) ## Output: 706.5
これにより、Circle
クラスの特定のインスタンスである circle1
オブジェクトの面積が出力されます。
メソッドは、クラス内に機能をカプセル化し、オブジェクトの属性に格納されたデータを操作する方法を提供するのに役立ちます。
初心者は括弧の使い方に特に注意する必要があります。 括弧はオブジェクトに対してメソッドを呼び出すために使用され、またメソッドにパラメータを渡すためにも使用されます。これは最初は混乱するかもしれませんが、クラスとオブジェクトについて学習を続けるうちに明確になるでしょう。
インスタンスオブジェクトとメソッドオブジェクトは、Python の主な 2 種類のオブジェクトです。要するに、インスタンスオブジェクトはクラスから作成され、メソッドオブジェクトはクラス内で定義されます。
継承は、既存のクラスを修正した新しいクラスを作成する方法です。新しいクラスをサブクラス(サブクラス)と呼び、既存のクラスをスーパークラス(親クラス)と呼びます。
継承を使用すると、スーパークラスのすべての属性とメソッドを持つサブクラスを作成できます。また、サブクラスに追加の属性やメソッドを追加したり、スーパークラスの属性やメソッドをオーバーライドしたりすることもできます。
以下は、Circle
クラスを継承したサブクラス Cylinder
の例です。
class Cylinder(Circle):
def __init__(self, radius, height):
super().__init__(radius)
self.height = height
Cylinder
クラスには、radius
と height
の 2 つのパラメータを受け取る __init__
メソッドがあります。このメソッドは、super()
関数を使用して Circle
クラスの __init__
メソッドを呼び出し、オブジェクトの radius
属性を初期化し、その後オブジェクトの height
属性を設定します。
super()
関数は、Python の特殊な関数で、クラスのスーパークラスを参照します。サブクラス内からスーパークラスのメソッドを呼び出すために使用されます。
super()
関数はクラス定義内で定義され、作成されるオブジェクトを参照する self
パラメータを受け取ります。呼び出されるメソッドに応じて、追加のパラメータを受け取ることもできます。この例では、radius
パラメータを Circle
クラスの __init__
メソッドに渡し、オブジェクトの radius
属性を初期化します。
Cylinder
クラスは、Circle
クラスのすべての属性とメソッドに加えて、追加の height
属性を持っています。Circle
クラスと同じように、ドット表記を使用して Cylinder
クラスの属性やメソッドにアクセスできます。
たとえば、Cylinder
オブジェクトを作成し、その属性にアクセスするには、次のようにします。
cylinder1 = Cylinder(5, 10)
print(cylinder1.radius) ## 5 を出力
print(cylinder1.height) ## 10 を出力
継承は、オブジェクト指向プログラミングにおいてコードを再利用し、クラスの階層を作成するのに便利な機能です。
super()
関数は、サブクラスでスーパークラスのコードを再利用し、追加の機能で拡張したい場合に便利です。
super()
関数はスーパークラスへの静的な参照ではないことに注意する必要があります。これは、呼び出されるクラスに応じて変化する動的な参照です。これにより、複数レベルの継承で継承を使用し、各レベルで正しいスーパークラスにアクセスすることができます。
たとえば、次のクラスを考えてみましょう。
class A:
def method(self):
print("A method")
class B(A):
def method(self):
super().method()
print("B method")
class C(B):
def method(self):
super().method()
print("C method")
ここで、C
は B
のサブクラスで、B
は A
のサブクラスです。C
オブジェクトで method
メソッドを呼び出すと、まず super()
関数を使用して A
クラスの method
メソッドが呼び出され、次に super()
関数を使用して B
クラスの method
メソッドが呼び出され、最後に C
クラスの method
メソッドが呼び出されます。
obj = C()
obj.method() ## 「A method」、「B method」、「C method」を出力
super()
関数は、オブジェクト指向プログラミングにおいてコードを再利用し、クラスの階層を作成するのに便利な機能です。
Python では、プライベート変数は、定義されたクラス内でのみ使用されることを意図した変数であり、外部コードからは使用されないようになっています。プライベート変数は、クラスの外部から直接アクセスすることはできません。
Circle
クラスでプライベート変数を定義するには、変数名の前に二重アンダースコア (__
) を付けます。たとえば:
class Circle:
def __init__(self, radius):
self.__radius = radius
これにより、Circle
クラス内にプライベート変数 __radius
が定義されます。
プライベート変数は、定義されたクラス内でのみ使用されることを意図しています。クラスの外部から直接アクセスすることはできません。たとえば、Circle
クラスの外部から __radius
変数にアクセスしようとすると、エラーが発生します:
circle1 = Circle(5)
print(circle1.__radius) ## これは AttributeError を引き起こします
プライベート変数は、クラス内にデータをカプセル化し、外部コードがそれを変更する能力を制限するのに役立ちます。ただし、Python ではプライベート変数は真にプライベートではなく、「名前修飾 (name mangling)」を使用してクラスの外部からアクセスすることができることに注意する必要があります。
名前修飾は、変数名に特別な接頭辞を付けて、クラスの外部からアクセスしにくくする手法です。
たとえば、__radius
変数は、次の構文を使用して Circle
クラスの外部からアクセスすることができます:
print(circle1._Circle__radius) ## これは 5 を出力します
ただし、これは良いプログラミング慣行とは見なされず、避けるべきです。
代わりに、プライベート変数は定義されたクラス内でのみ使用し、必要に応じてデータにアクセスまたは変更するためのパブリックメソッドを提供する必要があります。
以下は、プライベートな __radius
変数と、半径にアクセスおよび変更するためのパブリックメソッドを持つ Circle
クラスの例です:
class Circle:
def __init__(self, radius):
self.__radius = radius
def get_radius(self):
return self.__radius
def set_radius(self, radius):
self.__radius = radius
Circle
オブジェクトの半径にアクセスするには、get_radius
メソッドを使用できます:
circle1 = Circle(5)
print(circle1.get_radius()) ## 5 を出力
Circle
オブジェクトの半径を変更するには、set_radius
メソッドを使用できます:
circle1.set_radius(10)
print(circle1.get_radius()) ## 10 を出力
この実験では、Python のクラスとオブジェクトについて学びました。クラスを定義する方法、クラスからオブジェクトを作成する方法、オブジェクトの属性やメソッドにアクセスする方法、オブジェクトの属性を変更する方法、およびスーパークラスを継承したサブクラスを作成する方法を学びました。
この実験でカバーされた主要な概念の概要は次のとおりです。
__init__
メソッドは、クラスからオブジェクトが作成されるときに呼び出されます。これにより、オブジェクトの属性を設定することができます。この実験が Python のクラスとオブジェクトについての学習に役立ったことを願っています。何か質問があれば、教えてください!