依存性逆転の法則の学習
依存性逆転の原則 (Dependency Inversion Principle)
依存関係逆転の原則は柔軟なシステムの作り方を教えてくれます。 最も柔軟なシステムは、ソースコードの依存関係がインターフェイスだけを参照している場合です。
上位クラスの具象クラスと下位クラスの具象クラスがあります。
上位クラスの具象クラスから下位クラスの具象クラスのインスタンスを直接生成すると、下位クラスの変更の影響を上位クラスが強く受けてしまいます。
そこで、以下の手順で実施できるようにします。
(1) 間に抽象クラスを挟む
(2) DIを用いる
参考リンク
Pythonでモジュールをインポートするときの構文
はじめに
関数の定義と関数を利用する処理を同じファイルに記述すると、コード行数が膨大になります。
また、関数を再利用しにくいです。
そこで、関数の定義を別ファイルに分けて、関数の定義(モジュール)を読み込む(インポート)方法をとります。
使用するモジュール定義
今回は以下のモジュールを使用します
[dos.py]
class Dog: # property voice = "bow!" # method def bark(self): print(self.voice)
モジュールのインポート方法1
クラス名が必要です。
import health import dogs dog = dogs.Dog() dog.bark()
モジュールのインポート方法2
普段はこちらを使用したほうがいいと思います。 クラス名が必要ありません。
from dogs import Dog dog = Dog() dog.bark()
class Dog: # property voice = "bow!" # method def bark(self): print(self.voice)
参考リンク
jupyterノートブックで、pandas_datareaderが見つからない問題の対処
エラーメッセージ
--------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) <ipython-input-1-86720d1c88cc> in <module>() 7 import matplotlib.pyplot as plt 8 import numpy as np ----> 9 import pandas_datareader 10 import sklearn 11 import sklearn.linear_model ModuleNotFoundError: No module named 'pandas_datareader'
対処方法
構造化束縛 [C++17]
構造化束縛
C++17で追加された構造化束縛は多値を分解して受け取るための変数宣言の文法です。
多値を受け取るためには、これまでは多値をかたまりで受け取るか、ライブラリで分解して受け取るしかありませんでした。
構造化束縛を使うと、少ないコード量で多値を分解して受け取ることが可能です。
多値を受け取るコードの比較
#include <iostream> #include <tuple> std::tuple < int, double, std::string > get_tuple_value() { return { 1, 2.0, "hello" }; } int main(void){ // 多値を受け取る方法(多値をかたまりで受け取る) auto result = get_tuple_value(); std::cout << "b : " << std::get<0>(result) << std::endl; std::cout << "c : " << std::get<1>(result) << std::endl; std::cout << "d : " << std::get<2>(result) << std::endl; // 多値を受け取る方法(ライブラリで分解して受け取る) int param1; double param2; std::string param3; std::tie(param1, param2, param3) = get_tuple_value(); std::cout << "b : " << param1 << std::endl; std::cout << "c : " << param2 << std::endl; std::cout << "d : " << param3 << std::endl; // 多値を受け取る方法(C++17) auto [b, c, d] = get_tuple_value();; std::cout << "b : " << b << std::endl; std::cout << "c : " << c << std::endl; std::cout << "d : " << d << std::endl; }
b : 1 c : 2 d : hello b : 1 c : 2 d : hello b : 1 c : 2 d : hello
if文内、switch文内、range-based for文内で使用してみる
if, switch, range-based for文で使用する。
#include <iostream> #include <tuple> #include <map> #include <vector> int main(void){ std::tuple<int, double, std::string> expr{5, 2.0, "test"s }; // "test"sとすることでstd::string型の文字列リテラルとなる // 構造化束縛はif文で使用可能です if ( auto[a, b, c] = expr ; a == 5 ) // 初期化文付き条件文 (C++17) { std::cout << "a : " << a << ", b : " << b << ", c : " << c << std::endl; } // 構造化束縛はswitch文で使用可能です switch ( auto[a, b, c] = expr; a ) // 初期化文付き条件文 (C++17) { case 5: std::cout << "a : " << a << std::endl; std::cout << "b : " << b << std::endl; std::cout << "c : " << c << std::endl; break; default: break; } std::vector<std::tuple<int, double, std::string>> map_Prodct; map_Prodct.push_back(expr); map_Prodct.push_back(expr); map_Prodct.push_back(expr); map_Prodct.push_back(expr); map_Prodct.push_back(expr); // 構造化束縛は[range-based for文]でも使用可能です for ( auto[a,b,c] : map_Prodct ) { std::cout << "a : " << a << ", b : " << b << ", c : " << c << std::endl; } }
a : 5, b : 2, c : test a : 5 b : 2 c : test a : 5, b : 2, c : test a : 5, b : 2, c : test a : 5, b : 2, c : test a : 5, b : 2, c : test a : 5, b : 2, c : test
使用例
#include <iostream> using namespace std; int main(void){ { int ar[] = {3, 1, 4}; // 配列を分解する。 // ar[0]がaに代入され、 // ar[1]がbに代入され、 // ar[2]がcに代入される。 // 分解する要素数は、配列の要素数と同じであること auto [a, b, c] = ar; std::cout << a << std::endl; std::cout << b << std::endl; std::cout << c << std::endl; } std::cout << std::endl; // 参照の例 { int ar[] = {3, 1, 4}; int (&rar)[3] = ar; auto [a, b, c] = rar; // ar[1]を値2に書き換える b = 2; std::cout << a << std::endl; std::cout << b << std::endl; std::cout << c << std::endl; } }
Pythonでプライベートメンバ変数をクラスに定義する [Python]
Pythonのプロパティを使う方法
Pythonでは、クラスのカプセル化を実現する際は、プロパティを用いるほうがいいと思います。
getter, setterを作ったとしても、使用者側がそれを使ってくれる保証がありません。(´;ω;`)
あまり良くない書き方 その3 getter/setter - Python学習講座
コード
class Car(object): def __init__(self, model=None): self.model = model def run(self): print('run') class ToyotaCar(Car): def run(self): print('fast') class TeslaCar(Car): def __init__(self, model="Model S", enable_run=False): # 親のinit関数を呼び出す super().__init__(model) # プライベートメンバ変数 self.__enable_auto_run = enable_run @property def enable_auto_run(self): return self.__enable_auto_run @enable_auto_run.setter def enable_auto_run(self, is_enable): self.__enable_auto_run = is_enable def run(self): print('super fast') def auto_run(self): print('auto_run') car = Car() car.run() print('########') toyota_car = ToyotaCar('Lexus') print(toyota_car.model) toyota_car.run() print('########') # コンストラクタで、プライベートメンバ変数(__enable_auto_run)に対して、Falseの値をセットする tesula_car = TeslaCar('Model_S', False) print(tesula_car.enable_auto_run) # Setterを通して、プライベートメンバ変数(__enable_auto_run)に対して、Trueの値をセットする tesula_car.enable_auto_run = True print(tesula_car.enable_auto_run)
出力イメージ
run ######## Lexus fast ######## False True
クラスのメソッドのオーバーライドとsuperによる親メソッドの呼び出し [Python]
クラスのメソッドのオーバーライドとsuperによる親メソッドの呼び出し
<コード>
class Car(object): def __init__(self, model=None): self.model = model def run(self): print('run') class ToyotaCar(Car): def run(self): print('fast') class TeslaCar(Car): def __init__(self, model="Model S", enable_run=False): # 親のinit関数を呼び出す super().__init__(model) self.enable_auto_run = enable_run def run(self): print('super fast') def auto_run(self): print('auto_run') car = Car() car.run() print('########') toyota_car = ToyotaCar('Lexus') print(toyota_car.model) toyota_car.run() print('########') tesula_car = TeslaCar('Model_S', True) print(tesula_car.model) print(tesula_car.enable_auto_run) tesula_car.run() tesula_car.auto_run()
<出力結果>
run ######## Lexus fast ######## Model_S True super fast auto_run