Python でクラスを使ったサンプルコードをまとめておきます。
加えて、関数に対し、クラスを作るメリットについてポイントをまとめておくことにします。
環境: Python 3.x
背景
Python でプログラミングを覚えるとき、最初は def で関数を作ると思います。
慣れてくると、クラスでメソッドを作るようにもなると思います。
そこで、クラス class の使い方についてまとめておきます。
忘れてしまった場合でも、コピー&ペーストすることですぐに使えるよう、サンプルコードの形でまとめておきます。
動かしてみるのがもっとも早いと思います。
サンプルコード
“readwrite1.py”
# -*- coding: utf-8 -*-
class Rw1:
def __init__( self ):
self.path0 = ""
def set_path1( self, path1 ):
self.path0 = path1
def read1( self, file0 ):
file1 = self.path0 + file0
with open( file1, 'r', encoding='utf-8' ) as f1:
str1 = f1.read()
return str1
def write1( self, file0, str1 ):
file1 = self.path0 + file0
with open( file1, 'w' ) as f1:
f1.write( str1 )
return 0
“test1.py”
# -*- coding: utf-8 -*-
from readwrite1 import Rw1
rw1 = Rw1()
rw1.set_path1( "C:/user/test/" )
file1 = "text1.txt"
str1 = rw1.read1( file1 )
print( str1 )
print( rw1.path0 )
file2 = "text2.txt"
rw1.write1( file2, str1 )
“text1.txt”
abc
def
使い方
スクリプトに記載したパス “C:/user/test/” を参考に、PC にフォルダ “test” を作ってください。
パスを変えたい場合は、”C:/user/test/” の部分を修正してください。
その中に、”readwrite1.py”, “test1.py”, “text1.txt” の3つのファイルを作成し、上のファイルを貼りつけて保存してください。
コマンドプロンプトで、python test1.py として実行すると、text1.txt の内容を読みだして表示し、text2.txt として保存します。
まずは動くか確認し、動いたら、好きなように修正をしてください。
たとえば、rw1.set_path( ) で、ファイルの読み書きをするパスを設定していますが、class の __init__ のところに移してデフォルトとなるパスを設定してしまえば、この行は不要となり、スクリプトがより簡単になります。
スクリプトの動き
クラスを呼び出して rw1 を作り、最初にテキストが入っているパスを設定します。
ファイル名を指定すると、フルパスを都度気にすることなく、テキストファイルの読み書きが自由にできるようになります。
クラス class のメリットは何か
関数のみでプログラミングするとどうなるか
class を使わずに関数のみで平易に記載すると、以前に作成した下記のサンプルのようになります。
テキストファイルを入出力する 【Python】
しかしこの場合、読み書きを行うパス自体は、それぞれ、関数の実行後、メモリから解放されてしまいます。
したがって、関数を使うたびにフルパスを指定する必要があります。
関数にパスの文字列を渡し、次回もこのパスは使うので、設定したパスをしばらく覚えておきたい、といったことができないわけです。
関数の中にパスを埋め込んでも、パスを変更するたびに読み書きの2つの関数を修正する必要が生じるため、煩雑です。
グローバル変数を使おうとすると、たとえば、読み書き用の作業フォルダを3つ設定して使い分けることにし、同時に読み書きしたい、となったとき、処理が複雑化してしまいます。
結局、関数のみしか使わないとすると、覚えておきたいパラメータ(動的に変わるかもしれないが維持しておきたい変数)は、スクリプト本体側(test1.py)で維持しておく必要が生じます。
そして、スクリプト本体側で、パス(path1, path2, …)を使った別の処理(本来、作りたかった処理)を加えていくと、処理が混ざって複雑度が増すので、バグの要因となります。
クラスを使うとどうなるか
そこで、例えば、ファイルの読み書きのような共通性のある処理については、クラスを作ることにします。
2つの関数に加え、パスを保持する文字列も、一つのクラスにまとめてしまいます。
すると、作成したインスタンス rw1 のみを気にするだけで、処理をメインのスクリプトからは完全に分離できます。
「インスタンスを作る」というのは、不揮発性のメモリ(RAM)上に領域を確保する、と考えると理解できると思います。
作成したインスタンス rw1 に積極的にアクセスしない限り、rw1 の内部のパラメータが変わることはない。
そして、スクリプト本体側で path1, path2 をいくら使っても、また書き換えても、読み書きの処理 rw1 に影響することはない、ということになります。
バグが入り込む余地がなくなって、本来作りたいプログラミングに集中できることになります。
まとめ
関数をいくつか作ってきたけれども、関数が増えてきてだんだんわからなくなってきた。パラメータも増えてきたけれども、共通化してまとめてしまいたい、となった場合、class を作ってまとめてしまえばよい、ということになります。
クラス class を定義し、関係しそうな関数とパラメータをひとくくりにまとめてしまいます。
すると、他のスクリプトから完全に分離でき(読み書きのような定型処理は完全に忘れることができ/分離度を上げることができ)、本来のプログラミングだけに集中できる、バグが生じる要因をなくせる、という点で、メリットがあるといえます。
関連リンク
・ 関数とメソッドの違い 【Python】
・ 他のスクリプトの関数を実行する 【Python】
・ 「参照渡し」に関するまとめ 【Python】