今回はPythonのオブジェクト指向について紹介します。
書き方
python2の書き方:
class Person:
#コード
#コード
python3以降の書き方:
class Person():
def eat(self):
print(‘eat’)
p = Person()
p.eat()
# 属性あり
#クラス
class Person():
#インスタンス
#クラス
class Person():
def info(self):
print(f'{self.age}歳’)
#インスタンス
p = Person()
p.name = ‘Tom’
p.age = 20
p.info()
print(f’名前:{p.name}’)
__init__
class Persion():
def __init__(self): #自動実行される
self.name = ‘test’
self.age = 20
def info(self):
print(f’名前:{self.name}年齢:{self.age}’)
p = Persion()
p.info() #名前:test年齢:20
引数あり
class Persion():
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(f’名前:{self.name}年齢:{self.age}’)
p = Persion(‘test’, 29)
p.info() #名前:test年齢:29
__str__
class Persion():
def info(self):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name
def info(self):
print(f’名前:{self.name}年齢:{self.age}’)
p = Persion(‘test’, 29)
p.info()
print(p) #__str__の結果を出力
__del__
class Persion():
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name
def __del__(self): #インスタンス削除のとき、自動実行される
print(“del”)
def info(self):
print(f’名前:{self.name}年齢:{self.age}’)
p = Persion(‘test’, 29)
p.info()
print(p)継承
単一の継承
class A():
def __init__(self):
self.num = 10
def info(self):
print(self.num)
class B(A): # 親クラスAを継承する
pass
result = B()
result.info() #10
複数の親
class A():
def __init__(self):
self.num = 10
def info(self):
print(self.num)
class B():
def __init__(self):
self.num = 20
def info(self):
print(self.num)
class C(B, A): # Bのメソッドを優先に使う
pass
result = C()
result.info() #20
オーバーライド
オーバーライドとは「親クラスと同じ名前のメソッドを子クラスで新たに定義すること」を言います。
class A():
def __init__(self):
self.num = 10
def info(self):
print(self.num)
class B():
def __init__(self):
self.num = 20
def info(self):
print(self.num)
class C(B, A):
def info(self):
print(“override”)
result = C()
result.info() #override
__mro__
クラスのスーパークラスの一覧をすべて取得する
class A():
def __init__(self):
self.num = 10
def info(self):
print(self.num)
class B():
def __init__(self):
self.num = 20
def info(self):
print(self.num)
class C(B, A):
def info(self):
print(“override”)
result = C()
print(C.__mro__)
#(<class ‘__main__.C’>, <class ‘__main__.B’>, <class ‘__main__.A’>, <class ‘object’>)
#(<class ‘__main__.C’>, <class ‘__main__.B’>, <class ‘__main__.A’>, <class ‘object’>)
親クラスのメソッドを実行
class A():
def __init__(self):
self.num = 10
def info(self):
print(self.num)
class B(A):
def __init__(self):
self.num = 20
def info(self):
print(self.num)
super().__init__()
super().info()
b = B()
b.info() #20 10
プライベート(メンバとメソッド)
パブリックなメンバとメソッド、プライベートなメンバとメソッドの記述方法とアクセス方法を書きます。
「__変数名」でプライベートなメンバとメソッドを定義できる。
class A():
def __init__(self):
self.num = 10
self.__money = 20 # プライベート変数
def __Go(self): # プライベートメソッド
print(“A Go”)
def get_money(self):
return self.__money
def set_money(self, money):
self.__money = money
a = A()
print(a.get_money())
クラスの変数とメソッド
Pythonのクラスには変数とメソッドがあります。
変数はクラス変数とインスタンス変数があります。
メソッドはいクラスメソッド、インスタンスメソッド、静的メソッドがあります。
class Dog():
name = ‘dog’ # クラス変数
def __init__(self, age):
self.age = age # インスタンス変数
# インスタンスメソッド
def sleep(self):
print(“sleep”)
# 引数付きのインスタンスメソッド
def eat(self, food):
print(f’eat {food}’)
# クラスメソッド
@classmethod
def walk(cls):
print(f'{cls.name} is walking’)
# 静的メソッド
@staticmethod
def run():
print(“running”)
プロパティ(property)
プロパティとはクラスの関数をプロパティとして使う方法です。
方法1
以下のサンプルコードを参考します。
class Student():
def __init__(self):
self.__age = 10
@property
def age(self):
return self.__age
@age.setter
def age(self, age): #age じゃないと、エラーとなる。
self.__age = age
stu = Student()
print(stu.age) #10
stu.age = 20
print(stu.age) #20
方法2
以下のサンプルコードを参考します。
class Student():
def __init__(self):
self.__age = 10
def get_age(self):
return self.__age
def set_age(self, age):
self.__age = age
age = property(get_age,set_age)
stu = Student()
print(stu.age) #10
stu.age = 20
print(stu.age) #20
__enter__と__exit__について
一般には__enter__メソッドでリソースを確保するような処理、__exit__メソッドでリソースを解放するような処理を実装します。
方法1
class File():
def __enter__(self):
print(‘withブロックに入ります’)
def __exit__(self, exc_type, exc_value, traceback):
print(‘withブロックを抜けます’)
with File() as file:
print(‘withブロックを実行中です’)
実行結果:
withブロックに入ります
withブロックを実行中です
withブロックを抜けます
withブロックを実行中です
withブロックを抜けます
方法2
from contextlib import contextmanager
@contextmanager
def file_open(path, mode):
try:
file = open(path, mode)
yield file
except Exception as e:
print(e)
finally:
file.close()
with file_open(“file.log”,’r’) as file:
file_data = file.read()
print(file_data)