目次
TestCaseの中に「os.path.abspath(__file__)」をコピペした凡ミス
今回は「Django」を使っている前提の話です。
僕が最近使っているフォルダ構成はこんな感じ。
functionとかmoduleを階層化して、階層をとばして結合しない縛りをいれてます。
このフォルダ構成で「modules」フォルダにPythonクラスのソースを置き、そのクラスを使った処理クラスをfunctionsフォルダにおいています。
そして、tcdemo直下にそのfunctionsフォルダのクラスを使うメインのPythonプログラムを置くという構造です。
ここでUNITTESTを書く際に、settings.pyというソース内に書いている「BASE_DIR」と同じパスを取得したかったのです。
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
僕は、これをよく考えずに
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
の部分をコピペしてしまいました。
これが凡ミスです。
どのあたりが凡ミスなのか
この「__file__」は、Pythonで実行中のスクリプトファイル.pyの場所(パス)を取得するものだからです。
だから、上記のように「module」と「functions」みたいに階層が違うところにあるソースファイルに「__file__」を書くと違うパスが返されます。
なのに、なんとなく「__file__」で返されるパスが「BASE_DIR」と同じものがかえされるような錯覚におちいってました。、
フォルダ階層が違うソースコードに、「os.path.abspath(__file__)」なんて書いて、同じパスが返されるわけがないのに・・・まさに、凡ミスです。
どうすればよかったのか。
djangoには「settings.py」で定義された値を読む機能が用意されています。
それを使えばよかったのです。
例えば、BASE_DIRを使いたいなら。
from django.conf import settings
basedir = getattr(settings, 'BASE_DIR', None)
ですね。
このやり方なら、どこに書こうが同じ「BASE_DIR」を取得できます。
だから。
本当なら、例えば「ja.bin」みたいなデータを静的なパスで取得したい場合なども、settings.pyの中に「JA_BIN_PATH」など独自の名前で定義して読み出せばいいです。
例えば、settings.pyで。
JA_BIN = '\\etcdemo\\functions\\modules\\ja\\ja.bin'
のように独自定義を追加しておいて。
self.basedir = getattr(settings, 'BASE_DIR', None)
self.jabin = getattr(settings, 'JA_BIN', None)
self.word2vec = wv.Word2Vec(self.basedir + self.jabin)
のように、ja.binファイルのパスを取得するとかですね。
これを、ふと忘れてコピペしてしまうのが、情けない話ではありました。
ではでは。