PYHINTS Telegram 460
Python Hints
توی پست قبلی زیر sample.env خروجی دستور tree رو هم گذاشتم (نباید اینجا باشه) فقط گفتم شاید توی مثال‌های بعدی لازم شد. اما مهمترین فایل این مثال config.py هست. راجب lru_cache قبلا صحبت کردیم؛ اما بطور خلاصه بخوام یادآوری کنم. اگر یک تابع در طول پروژه مقدار…
خط ۱۴ تا ۱۹:
همیشه اسمش رو Global بهش میدم تا همه بچه‌های تیم بدونند تحت هر ENV_STATE ایی که باشه این تنظیمات برای پروژه واجب هست.
و بعد از این برای هر ENV_STATE یک کلاس جداگونه تعریف میشه؛ بعضی‌ موارد ممکنه مقدار default داشته باشند مثل MONGO_DBNAME توی کلاس DevConfig (دوباره برمیگردم سراغش). اما توی خط بعدی
SettingsConfigDict(env_prefix="DEV_")
چیزی که خیلی مهم هست env_prefix هست که میگه اسم‌های هرکدوم از تنظیمات لازم که توی Global تعریف شده اگر اولش DEV_ داشت توسط این کلاس هندل میشه؛ زیاده روی هست ؟ شاید باشه ولی اینطوری مطمئن میشم طرف بیشتر حواسش جمع هست موقع ساخت .env همین کار رو برای موارد دیگه هم انجام میدم. من case_sensitive رو True نمیذارم هیچوقت (شاید یکی حال نمی‌کنه از کاراکترهای uppercase استفاده کنه توی .env )

خط ۳۶ تا ۴۷:
همونطور که گفتم من هرجا تابعی دارم که return value ثابتی رو خواهد داشت یا حتی input argument های محدودی داره که همیشه return value خاص خودشون رو تولید می‌کنند از lru_cache استفاده می‌کنم که سربار کمتری روی سیستم و پردازش داشته باشه (بیشتر نمیگم چون قبلا راجبش صحبت‌ کردم؛ مثالش توی نجات پروژه رو هم زدم)
توی این تابع بر اساس مقداری که BaseConfig از .env برای ENV_STATE خواهد گرفت class معادلش رو صدا میزنم.
اما برای اینکه مطمئن بشم مقدار ENV_STATE برای مثلا DEV در صورت وجود DEV_ENV_STATE خونده نمی‌شه موقع ساخت instance اینکارو کردم :
return DevConfig(ENV_STATE="development")
که یعنی مهم نیست یوزر چی خواسته یا اینکه اصن تعریف کرده یا نه باید development باشه ENV_STATE ایی که از DevConfig میاد.

حواستون باشه ENV_STATE , DEV_ENV_STATE تنظیمات متفاوتی هست از نظر کدهای بالا بخاطر env_prefix هرچیزی که env_prefix درست رو نداشته باشه بی‌اهمیت میشه توی اون کلاس.

print(settings.model_dump())
وظیفه model_dump بازگردان خروجی بصورت dictionary هست همون کار
settings.dict()
رو می‌کنه که اتوی آپدیت‌های بعدی قرار هست deprecate بشه.

شمارو نمی‌دونم ولی من این تنظیم رو به شکوندن فایل‌ها به ۱۲ تا فایل بیس و بعدم monkey patch برای هر environment ترجیح میدم.

اما اگر تنظیمات بسیار زیادی داشتید؛ می‌تونید ازین حالت هم استفاده کنید :
├── config
│ ├── base.py
│ ├── dev.py
│ ├── __init__.py
│ ├── prod.py
│ └── test.py


و توی init تابع get_config , settings رو داشته باشید :
from functools import lru_cache

from config.base import BaseConfig, BaseSettings
from config.dev import DevConfig
from config.prod import ProdConfig
from config.test import TestConfig


@lru_cache()
def get_config(env_state: str | None) -> GlobalConfig:
try:
match env_state.casefold(): # type: ignore
case "production" | "prod":
return ProdConfig(ENV_STATE="production") # type: ignore
case "test":
return TestConfig(ENV_STATE="test") # type: ignore
case _:
return DevConfig(ENV_STATE="development") # type: ignore
except AttributeError:
return DevConfig(ENV_STATE="development") # type: ignore


settings = get_config(BaseConfig().ENV_STATE)


موقع استفاده هم یوزر راحت هست :
from myproject.config import settings


بنظرم این مورد هم حتی تمیزتر هست.‍‍‍
👍18❤‍🔥41



tgoop.com/pyHints/460
Create:
Last Update:

