Python : クラス-1
参考書籍 : Python実践入門
・Pythonのクラス機構
クラス定義の構文は、以下のようになる。
# class クラス名(基底クラス名): # def メソッド名(引数1, ...): # 処理 #
基底クラスの指定は()も含めて省略でき、省略した場合はobjectクラスを継承する。
関数にはメソッドとプロパティをもたせることができる。
プロパティは__init__()内でselfを使用して定義する。
class Page(object): def __init__(self, num, content): self.num = num # property self.content = content # method def output(self): return f'{self.content}' >>> Page <class '__main__.Page'>
・インスタンスの生成
クラスオブジェクトに()をつけて呼び出すと、インスタンスを作成できる。
title_page = Page(0, 'Python Practice Book') print(type(title_page)) # <class '__main__.Page'> print(isinstance(title_page, Page)) # True print(dir(title_page)) # ['__class__', ... 'content', 'num', 'output']
・インスタンスメソッドの呼び出し
クラス定義の中で定義されたメソッドは、クラスがインスタンス化することにより、インスタンスメソッドとして呼び出せる。
インスタンスメソッドは第一引数で受け取るselfを使い、インスタンス自身にアクセスできる。
print(title_page.output()) # Python Practice Book
・__new__()と__init__()の違い
Pythonにおけるコンストラクタは__new__()で、__init__()はイニシャライザと呼ばれる。
コンストラクタ__new__()はコンストラクタを生成する処理を担当し、
イニシャライザ__init()__はインスタンス生成後の初期化を行う。
__new__()の戻り値がクラスのインスタンスとなる。
class Klass(object): def __new__(cls, *args): # コンストラクタ print(f'{cls=}') print('new', args) return super().__new__(cls) def __init__(self, *args): print('init', args) kls = Klass(1, 2, 3) # new (1, 2, 3) # init (1, 2, 3)
・プロパティ
@propertyを使い、メソッドに()なしでアクセスできる。
class Book(object): def __init__(self, raw_price): if raw_price < 0: raise ValueError('price must be positive') self.raw_price = raw_price self._discounts = 0 @property def discounts(self): return self._discounts @discounts.setter def discounts(self, value): if value < 0 or 100 < value: raise ValueError('discounts must be between 0 and 100') self._discounts = value @property def price(self): multi = 100 - self._discounts return int(self.raw_price * multi / 100) book = Book(2000) print(book.discounts) # 0 print(book.price) # 2000 book.discounts = 20 print(book.price) # 1600 book.discounts = 120 # ValueError: discounts must be between 0 and 100
discounts()とprice()には@propertyがついており、()なしで呼び出せる。
@propertyがついたメソッドはゲッターと呼ばれ、値を取得するために呼び出される。
@discounts.setterがついたメソッドはセッターと呼ばれ、book.discounts = 20のように値を代入するときに呼び出される。
代入と同時にエラーチェックを行っている。
@price.setterは存在しないため、book.price = 100のような操作はAttributeErrorとなる。
クラスBook内で、_discountのようにプロパティの頭文字にアンダースコアをつけるときは、プライベート変数として使用することを表現している。
__xのように、アンダースコア2つをつけると、名前修飾が行われる。
名前修飾は、Klassクラスの変数__xをKlass__xという名前に変換する機能である。
この機能は、サブクラスでの名前衝突を避けるため使われる。