前提
Python で CLI ツールを開発しています。開発環境は Windows です。
プログラムの規模が大きくなり、複数のファイルに分けてソースコードを管理するようになりました。しかしながら、何分大きなプロジェクトが初めての経験で色々戸惑っております。
実現したいこと
コードの可読性と管理のしやすさに重点を置いた場合の適切な設定(config
)の保持方法を知りたいです。
dataclass
より CONSTANT
で保持した方がいいとか、json
データなら json
で保持すべき等のアドバイスが欲しいです。
ユーザーによって編集できるような設定ファイルではなく、あくまでソースコードの中の話です。
設定ファイルうんぬんというより、Python におけるプロジェクト構造のベストプラクティスを知りたいのかも知りません。皆バラバラなので…。
発生している問題・エラーメッセージ
問題は発生していません。
該当のソースコード
今現在の私の設定の保持方法です。わかりやすい例でヘッダーを出していますが、他にも固定長のリストやタプルを保持することがあります。
config.py
というファイルを作成し、dataclass
の frozen
を使うことでデータの安全性を確保しているつもりです。
python
1"""config.py""" 2 3from dataclasses import dataclass, field 4 5 6@dataclass(slots=True, frozen=True) 7class Config: 8 HEADER: dict[str, str] = field( 9 default_factory=lambda: { 10 "Accept": "image/jpeg,image/jpg,image/png,image/webp", 11 "Accept-Encoding": "gzip, deflate, br", 12 "Accept-Language": "en-US,en;q=0.5", 13 "Cache-Control": "no-cache", 14 "Connection": "keep-alive", 15 "DNT": "1", 16 "Pragma": "no-cache", 17 "User-Agent": ( 18 "Mozilla/5.0 (Windows NT 10.0; rv:108.0) " 19 "Gecko/20100101 Firefox/108.0" 20 ), 21 } 22 ) 23
しかしながら、そもそも設定内容を dataclass
で保持し、エクスポートして使うことが本当に正しいのかよくわかりません。
純粋に CONSTANT
でいいのでは?とも思います。
python
1"""constant.py""" 2 3HEADER: dict[str, str] = { 4 "Accept": "image/jpeg,image/jpg,image/png,image/webp", 5 "Accept-Encoding": "gzip, deflate, br", 6 "Accept-Language": "en-US,en;q=0.5", 7 "Cache-Control": "no-cache", 8 "Connection": "keep-alive", 9 "DNT": "1", 10 "Pragma": "no-cache", 11 "User-Agent": ( 12 "Mozilla/5.0 (Windows NT 10.0; rv:108.0) " 13 "Gecko/20100101 Firefox/108.0" 14 ), 15} 16
別のファイルで読み込む場合、config.py
なら、
python
1"""helper.py""" 2 3import httpx 4from .config import Config 5 6config = Config() 7 8 9@dataclass(slots=True) 10class Downloader: 11 async def fetch(self, url: str) -> str: 12 async with httpx.AsyncClient( 13 headers=config.HEADER, 14 http2=True, 15 timeout=httpx.Timeout( 16 timeout=5.0, connect=5.0, read=5.0, write=5.0, pool=5.0 17 ), 18 ) as client: 19 res: httpx.Response = await client.get(url) 20 res.raise_for_status() 21 return res.text() 22
constant.py
なら、
python
1"""helper.py""" 2 3import httpx 4from .constant import HEADER 5 6 7@dataclass(slots=True) 8class Downloader: 9 async def fetch(self, url: str) -> str: 10 async with httpx.AsyncClient( 11 headers=HEADER, 12 http2=True, 13 timeout=httpx.Timeout( 14 timeout=5.0, connect=5.0, read=5.0, write=5.0, pool=5.0 15 ), 16 ) as client: 17 res: httpx.Response = await client.get(url) 18 res.raise_for_status() 19 return res.text() 20
これだとちょっとわかりづらいので、import constant
として、constant.HEADER
とした方がコードが読みやすいでしょうか。
そもそも初めは、同一ファイルにクラスのプロパティとして保持していました。そのうち格納したい値が増えて、ごちゃごちゃしてきたのでファイルを分けるようになりました。
試したこと
今回の例の場合、データ型が json
のため、純粋な json
ファイルで保持し、デコードしてソースコードで利用するという方法もあります。
json
1{ 2 "Accept": "image/jpeg,image/jpg,image/png,image/webp", 3 "Accept-Encoding": "gzip, deflate, br", 4 "Accept-Language": "en-US,en;q=0.5", 5 "Cache-Control": "no-cache", 6 "Connection": "keep-alive", 7 "DNT": "1", 8 "Pragma": "no-cache", 9 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:108.0) Gecko/20100101 Firefox/108.0" 10}
加えて、一般的な設定ファイル:ini
、yaml
、toml
等もデコード処理が入るため、速度面を考慮すると純粋な Python ファイルの方がいいような気もします。その辺はよくわかりません。
まとめ
ここまでの内容をまとめると、config
は、
- クラス内で直接保持
- 別のクラスで保持
- コンスタントで保持
- データ毎のネイティブな保持
のうち、どの方法がより可読性が高く管理がしやすいでしょうかというのが今回の質問です。
実際に開発されている方はどのように考えどのような理由の元に各データを配置・管理しているのかも知りたいです。
補足情報(FW/ツールのバージョンなど)
- Windows 11 home 22H2
- Python 3.11.1
- Poetry 1.3.1
- VSCode 1.7.2
回答2件
あなたの回答
tips
プレビュー