خط ۱۴ تا ۱۹:
همیشه اسمش رو Global بهش میدم تا همه بچه‌های تیم بدونند تحت هر ENV_STATE ایی که باشه این تنظیمات برای پروژه واجب هست.
و بعد از این برای هر ENV_STATE یک کلاس جداگونه تعریف میشه؛ بعضی‌ موارد ممکنه مقدار default داشته باشند مثل MONGO_DBNAME توی کلاس DevConfig (دوباره برمیگردم سراغش). اما توی خط بعدی
SettingsConfigDict(env_prefix="DEV_")
چیزی که خیلی مهم هست env_prefix هست که میگه اسم‌های هرکدوم از تنظیمات لازم که توی Global تعریف شده اگر اولش DEV_ داشت توسط این کلاس هندل میشه؛ زیاده روی هست ؟ شاید باشه ولی اینطوری مطمئن میشم طرف بیشتر حواسش جمع هست موقع ساخت .env همین کار رو برای موارد دیگه هم انجام میدم. من case_sensitive رو True نمیذارم هیچوقت (شاید یکی حال نمی‌کنه از کاراکترهای uppercase استفاده کنه توی .env )

خط ۳۶ تا ۴۷:
همونطور که گفتم من هرجا تابعی دارم که return value ثابتی رو خواهد داشت یا حتی input argument های محدودی داره که همیشه return value خاص خودشون رو تولید می‌کنند از lru_cache استفاده می‌کنم که سربار کمتری روی سیستم و پردازش داشته باشه (بیشتر نمیگم چون قبلا راجبش صحبت‌ کردم؛ مثالش توی نجات پروژه رو هم زدم)
توی این تابع بر اساس مقداری که BaseConfig از .env برای ENV_STATE خواهد گرفت class معادلش رو صدا میزنم.
اما برای اینکه مطمئن بشم مقدار ENV_STATE برای مثلا DEV در صورت وجود DEV_ENV_STATE خونده نمی‌شه موقع ساخت instance اینکارو کردم :
return DevConfig(ENV_STATE="development")
که یعنی مهم نیست یوزر چی خواسته یا اینکه اصن تعریف کرده یا نه باید development باشه ENV_STATE ایی که از DevConfig میاد.

حواستون باشه ENV_STATE , DEV_ENV_STATE تنظیمات متفاوتی هست از نظر کدهای بالا بخاطر env_prefix هرچیزی که env_prefix درست رو نداشته باشه بی‌اهمیت میشه توی اون کلاس.

print(settings.model_dump())
وظیفه model_dump بازگردان خروجی بصورت dictionary هست همون کار
settings.dict()
رو می‌کنه که اتوی آپدیت‌های بعدی قرار هست deprecate بشه.

شمارو نمی‌دونم ولی من این تنظیم رو به شکوندن فایل‌ها به ۱۲ تا فایل بیس و بعدم monkey patch برای هر environment ترجیح میدم.

اما اگر تنظیمات بسیار زیادی داشتید؛ می‌تونید ازین حالت هم استفاده کنید :
├── config
│ ├── base.py
│ ├── dev.py
│ ├── __init__.py
│ ├── prod.py
│ └── test.py


و توی init تابع get_config , settings رو داشته باشید :

from functools import lru_cache

from config.base import BaseConfig, BaseSettings
from config.dev import DevConfig
from config.prod import ProdConfig
from config.test import TestConfig


@lru_cache()
def get_config(env_state: str | None) -> GlobalConfig:
try:
match env_state.casefold(): # type: ignore
case "production" | "prod":
return ProdConfig(ENV_STATE="production") # type: ignore
case "test":
return TestConfig(ENV_STATE="test") # type: ignore
case _:
return DevConfig(ENV_STATE="development") # type: ignore
except AttributeError:
return DevConfig(ENV_STATE="development") # type: ignore


settings = get_config(BaseConfig().ENV_STATE)


موقع استفاده هم یوزر راحت هست :
from myproject.config import settings


بنظرم این مورد هم حتی تمیزتر هست.‍‍‍

BY Python Hints




Share with your friend now:
tgoop.com/pyHints/460

View MORE
Open in Telegram


Telegram News

Date: |

The channel also called on people to turn out for illegal assemblies and listed the things that participants should bring along with them, showing prior planning was in the works for riots. The messages also incited people to hurl toxic gas bombs at police and MTR stations, he added. The main design elements of your Telegram channel include a name, bio (brief description), and avatar. Your bio should be: How to Create a Private or Public Channel on Telegram? In 2018, Telegram’s audience reached 200 million people, with 500,000 new users joining the messenger every day. It was launched for iOS on 14 August 2013 and Android on 20 October 2013. Clear
from us


Telegram Python Hints
FROM American