[解決済み】Pythonのクラスはいつ使うべきですか?
質問
私は2年ほど前からpythonでプログラミングをしています。主にデータ関連(pandas、mpl、numpy)ですが、自動化スクリプトや小さなウェブアプリも作っています。 私はより良いプログラマーになり、私のpythonの知識を増やそうとしています。私を悩ませることの一つは、私が(小さなWebアプリのためのランダムなflaskコードをコピーする以外)クラスを使用したことがないことです。 私はそれが何であるか一般的に理解していますが、私は単純な関数の上にそれらを必要とする理由を理解することができないようです。
私の質問を具体的に補足します。私は、複数のデータソース(mongo、sql、postgres、apis)からデータを取得し、多くのまたは少しのデータ加工と書式設定を行い、データをcsv/excel/htmlに書き込み、電子メールで送信する自動レポートを大量に書いています。 スクリプトは、250行から600行までです。 これを行うためにクラスを使用する理由はあるでしょうか?
どのように解決するのですか?
クラスは オブジェクト指向プログラミング . OOPは、コードの構成、再利用性、カプセル化に大きな関心を寄せています。
まず最初に、免責事項:OOPは、部分的には 関数型プログラミング これはPythonで多く使われている別のパラダイムです。Pythonでプログラミングする人すべてが(あるいはほとんどの言語が)OOPを使っているわけではありません。Java 8では、あまりオブジェクト指向でないこともたくさんできます。もしあなたがオブジェクト指向を使いたくないなら、使わないでください。もしあなたが、二度と使わないデータを処理するために単発のスクリプトを書くだけなら、そのままの書き方を続けてください。
しかし、OOPを使うべき理由はたくさんあります。
いくつかの理由を紹介します。
-
組織化。 OOPは、コード内のデータと手順の両方を記述し定義する、よく知られた標準的な方法を定義しています。データとプロシージャの両方は、さまざまな定義レベルで(異なるクラスで)格納することができ、これらの定義について話すための標準的な方法があります。つまり、標準的な方法でOOPを使用すれば、後の自分や他の人があなたのコードを理解し、編集し、使用するのに役立つのです。また、複雑で任意のデータ保存メカニズム(ディクショ ンのディック、リスト、ディック、セットのディックのリストなど)を使用する代わりに、データ構造の断片に名前を付けて便利に参照することができるようになります。
-
状態です。OOPは、状態を定義し、追跡するのに役立ちます。例えば、古典的な例ですが、学生を処理するプログラム(例えば成績プログラム)を作成する場合、学生について必要なすべての情報(名前、年齢、性別、学年、コース、成績、教師、仲間、食事、特別なニーズなど)を一箇所に集め、このデータはオブジェクトが生きている限り持続し、簡単にアクセスできるようにすることができます。
-
カプセル化 : カプセル化によって、プロシージャとデータは一緒に保存されます。メソッド(OOP用語で関数)は、メソッドが操作して生成するデータと一緒に定義されます。Java のような言語では アクセス制御 Pythonでは、パブリックAPIをどのように記述するかによって、メソッドとデータをユーザーから隠すことができることを意味します。このことは、コードを変更する必要がある場合、あるいは変更したい場合、コードの実装には何でもできるが、パブリックAPIは同じままにしておくということです。
-
継承 : 継承を利用すると、データや手続きを一箇所(一つのクラス)で定義し、後からその機能をオーバーライドしたり拡張したりすることができます。例えば、Pythonの場合、よく
dict
クラスは、機能を追加するために使用されます。よくある変更は、存在しない辞書からキーが要求されたときに例外を投げるメソッドをオーバーライドして、未知のキーに基づくデフォルト値を与えるというものです。これにより、自分のコードを今すぐまたは後で拡張したり、他の人が自分のコードを拡張したり、他の人のコードを拡張したりすることができるようになります。 -
再利用性。これらの理由とその他の理由により、コードの再利用性を高めることができます。オブジェクト指向のコードでは、一度しっかりとした(テストされた)コードを書けば、何度でも再利用することができます。もし、特定のユースケースのために何かを微調整する必要があれば、既存のクラスを継承して、既存の動作を上書きすることができます。もし何かを変更する必要があれば、既存のパブリックメソッドのシグネチャを維持したまますべてを変更することができ、誰も賢くなることはありません(希望的観測)。
繰り返しになりますが、OOPを使わない理由はいくつかありますし、使う必要もありません。でも、幸いなことにPythonのような言語では、ほんの少し使うことも、たくさん使うことも、あなた次第なのです。
学生の使用例です(コードの品質を保証するものではありません、単なる例です)。
オブジェクト指向
class Student(object):
def __init__(self, name, age, gender, level, grades=None):
self.name = name
self.age = age
self.gender = gender
self.level = level
self.grades = grades or {}
def setGrade(self, course, grade):
self.grades[course] = grade
def getGrade(self, course):
return self.grades[course]
def getGPA(self):
return sum(self.grades.values())/len(self.grades)
# Define some students
john = Student("John", 12, "male", 6, {"math":3.3})
jane = Student("Jane", 12, "female", 6, {"math":3.5})
# Now we can get to the grades easily
print(john.getGPA())
print(jane.getGPA())
標準ディクショナリ
def calculateGPA(gradeDict):
return sum(gradeDict.values())/len(gradeDict)
students = {}
# We can set the keys to variables so we might minimize typos
name, age, gender, level, grades = "name", "age", "gender", "level", "grades"
john, jane = "john", "jane"
math = "math"
students[john] = {}
students[john][age] = 12
students[john][gender] = "male"
students[john][level] = 6
students[john][grades] = {math:3.3}
students[jane] = {}
students[jane][age] = 12
students[jane][gender] = "female"
students[jane][level] = 6
students[jane][grades] = {math:3.5}
# At this point, we need to remember who the students are and where the grades are stored. Not a huge deal, but avoided by OOP.
print(calculateGPA(students[john][grades]))
print(calculateGPA(students[jane][grades]))
関連
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
[解決済み】RuntimeWarning: 割り算で無効な値が発生しました。
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] Pythonで静的なクラス変数は可能ですか?
-
[解決済み] どのような場合に '$this' よりも 'self' を使うべきですか?
-
[解決済み] Pythonのクラスはなぜオブジェクトを継承するのですか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】forループを使った辞書の反復処理
-
[解決済み】Pythonに三項条件演算子はありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
python string splicing.join()とsplitting.split()の説明
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
[解決済み】RuntimeWarning: invalid value encountered in double_scalars で numpy の除算ができない。
-
[解決済み】DataFrameのコンストラクタが正しく呼び出されない!エラー
-
[解決済み】RuntimeWarning: 割り算で無効な値が発生しました。
-
[解決済み】「RuntimeError: dictionary changed size during iteration」エラーを回避する方法とは?
-
[解決済み】Django: ImproperlyConfigured: SECRET_KEY 設定は空であってはならない
-
[解決済み】Python: OverflowError: 数学の範囲エラー
-
[解決済み】cアンダースコア式`c_`は、具体的に何をするのですか?
-
[解決済み】pythonの複数の戻り値を無視する