Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonのオブジェクト指向プログラミング入門:クラス・インスタンス・カプセル化の基礎を解説

Pythonは、誕生当初からオブジェクト指向プログラミング言語として設計されてきました。クラスとオブジェクトは、オブジェクト指向プログラミングにおける2つの主要な構成要素です。

クラスは新しい型のオブジェクトを作り出すための設計図であり、そのクラスから生成された個々の実体が「インスタンス(オブジェクト)」と呼ばれます。

それでは、最もシンプルなクラスを作成してみましょう。

Pythonでクラスを定義する

まず、空のクラスを定義してみます。

# クラスを定義する
class Vehicle():
    pass  # 空のブロック

# オブジェクトのインスタンス化
v = Vehicle()
print(v)

実行結果

<__main__.Vehicle object at 0x055DB9F0>

上記のコードで行ったこと

まず、class文を使って新しいクラス「Vehicle」を作成しました。class文の後にはインデントされたブロックが続き、これがクラスの本体となります。この例では、pass文で示される空のブロックになっています。

次に、Vehicleクラスを使うために、クラス名に続けて括弧 () を付けることで、このクラスのオブジェクト(インスタンス)を生成しました。そして、オブジェクトが正しく作成されたことを確認するために print 関数で出力すると、「__main__モジュール内のVehicleクラスのインスタンスである」という情報が得られます。

オブジェクト(ここでは変数v)はクラスのインスタンスです。それぞれの具体的なオブジェクトは、特定のクラスのインスタンスとなります。1つのクラスからはいくつでもインスタンスを生成でき、各インスタンスはクラスのメソッドやプロパティ(属性)を持ちます。

クラス内で定義されたすべてのメソッドと変数は、そのクラスのオブジェクトからアクセス可能です。

クラス内にメソッドを定義する

class Vehicle():
    def car(self):
        color = 'Red'
        return color

v = Vehicle()
print(v.car())
print(v)

実行結果

Red
<__main__.Vehicle object at 0x05A59690>

インスタンスメソッド

Pythonでは、クラス内にメソッドを定義する際、必ず最初の引数として「self」を指定する必要があります。これは、そのクラスからオブジェクトを生成したとき、そのオブジェクト自身が自動的にメソッドへ渡されることを意味します。

通常、メソッドを呼び出す際には引数selfを明示的に指定しませんが、クラス内でメソッドを定義するときには、必ずselfという引数が必要になります。

具体例で確認してみましょう。

class myClass():
    def myMethod(self):
        return 'Hello'

myInstance = myClass()
print(myInstance.myMethod())

実行結果

Hello

上記のプログラムでは、myClassクラスを定義し、その中にmyMethod()メソッドを定義しています。引数としてはselfのみを受け取ります。

しかし、クラスのインスタンスを通じてメソッドを呼び出す際には、何も引数を渡していません。これは、インスタンスに対してメソッドを呼び出すと、第一引数として自動的にそのインスタンス自身が渡されるためです。

先ほどのプログラムの1行を変更してみましょう。

def myMethod():

メソッドmyMethod()から引数selfを削除しました。プログラムを再実行すると、どうなるでしょうか。

================ RESTART: C:\Python\Python361\oops_python.py ================
Traceback (most recent call last):
File "C:\Python\Python361\oops_python.py", line 18, in <module>
print(myInstance.myMethod())
TypeError: myMethod() takes 0 positional arguments but 1 was given

このようにTypeErrorが発生します。つまり、メソッドの第一引数にselfを指定することは必須なのです。

インスタンス属性

インスタンス属性とは、__init__メソッドのパラメータとして定義される、オブジェクト固有の属性のことです。オブジェクトごとに異なる値を持つことができます。

以下の例を見てみましょう。

import random

class myClass():
    def myMethod(self):
        self.attrib1 = random.randint(1, 11)
        self.attrib2 = random.randint(1, 21)

myInst = myClass()
myInst.myMethod()

print(myInst.attrib1)
print(myInst.attrib2)

実行結果

2
18

上記のプログラムでは、「attrib1」と「attrib2」がインスタンス属性に該当します。ランダムな値が代入されるため、実行するたびに出力結果は変わります。

Pythonのイニシャライザ(コンストラクタ)

コンストラクタとは、クラスのインスタンスメンバーを初期化するために使われる特殊なメソッドです。

コンストラクタには主に2種類あります。

  • パラメータ付きコンストラクタ
  • パラメータなしコンストラクタ

