【Python入門】クラス②

Python入門

1.カプセル化(Encapsulation)とは

カプセル化とは、クラスの内部データを外部から勝手に変更させないための仕組みです。
Python では完全な「非公開」はありませんが、慣習的に _(1つ)__(2つ) を使って「内部用」を示します。

_変数(1つのアンダースコア)= 内部利用の目印

(外からアクセスできるが「触らないでね」という意味)

class User:
    def __init__(self, name):
        self._name = name  # 内部用の変数

__変数(2つのアンダースコア)= 名前修飾で外部から触れにくくする(疑似非公開)

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # 実質的に外部から触れられない

    def deposit(self, amount):
        self.__balance += amount

    def get_balance(self):
        return self.__balance

外から触れられない:

acc = BankAccount(1000)
# acc.__balance  ← エラーになる

安全な方法(deposit / get_balance)を通して値を扱うのがカプセル化

2.プロパティ

Python では getter/setter を関数っぽく書ける。
getter(外部から取得するとき)は、関数名の上に「@property」と記載し、関数名を記載。この関数名が外部から見える属性名となる。返却値に自身の属性を指定する。
setter(外部から属性を入力するとき)は、関数の上に「@属性名.setter」と記載し、関数名は属性名と合わせる。

class Person:
    def __init__(self, age):
        self._age = age

    @property
    def age(self):
        return self._age  # 取得

    @age.setter
    def age(self, value):
        if value < 0:
            raise ValueError("年齢は0以上")  #ここは今は無視
        self._age = value  # 設定

使う側:

p = Person(20)
p.age = 30      # セッター
print(p.age)    # ゲッター

プロパティを使う場合はproperty下の関数名が属性名になり、使わない場合はself.xxxとアクセスしたときにxxxの部分が属性名になる。両方使う場合、属性名を分ける必要がある。

3.クラスメソッド(classmethod)

クラスメソッドは、クラス自身に対して動作するメソッド です。

特徴:

  • 第一引数が cls(クラス自身)
  • @classmethod デコレータを使う
  • クラス変数にアクセスできる

クラス変数…クラスで共有して使える変数のこと。そのクラス自体が持ってる変数のため、クラス名.変数で指定する必要がある。※通常は各インスタンスが個別の変数を持つ。
クラスメソッド…そのクラス自体が持っているメソッドで、インスタンスせずそのまま呼び出す。

✔ クラス変数を扱う例

class Dog:
    count = 0  # クラス変数

    def __init__(self):
        Dog.count += 1

    @classmethod  # クラス関数
    def how_many(cls):
        return cls.count

使い方:

a = Dog()
b = Dog()
print(Dog.how_many())  # 2

※クラス名ではなくインスタンス名.クラス変数とするとインスタンス内に新しい変数ができてしまうので注意!

4.静的メソッド(staticmethod)

静的メソッドはクラスにもインスタンスにも依存しない “普通の関数” をまとめたい時に使います。

特徴:

  • 第一引数に self も cls も取らない
  • @staticmethod デコレータで定義
  • グループ化のためにクラス内に置くだけ

✔ 静的メソッドの例

class MathUtil: #とりあえず関数をまとめるためのクラス

    @staticmethod #静的メソッド
    def add(a, b):
        return a + b

使い方:

print(MathUtil.add(3, 5))  # 8

✔ インスタンスを作らずに呼べる
✔ クラス変数やインスタンス変数にはアクセスしない。

5.クラスメソッド vs 静的メソッドの違い

種類第一引数目的
インスタンスメソッドselfインスタンスのデータを扱う
クラスメソッドclsクラス全体を扱う / クラス変数を扱う
静的メソッドなしクラスに属するだけの共通関数

6.実例

class Product:
    tax_rate = 0.1  # クラス変数

    def __init__(self, price):
        self.price = price  # インスタンス変数

    def total(self):
        return int(self.price * (1 + Product.tax_rate))

    @classmethod
    def set_tax(cls, rate):
        cls.tax_rate = rate

    @staticmethod
    def is_valid_price(price):
        return price >= 0

使う側:

Product.set_tax(0.08)       # クラスメソッド
print(Product.is_valid_price(100))  # 静的メソッド
p = Product(1000)
print(p.total())
タイトルとURLをコピーしました