インスタンス属性とクラス属性

Python によるオブジェクト指向プログラミング

Alex Yarosh

Content Quality Analyst @ DataCamp

OOP の基本原則

 

継承:

  • 既存コードの機能拡張

ポリモーフィズム:

  • 統一的なインターフェースの提供

カプセル化:

  • データとメソッドの束ね
Python によるオブジェクト指向プログラミング

インスタンスレベルのデータ

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

emp1 = Employee("Teo Mille", 50000) 
emp2 = Employee("Marta Popov", 65000)
  • namesalary はインスタンス属性
  • self はインスタンスを指す
Python によるオブジェクト指向プログラミング

クラスレベルのデータ

  • クラスの全インスタンスで共有されるデータ
  • class 本体でクラス属性を定義
class MyClass:
    # クラス属性を定義
    CLASS_ATTR_NAME = attr_value


  • クラス内の「グローバル変数」
Python によるオブジェクト指向プログラミング

クラスレベルのデータ

class Employee:
  # クラス属性を定義
  MIN_SALARY = 30000    #<--- self ではない

def __init__(self, name, salary): self.name = name # クラス名でクラス属性にアクセス if salary >= Employee.MIN_SALARY: self.salary = salary else: self.salary = Employee.MIN_SALARY
  • MIN_SALARY は全インスタンスで共有
  • クラス属性の定義に self は使わない
  • 値にアクセスするには ClassName.ATTR_NAME を使う
Python によるオブジェクト指向プログラミング

クラスレベルのデータ

class Employee:
  # クラス属性を定義
  MIN_SALARY = 30000    

def __init__(self, name, salary): self.name = name # クラス名でクラス属性にアクセス if salary >= Employee.MIN_SALARY: self.salary = salary else: self.salary = Employee.MIN_SALARY
emp1 = Employee("TBD", 40000)
print(emp1.MIN_SALARY)
30000
emp2 = Employee("TBD", 60000)
print(emp2.MIN_SALARY)
30000
Python によるオブジェクト指向プログラミング

なぜクラス属性を使うのか

クラスに関係するグローバル定数

 

  • 属性の最小/最大値
  • よく使う定数(例:Circle クラスの pi
  • ...
Python によるオブジェクト指向プログラミング

クラスメソッド

  • メソッドは既に「共有」:全インスタンスで同じコード
  • クラスメソッドはインスタンス属性を使えない
class MyClass:

  @classmethod                         # <---デコレータでクラスメソッドを宣言

def my_awesome_method(cls, args...): # <---cls はクラスを指す # ここで処理 # インスタンス属性は使えない :(
MyClass.my_awesome_method(args...)
Python によるオブジェクト指向プログラミング

代替コンストラクタ

class Employee:
  MIN_SALARY = 30000
  def __init__(self, name, salary=30000):
      self.name = name
      if salary >= Employee.MIN_SALARY:
        self.salary = salary
      else:
        self.salary = Employee.MIN_SALARY
  • __init__() は1つだけ

  @classmethod
  def from_file(cls, filename):
      with open(filename, "r") as f:
          name = f.readline()
      return cls(name)

  • オブジェクト生成にクラスメソッドを使う
  • return でオブジェクトを返す
  • cls(...)__init__(...) を呼ぶ
Python によるオブジェクト指向プログラミング

代替コンストラクタ

class Employee:
  MIN_SALARY = 30000
  def __init__(self, name, salary=30000):
      self.name = name
      if salary >= Employee.MIN_SALARY:
        self.salary = salary
      else:
        self.salary = Employee.MIN_SALARY

  @classmethod
  def from_file(cls, filename):
      with open(filename, "r") as f:
          name = f.readline()
      return cls(name)        

従業員名が1行だけのテキストファイル

# Employee() を直接呼ばずに作成
emp = Employee.from_file("employee_data.txt")
type(emp)
__main__.Employee
Python によるオブジェクト指向プログラミング

Passons à la pratique !

Python によるオブジェクト指向プログラミング

Preparing Video For Download...