1/99スタックエンジニアの適当記録

適当なことを書きます。関西で転職したいです。

pythonのBASE_DIRについて

djangoで出てくるBASE_DIRについて書きます。

BASE_DIRとは

djangoではBASE_DIRは、「プロジェクトのベースディリクトリ」を表します。
では、どうやってBASE_DIRはベースディレクトリを表示できているのでしょうか。
答えは簡単です。
BASE_DIRはdjangoの設定ファイルである「settings.py」に定義されています。

BASE_DIRの定義場所

実際に見てみましょう。
settings.pyはdjangoプロジェクトに必ず一つは必要なので、プロジェクトを作成した時点で作られます。
例えば、django-admin startproject hogehogehogeしてみると、

C:\work\django_practice\hogehogehoge>tree /F
フォルダー パスの一覧:  ボリューム Local Disk
ボリューム シリアル番号は FAFC-01FC です
C:.
│  manage.py
│
└─hogehogehoge
        asgi.py
        settings.py
        urls.py
        wsgi.py
        __init__.py

上記のような構成のプロジェクトが作成されます。
settings.pyの中身を見てみます。

ありました。
BASE_DIRが定義されています。

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

BASE_DIRの定義

BASE_DIRの定義方法についてみてみます。

os.path.dirnameは引数のパス名からディレクトリ部分だけを抽出します。

C:\work>python
>>> import os
>>> os.path.dirname("hoge/hoge/hoge.py")
'hoge/hoge'

また、os.path.abspathは引数のパスの絶対パスを返します。

>>> import os
>>> os.path.abspath("settings.py")
'C:\\work\\django_practice\\hogehogehoge\\settings.py'

そして、__file__はグローバル変数でモジュールがロードされた絶対パスを返します。
※__File__はpythonの対話で実行するとエラーとなります。理由はモジュールがロードされていないからです。

まとめ

まとめるとabspathで「モジュールがロードされた絶対パス」の絶対パスを返し、dirname×2で「2度ディレクトリ部分だけを抽出」しているということになります。

個人的に2回ディレクトリを抽出している部分が少し謎だったのですが、ここに記述がありました。
ディレクトリの絶対パスを取得する為に、2回関数を実行しているようです。
shtaxxx.hatenablog.com
>>os.path.abspath(__file__)にos.path.dirnameを2回適用することで,
>>現在のファイルの絶対パスから親ディレクトリの絶対パスを生成している.

BASE_DIRの定義について理解が深まったところでこの記事は以上です。