Pythonでは「__init__」が、すべてのPythonクラスに紐付けられた特殊なメソッドです。

Pythonは、クラスからオブジェクトが生成されるたびに、自動的に__init__を呼び出します。その役割は、ユーザーが指定した値でクラスの属性を初期化することです。

オブジェクト指向プログラミングにおいて、このメソッドは「コンストラクタ」と呼ばれます。

class Employee:
    def __init__(self, name):
        self.name = name

    def display(self):
        print("The name of the employee is: ", self.name)

obj1 = Employee('Zack')
obj2 = Employee('Rajesh')
obj3 = Employee('Tashleem')

obj3.display()
obj1.display()

実行結果

The name of the employee is: Tashleem
The name of the employee is: Zack

上記のプログラムでは、Employeeクラスのインスタンス(obj1〜obj3)を生成する際にname引数を渡し、コンストラクタがその引数をインスタンス属性に割り当てています。

したがって、特定のインスタンスに対してdisplayメソッドを呼び出せば、そのインスタンスに対応する名前が表示されます。

Pythonにおけるカプセル化

Pythonは本質的にオブジェクト指向の性質を持っているため、メソッドや変数へのアクセスを制限する仕組みを提供しています。

データカプセル化を適切に行うことで、オブジェクトの属性を外部から直接書き換えることはできなくなります。もし誰でも自由にインスタンス属性を変更できると、アプリケーションは悪意ある攻撃者に対して脆弱になってしまいます。カプセル化によって、インスタンス属性の値を変更できるのは、専用のメソッドを呼び出した場合だけになります。

class Product:
    def __init__(self):
        self.__maxprice = 1000
        self.__minprice = 1

    def sellingPrice(self):
        print('Our product maximum price is: {}'.format(self.__maxprice))
        print('Our product minimum price is: {}'.format(self.__minprice))

    def productMaxPrice(self, price):
        self.__maxprice = price

    def productMinPrice(self, price):
        self.__minprice = price

prod1 = Product()
prod1.sellingPrice()

prod1.__maxprice = 1500
prod1.sellingPrice()

prod1.__minprice = 10
prod1.sellingPrice()

prod1.productMaxPrice(1500)
prod1.sellingPrice()

prod1.productMinPrice(10)
prod1.sellingPrice()

実行結果

Our product maximum price is: 1000
Our product minimum price is: 1
Our product maximum price is: 1000
Our product minimum price is: 1
Our product maximum price is: 1000
Our product minimum price is: 1
Our product maximum price is: 1500
Our product minimum price is: 1
Our product maximum price is: 1500
Our product minimum price is: 10

上記のプログラムでは、Productクラスのインスタンスを生成し、インスタンス変数の値を直接変更しようとしていますが、出力されるのは依然としてコンストラクタ内で設定された値です。

これは、アンダースコア2つ(__)で始まる属性が「名前マングリング」という仕組みによって、外部から直接アクセスできないように保護されているためです。インスタンス属性の値を変更する唯一の方法は、productMaxPrice()またはproductMinPrice()といった専用メソッドを呼び出すことです。

  1. 【Python入門】メタクラスによるメタプログラミングの基本と実践例

    メタプログラミングとは、プログラムが自分自身を操作したり、自身についての知識を持ったりするプログラミング手法のことを指します。Pythonでは「メタクラス」と呼ばれる特殊なクラスを使うことで、クラスに対するメタプログラミングを実現できます。メタクラスによるメタプログラミングでは、既存のコードを修正・ラップ・生成することでコードを操作する関数やクラスを構築します。メタプログラミングの主な機能は以下の通りです。メタクラスデコレータクラスデコレータメタクラスとは何かメタクラスを簡潔に定義するなら、「クラスを作り出すクラス」です。Pythonはオブジェクト指向言語であり、すべてがオブジェクトとして扱わ

  2. Pythonのオブジェクト指向プログラミングの基本概念をわかりやすく解説

    Pythonにおけるオブジェクト指向プログラミング(OOP)の概念Pythonはオブジェクト指向プログラミング言語です。クラスやオブジェクトを簡単に作成し、自由に利用することができます。Pythonの主要なオブジェクト指向の概念は以下の7つです。オブジェクト(Object)クラス(Class)メソッド(Method)継承(Inheritance)ポリモーフィズム(Polymorphism/多態性)データ抽象化(Data Abstraction)カプセル化(Encapsulation)オブジェクト(Object)オブジェクトとは、状態と振る舞いを持つ実体のことです。物理的なものでも論理的なもので