پکیج `python-decouple`
یک ابزار مفید برای جداسازی تنظیمات و پیکربندیهای پروژههای پایتون است. این کار باعث میشود که کد شما از وابستگیهای محیطی جدا باشد و تنظیمات را به راحتی تغییر دهید بدون اینکه نیاز به تغییر در کد داشته باشید. این پکیج به خصوص برای مدیریت متغیرهای محیطی و تنظیمات حساس مانند کلیدهای API، اطلاعات پایگاه داده و غیره بسیار مفید است.
ویژگیها
- مدیریت متغیرهای محیطی: متغیرهای محیطی را از فایل
- پشتیبانی از انواع دادهها: قابلیت تبدیل مقادیر متغیرها به انواع دادهای مختلف مانند
- مقدار پیشفرض: امکان تعریف مقادیر پیشفرض برای متغیرهایی که ممکن است در محیط تنظیم نشده باشند.
نصب
برای نصب پکیج
نحوه استفاده
1. ایجاد فایل `.env`:
ابتدا یک فایل با نام
2. استفاده از `config` در کد پایتون:
در کد پایتون خود، پکیج
3. توضیحات بیشتر:
-
این خط مقدار متغیر
-
این خط مقدار متغیر
-
این خط مقدار متغیر
مثال کامل
فرض کنید یک پروژه ساده دارید که از Flask استفاده میکند و میخواهید تنظیمات خود را با استفاده از
1. ایجاد فایل `.env`:
2. کد پایتون:
این کد یک برنامه ساده Flask ایجاد میکند که تنظیمات خود را از فایل
#python_decouple
@Syntax_fa
یک ابزار مفید برای جداسازی تنظیمات و پیکربندیهای پروژههای پایتون است. این کار باعث میشود که کد شما از وابستگیهای محیطی جدا باشد و تنظیمات را به راحتی تغییر دهید بدون اینکه نیاز به تغییر در کد داشته باشید. این پکیج به خصوص برای مدیریت متغیرهای محیطی و تنظیمات حساس مانند کلیدهای API، اطلاعات پایگاه داده و غیره بسیار مفید است.
ویژگیها
- مدیریت متغیرهای محیطی: متغیرهای محیطی را از فایل
.env بارگذاری میکند.- پشتیبانی از انواع دادهها: قابلیت تبدیل مقادیر متغیرها به انواع دادهای مختلف مانند
int`، `float`، `bool و ...- مقدار پیشفرض: امکان تعریف مقادیر پیشفرض برای متغیرهایی که ممکن است در محیط تنظیم نشده باشند.
نصب
برای نصب پکیج
python-decouple میتوانید از دستور زیر استفاده کنید:pip install python-decouple
نحوه استفاده
1. ایجاد فایل `.env`:
ابتدا یک فایل با نام
.env در ریشه پروژه خود ایجاد کنید و تنظیمات مورد نظر خود را در آن وارد کنید. برای مثال:DEBUG=True
SECRET_KEY=mysecretkey
DATABASE_URL=postgres://user:password@localhost:5432/mydatabase
2. استفاده از `config` در کد پایتون:
در کد پایتون خود، پکیج
decouple را وارد کرده و از Config استفاده کنید:from decouple import config
DEBUG = config('DEBUG', default=False, cast=bool)
SECRET_KEY = config('SECRET_KEY')
DATABASE_URL = config('DATABASE_URL')
3. توضیحات بیشتر:
-
config('DEBUG', default=False, cast=bool):این خط مقدار متغیر
DEBUG را از فایل .env میخواند و آن را به نوع bool تبدیل میکند. اگر این متغیر در فایل .env موجود نباشد، مقدار پیشفرض False استفاده میشود.-
config('SECRET_KEY'):این خط مقدار متغیر
SECRET_KEY را از فایل .env میخواند.-
config('DATABASE_URL'):این خط مقدار متغیر
DATABASE_URL را از فایل .env میخواند.مثال کامل
فرض کنید یک پروژه ساده دارید که از Flask استفاده میکند و میخواهید تنظیمات خود را با استفاده از
python-decouple مدیریت کنید.1. ایجاد فایل `.env`:
DEBUG=True
SECRET_KEY=mysecretkey
DATABASE_URL=sqlite:///mydatabase.db
2. کد پایتون:
from flask import Flask
from decouple import config
app = Flask(__name__)
app.config['DEBUG'] = config('DEBUG', default=False, cast=bool)
app.config['SECRET_KEY'] = config('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = config('DATABASE_URL')
@app.route('/')
def home():
return "Hello, World!"
if __name__ == '__main__':
app.run()
این کد یک برنامه ساده Flask ایجاد میکند که تنظیمات خود را از فایل
.env میخواند. با این کار، میتوانید به راحتی تنظیمات خود را تغییر دهید بدون اینکه نیاز به تغییر در کد داشته باشید.#python_decouple
@Syntax_fa
👍3🔥2❤1👌1
هفت روش برای پیاده سازی dto ها در پایتون:
https://dev.to/izabelakowal/some-ideas-on-how-to-implement-dtos-in-python-be3
#python #dto
@Syntax_fa
https://dev.to/izabelakowal/some-ideas-on-how-to-implement-dtos-in-python-be3
#python #dto
@Syntax_fa
DEV Community
7 ways to implement DTOs in Python and what to keep in mind
Data Transfer Objects are simply data structures typically used to pass data between application...
🔥5👍3❤2👎1
از پایتون 3.13 چخبر؟ 🍸
1. یک مفسر تعاملی (Interactive Interpreter) بهتر
پایتون 3.13 بهبودهای قابل توجهی در مفسر تعاملی به همراه پیامهای خطای پیشرفته معرفی میکند. مفسر تعاملی جدید اکنون از رنگبندی پشتیبانی میکند و تجربهای بصریتر ارائه میدهد. این پشتیبانی از رنگ به tracebacks و خروجی doctest نیز گسترش مییابد. کاربران میتوانند رنگبندی را از طریق متغیرهای محیطی PYTHON_COLORS و NO_COLOR غیرفعال کنند.
علاوه بر این، پایتون 3.12 شامل یک کامپایلر JIT (Just-In-Time) اولیه بر اساس PEP 744 است. اگرچه در حال حاضر بهطور پیشفرض غیرفعال است، این کامپایلر نشاندهنده بهبودهای عملکردی امیدوارکنندهای است و برنامههایی برای بهبودهای بیشتر در نسخههای بعدی وجود دارد.
2. کامپایل آزمایشی Just-in-Time (JIT)
پایتون یک کامپایلر آزمایشی just-in-time (JIT) معرفی میکند که در صورت فعالسازی، میتواند برخی برنامههای پایتون را سریعتر کند. کامپایلر JIT با ترجمه bytecode تخصصی Tier 1 به یک نمایش میانی داخلی Tier 2 جدید کار میکند که برای ترجمه به کد ماشین بهینه شده است. چندین مرحله بهینهسازی به Tier 2 IR اعمال میشود قبل از اینکه تفسیر یا به کد ماشین ترجمه شود. گزینههای پیکربندی (–enable-experimental-jit) به کاربران اجازه میدهد تا رفتار JIT را در زمان ساخت و اجرا کنترل کنند، از جمله فعال یا غیرفعال کردن JIT و مفسر Tier
مزایای بالقوه کامپایلر JIT:
بهبود عملکرد قابل توجه برای بخشهای خاصی از کد که از اجرای کد ماشین سود میبرند.
امکان بهینهسازیهای آینده که قبلاً با تفسیر bytecode ممکن نبودند.
3. سی پایتون (CPython) آزمایشی بدون GIL
سی پایتون اکنون از اجرای بدون Global Interpreter Lock (GIL) پشتیبانی میکند، که امکان اجرای multithreadding آزاد را با پیکربندی –disable-gil فراهم میسازد. اجرای چندریسمانی آزاد به بهرهبرداری بهتر از هستههای CPU موجود از طریق اجرای موازی ریسمانها کمک میکند و به برنامههایی که برای threading طراحی شدهاند، سود میرساند.
ماژولهای توسعه C-API باید بهطور خاص برای ساختار چندریسمانی آزاد ساخته شوند و باید با استفاده از مکانیزمهای مناسب، پشتیبانی از اجرای بدون GIL را نشان دهند.
4. گزارشدهی و راهنمایی خطای بهبود یافته
ردیابی خطا در پایتون در نسخه جدید بهبود یافته است. مفسر اکنون پیامهای خطا را بهطور پیشفرض هنگام نمایش tracebacks رنگی میکند. در ویژگی دیگر، پیام خطا در صورت ارسال یک کلیدواژه اشتباه به یک تابع، کلیدواژه صحیح را پیشنهاد میدهد.
گاهی اوقات که یک اسکریپت همنام یک ماژول کتابخانه استاندارد است، پایتون اکنون پیام خطای دقیقی ارائه میدهد و پیشنهاد میکند برای درک بهتر، نام ماژول تغییر کند.
5. جمعآوری زباله افزایشی
پایتون 3.12 جمعآوری زباله افزایشی را معرفی میکند که زمان توقف حداکثر را برای هیپهای بزرگتر به طور قابل توجهی کاهش میدهد. این بهبود بهویژه برای برنامههایی با تخصیص و آزادسازی حافظه زیاد مفید است.
این ویژگی به برنامههای پایتون اجازه میدهد تا روانتر اجرا شوند و تأثیر توقفهای جمعآوری زباله کاهش یابد، که به بهبود عملکرد کلی و واکنشپذیری منجر میشود.
6. بهینهسازی حافظه برای Docstrings
پایتون 3.13 تغییری ظریف اما مؤثر برای بهبود کارایی حافظه معرفی میکند: بهینهسازی حافظه برای Docstrings. این ویژگی منبع پنهانی از استفاده حافظه و اندازه فایل مرتبط با docstrings در کد پایتون را هدف قرار میدهد.
محدودیتهای Docstrings سنتی در پایتون به شرح زیر است:
بهطور سنتی، docstrings در پایتون شامل هر گونه فاصله تورفتگی ابتدایی بودند. در حالی که این فضاهای اضافی به نظر بیضرر میآیند، به اندازه کلی فایلهای bytecode کامپایلشده (.pyc) افزوده و احتمالاً استفاده از حافظه را هنگام اجرای کد افزایش میدادند.
مزایای بهینهسازی حافظه برای Docstrings:
بهینهسازی حافظه برای Docstrings این ناکارآمدی را برطرف میکند. بهطور خودکار هر گونه تورفتگی ابتدایی را از docstrings قبل از فرآیند کامپایل حذف میکند.
این اطمینان میدهد که تنها محتوای واقعی docstring ذخیره میشود، که منجر به:
کاهش استفاده از حافظه برای فایلهای bytecode کامپایلشده.
احتمالاً کاهش استفاده از حافظه در هنگام اجرای برنامه، بهویژه برای پروژههایی با docstring گسترده.
Source
#python
@Syntax_fa
1. یک مفسر تعاملی (Interactive Interpreter) بهتر
پایتون 3.13 بهبودهای قابل توجهی در مفسر تعاملی به همراه پیامهای خطای پیشرفته معرفی میکند. مفسر تعاملی جدید اکنون از رنگبندی پشتیبانی میکند و تجربهای بصریتر ارائه میدهد. این پشتیبانی از رنگ به tracebacks و خروجی doctest نیز گسترش مییابد. کاربران میتوانند رنگبندی را از طریق متغیرهای محیطی PYTHON_COLORS و NO_COLOR غیرفعال کنند.
علاوه بر این، پایتون 3.12 شامل یک کامپایلر JIT (Just-In-Time) اولیه بر اساس PEP 744 است. اگرچه در حال حاضر بهطور پیشفرض غیرفعال است، این کامپایلر نشاندهنده بهبودهای عملکردی امیدوارکنندهای است و برنامههایی برای بهبودهای بیشتر در نسخههای بعدی وجود دارد.
2. کامپایل آزمایشی Just-in-Time (JIT)
پایتون یک کامپایلر آزمایشی just-in-time (JIT) معرفی میکند که در صورت فعالسازی، میتواند برخی برنامههای پایتون را سریعتر کند. کامپایلر JIT با ترجمه bytecode تخصصی Tier 1 به یک نمایش میانی داخلی Tier 2 جدید کار میکند که برای ترجمه به کد ماشین بهینه شده است. چندین مرحله بهینهسازی به Tier 2 IR اعمال میشود قبل از اینکه تفسیر یا به کد ماشین ترجمه شود. گزینههای پیکربندی (–enable-experimental-jit) به کاربران اجازه میدهد تا رفتار JIT را در زمان ساخت و اجرا کنترل کنند، از جمله فعال یا غیرفعال کردن JIT و مفسر Tier
مزایای بالقوه کامپایلر JIT:
بهبود عملکرد قابل توجه برای بخشهای خاصی از کد که از اجرای کد ماشین سود میبرند.
امکان بهینهسازیهای آینده که قبلاً با تفسیر bytecode ممکن نبودند.
3. سی پایتون (CPython) آزمایشی بدون GIL
سی پایتون اکنون از اجرای بدون Global Interpreter Lock (GIL) پشتیبانی میکند، که امکان اجرای multithreadding آزاد را با پیکربندی –disable-gil فراهم میسازد. اجرای چندریسمانی آزاد به بهرهبرداری بهتر از هستههای CPU موجود از طریق اجرای موازی ریسمانها کمک میکند و به برنامههایی که برای threading طراحی شدهاند، سود میرساند.
ماژولهای توسعه C-API باید بهطور خاص برای ساختار چندریسمانی آزاد ساخته شوند و باید با استفاده از مکانیزمهای مناسب، پشتیبانی از اجرای بدون GIL را نشان دهند.
4. گزارشدهی و راهنمایی خطای بهبود یافته
ردیابی خطا در پایتون در نسخه جدید بهبود یافته است. مفسر اکنون پیامهای خطا را بهطور پیشفرض هنگام نمایش tracebacks رنگی میکند. در ویژگی دیگر، پیام خطا در صورت ارسال یک کلیدواژه اشتباه به یک تابع، کلیدواژه صحیح را پیشنهاد میدهد.
گاهی اوقات که یک اسکریپت همنام یک ماژول کتابخانه استاندارد است، پایتون اکنون پیام خطای دقیقی ارائه میدهد و پیشنهاد میکند برای درک بهتر، نام ماژول تغییر کند.
>>> sys.version_info
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined. Did you forget to import 'sys'!
5. جمعآوری زباله افزایشی
پایتون 3.12 جمعآوری زباله افزایشی را معرفی میکند که زمان توقف حداکثر را برای هیپهای بزرگتر به طور قابل توجهی کاهش میدهد. این بهبود بهویژه برای برنامههایی با تخصیص و آزادسازی حافظه زیاد مفید است.
# Python 3.12
import gc
gc.isincremental() # Returns True
این ویژگی به برنامههای پایتون اجازه میدهد تا روانتر اجرا شوند و تأثیر توقفهای جمعآوری زباله کاهش یابد، که به بهبود عملکرد کلی و واکنشپذیری منجر میشود.
6. بهینهسازی حافظه برای Docstrings
پایتون 3.13 تغییری ظریف اما مؤثر برای بهبود کارایی حافظه معرفی میکند: بهینهسازی حافظه برای Docstrings. این ویژگی منبع پنهانی از استفاده حافظه و اندازه فایل مرتبط با docstrings در کد پایتون را هدف قرار میدهد.
محدودیتهای Docstrings سنتی در پایتون به شرح زیر است:
بهطور سنتی، docstrings در پایتون شامل هر گونه فاصله تورفتگی ابتدایی بودند. در حالی که این فضاهای اضافی به نظر بیضرر میآیند، به اندازه کلی فایلهای bytecode کامپایلشده (.pyc) افزوده و احتمالاً استفاده از حافظه را هنگام اجرای کد افزایش میدادند.
مزایای بهینهسازی حافظه برای Docstrings:
بهینهسازی حافظه برای Docstrings این ناکارآمدی را برطرف میکند. بهطور خودکار هر گونه تورفتگی ابتدایی را از docstrings قبل از فرآیند کامپایل حذف میکند.
این اطمینان میدهد که تنها محتوای واقعی docstring ذخیره میشود، که منجر به:
کاهش استفاده از حافظه برای فایلهای bytecode کامپایلشده.
احتمالاً کاهش استفاده از حافظه در هنگام اجرای برنامه، بهویژه برای پروژههایی با docstring گسترده.
Source
#python
@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13💋3👍2❤1🥰1
تو چند دقیقه نحوه کار با Redis Pub/Sub رو تو پایتون یاد بگیر
Pub/Sub
(انتشار/اشتراک) یک الگوی معماری است که به برنامهها اجازه میدهد تا به صورت غیرمستقیم با یکدیگر ارتباط برقرار کنند. در این الگو، تولیدکنندگان اطلاعات (Publisher) پیامها را منتشر میکنند و مصرفکنندگان (Subscriber) به موضوعات (Topics) خاصی که به آنها علاقهمند هستند، اشتراک میگذارند. این سیستم اجازه میدهد تا بدون نیاز به وابستگی مستقیم با یکدیگر، اطلاعات را تبادل کنند.
مزایای Pub/Sub
- کاهش وابستگیها: تولیدکنندگان و مصرفکنندگان نیازی به شناخت یکدیگر ندارند.
- مقیاسپذیری: میتوان به سادگی مصرفکنندگان و تولیدکنندگان جدیدی اضافه کرد.
- توزیعپذیری: میتوان سیستمها را به صورت توزیعشده پیادهسازی کرد.
مثال ساده با Redis Pub/Sub
در این مثال، از Redis به عنوان سیستم Pub/Sub استفاده خواهیم کرد. ابتدا باید Redis را نصب و راهاندازی کنید.
نصب Redis
تو ریپازیتوری ای که لینکشو آخر پست میذارم، سرویس ردیس رو توی docker-compose.yml مشخص کردم و روی داکر اجراش میکنیم.
همچنین داخل فایل .env تنظیمات ردیس رو میتونید مشخص کنید.
پیادهسازی در پایتون
برای این کار به کتابخانه
در این مثال، یک Publisher و یک Subscriber خواهیم داشت.
Publisher (server.py):
در قدم اول کانکشن با ردیس رو می سازیم.
با متد ping میتونیم چک کنیم وضعیت کانگشنمون اوکی هست یا نه(جنبه آموزشی نوشتمش)
بعد مشخص کردیم که topic ما اسمش چیه.
دیتایی که قراره داخل payload مسیج قرار بدیم رو مشخص کردیم که بصورت دیکشنری هستش و بعدش اومدیم به json تبدیلش کردیم و مسیح رو پابلیش کردیم.
Subscriber (client.py):
در قدم اول یک کانکشن ردیس گرفتیم. بعد تاپیکی که subscribe میکنیمش رو مشخص کردیم(میتونیم چندین تا تاپیک رو سابسکرایب کنیم)
در قدم بعدی داخل یک long running میایم به مسیج های جدیدی که میاد گوش میدیم و یک switch case زدیم و براساس تاپیک ها میتونیم کارهای خاص خودش رو انجام بدیم.
نحوه اجرا
1. در یک ترمینال،
2. در یک ترمینال دیگه server.py رو اجرا کنید که با هربار اجرا یک مسیج رو پابلیش میکنه.
سورس کد:
https://github.com/alireza-fa/redis-pub-sub-example
#redis_pub_sub #pub_sub #event_driven #python
@Syntax_fa
Pub/Sub
(انتشار/اشتراک) یک الگوی معماری است که به برنامهها اجازه میدهد تا به صورت غیرمستقیم با یکدیگر ارتباط برقرار کنند. در این الگو، تولیدکنندگان اطلاعات (Publisher) پیامها را منتشر میکنند و مصرفکنندگان (Subscriber) به موضوعات (Topics) خاصی که به آنها علاقهمند هستند، اشتراک میگذارند. این سیستم اجازه میدهد تا بدون نیاز به وابستگی مستقیم با یکدیگر، اطلاعات را تبادل کنند.
مزایای Pub/Sub
- کاهش وابستگیها: تولیدکنندگان و مصرفکنندگان نیازی به شناخت یکدیگر ندارند.
- مقیاسپذیری: میتوان به سادگی مصرفکنندگان و تولیدکنندگان جدیدی اضافه کرد.
- توزیعپذیری: میتوان سیستمها را به صورت توزیعشده پیادهسازی کرد.
مثال ساده با Redis Pub/Sub
در این مثال، از Redis به عنوان سیستم Pub/Sub استفاده خواهیم کرد. ابتدا باید Redis را نصب و راهاندازی کنید.
نصب Redis
تو ریپازیتوری ای که لینکشو آخر پست میذارم، سرویس ردیس رو توی docker-compose.yml مشخص کردم و روی داکر اجراش میکنیم.
همچنین داخل فایل .env تنظیمات ردیس رو میتونید مشخص کنید.
docker-compose up -d
پیادهسازی در پایتون
برای این کار به کتابخانه
redis نیاز داریم. میتوانید آن را با pip نصب کنید:pip install redis
در این مثال، یک Publisher و یک Subscriber خواهیم داشت.
Publisher (server.py):
import json
from redis import StrictRedis
server = StrictRedis(host="localhost", port=6399, password="redis_password", db=0)
# redis ping
print(server.ping())
topic = "example_topic"
data = {
"name": "alireza",
"age": 22,
}
server.publish(channel=topic, message=json.dumps(data))
در قدم اول کانکشن با ردیس رو می سازیم.
با متد ping میتونیم چک کنیم وضعیت کانگشنمون اوکی هست یا نه(جنبه آموزشی نوشتمش)
بعد مشخص کردیم که topic ما اسمش چیه.
دیتایی که قراره داخل payload مسیج قرار بدیم رو مشخص کردیم که بصورت دیکشنری هستش و بعدش اومدیم به json تبدیلش کردیم و مسیح رو پابلیش کردیم.
Subscriber (client.py):
import json
from redis import StrictRedis
client = StrictRedis(host="localhost", port=6399, password="redis_password", db=0)
topic = "example_topic"
pubsub = client.pubsub()
pubsub.subscribe(topic)
print("waiting for message...")
while True:
for message in pubsub.listen():
if message["data"] == 1:
continue
match message["type"]:
case topic:
# TODO - change serialization. json is not good
data = json.loads(message["data"])
print("received message", data["name"], data["age"])
در قدم اول یک کانکشن ردیس گرفتیم. بعد تاپیکی که subscribe میکنیمش رو مشخص کردیم(میتونیم چندین تا تاپیک رو سابسکرایب کنیم)
در قدم بعدی داخل یک long running میایم به مسیج های جدیدی که میاد گوش میدیم و یک switch case زدیم و براساس تاپیک ها میتونیم کارهای خاص خودش رو انجام بدیم.
نحوه اجرا
1. در یک ترمینال،
client.py را اجرا کنید2. در یک ترمینال دیگه server.py رو اجرا کنید که با هربار اجرا یک مسیج رو پابلیش میکنه.
سورس کد:
https://github.com/alireza-fa/redis-pub-sub-example
#redis_pub_sub #pub_sub #event_driven #python
@Syntax_fa
🔥6💋4👍3❤1👎1🙏1
ساخت یک Dockerfile مناسب برای پروژه های پایتونی:
خیلی خوب توضیح داده.
https://luis-sena.medium.com/creating-the-perfect-python-dockerfile-51bdec41f1c8
#python #Dockerfile
@Syntax_fa
خیلی خوب توضیح داده.
https://luis-sena.medium.com/creating-the-perfect-python-dockerfile-51bdec41f1c8
#python #Dockerfile
@Syntax_fa
Medium
Creating the Perfect Python Dockerfile
Increase your python code performance and security without changing the project source code.
💋7🔥1👌1🎃1
Syntax | سینتکس
ساخت یک Dockerfile مناسب برای پروژه های پایتونی: خیلی خوب توضیح داده. https://luis-sena.medium.com/creating-the-perfect-python-dockerfile-51bdec41f1c8 #python #Dockerfile @Syntax_fa
و اما Docekrfile که من از توضیحات ایشون رسیدم بهش:
نظر بدید
#python #dockerfile
@Syntax_fa
FROM python:3.11-slim as builder
# avoid stuck build due to user prompt
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y --no-install-recommends ...
# create and activate virtual environment
RUN python -m venv /home/myuser/venv
ENV PATH="/home/myuser/venv/bin:$PATH"
# install requirements
COPY ./requirements .
RUN pip3 install --upgrade --no-cache-dir pip
RUN pip3 install --no-cache-dir wheel
RUN pip3 install --no-cache-dir -r production.txt
FROM python:3.11-slim
RUN useradd --create-home myuser
COPY --from=builder /home/myuser/venv /home/myuser/venv
USER myuser
RUN mkdir /home/myuser/code
WORKDIR /home/myuser/code
COPY . /home/myuser/code
EXPOSE $DJANGO_PORT
# make sure all messages always reach console
ENV PYTHONUNBUFFERED=1
# activate virtual environment
ENV VIRTUAL_ENV=/home/myuser/venv
ENV PATH="/home/myuser/venv/bin:$PATH"
# /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat
# this will improve performance and avoid random freezes
# CMD ["gunicorn","-b", "0.0.0.0:8000", "-w", "4", "-k", "gevent", "--worker-tmp-dir", "/dev/shm", "--chdir", "config config.wsgi:application"]
نظر بدید
#python #dockerfile
@Syntax_fa
🔥6👍1🤣1🤨1
ارور ثروتمند و یا RichError 😏
ریچ ارور یک الگوی مدیریت خطا در برنامهنویسی است که به شما این امکان رو میده تا اطلاعات دقیقتری درباره خطاها ها و لایه های مختلفی که این خطا رخ داده تا در نهایت به دست شما رسیده ذخیره کنید و بر اساس این اطلاعات جمع آوری شده، به کاربر یا سیستمهای دیگه ارور و پیغام مناسب رو به راحتی نمایش بدید.
بر خلاف خطاهای استاندارد که معمولاً فقط شامل یک پیام یا کد خطا هستند، RichError میتونه شامل اطلاعات اضافی مثل متا دیتا، اپریشنی که توش خطا رخ داده، ارور های لایه پایین تر و هر اطلاعاتی که بدردتون میخوره رو داشته باشید.
چرا بهش Rich error میگیم؟
1. اطلاعات بیشتر:
- ریچ ارور میتونه شامل پیام خطا، کد خطا، نام عملی که باعث خطا شده و هر نوع اطلاعات دیگه باشه. این اطلاعات میتونن شامل متا دیتاهایی باشن که به درک بهتر مشکل کمک میکنن(خیلی کمک میکنن).
2. ساختار تو در تو:
- ریچ ارور میتونه به شما اجازه بده که خطاهای تو در تو رو مدیریت کنید. به این معنی که اگر یک خطا ناشی از یک خطای دیگه باشه میتونید به خطای اصلی برسید و درواقع خطایی از دست نمیره.
3. خیلی کارتونو راحت تر میکنه:
- تو مثال هایی که براتون زدم میفهمید که چقدر کارتون رو ساده تر میکنه همچنین باعث میشه کدتون منظم تر و یکپارچه بشه.
اگه هنوز درباره استفاده از Rich error دودلی اینم چند مزایای دیگه:
1. تشخیص بهتر مشکلات:
- با داشتن اطلاعات غنی درباره خطاها، تیمهای توسعه میتونن سریعتر و دقیقتر مشکلات رو شناسایی و حل کنن.
2. تجربه کاربری بهبود یافته:
- وقتی که خطاها به صورت واضح و با اطلاعات کافی به کاربر نمایش داده بشه، تجربه کاربری خیلی بهتر میشه.
3. توسعه سریعتر:
- با استفاده از RichError، سرعت توسعتون بیشتر میشه(طبق تجربه خودم)
5. سازگاری با سیستمهای دیگه:
- اطلاعات کافی و ساختارمند ریچ ارور میتونه به راحتی به سیستمهای دیگر منتقل بشه مثلا میتونید توی لاگرتون هم از اطلاعات ریچ ارور استفاده کنید.
چطور یک ریچ ارور خوب بنویسیم؟
تو ریپازیتوری زیر من ریچ اروری که تقریبا خودم استفاده میکنم رو قرار دادم. همچنین بخوبی درباره rich error توضیح دادم که اگه دوست دارید خودتون بنویسید چه مواردی رو باید رعایت کنید.
https://github.com/alireza-fa/rich-error
برای نصب:
ستاره فراموش نشه❤️
#rich_error #python
@Syntax_fa
ریچ ارور یک الگوی مدیریت خطا در برنامهنویسی است که به شما این امکان رو میده تا اطلاعات دقیقتری درباره خطاها ها و لایه های مختلفی که این خطا رخ داده تا در نهایت به دست شما رسیده ذخیره کنید و بر اساس این اطلاعات جمع آوری شده، به کاربر یا سیستمهای دیگه ارور و پیغام مناسب رو به راحتی نمایش بدید.
بر خلاف خطاهای استاندارد که معمولاً فقط شامل یک پیام یا کد خطا هستند، RichError میتونه شامل اطلاعات اضافی مثل متا دیتا، اپریشنی که توش خطا رخ داده، ارور های لایه پایین تر و هر اطلاعاتی که بدردتون میخوره رو داشته باشید.
چرا بهش Rich error میگیم؟
1. اطلاعات بیشتر:
- ریچ ارور میتونه شامل پیام خطا، کد خطا، نام عملی که باعث خطا شده و هر نوع اطلاعات دیگه باشه. این اطلاعات میتونن شامل متا دیتاهایی باشن که به درک بهتر مشکل کمک میکنن(خیلی کمک میکنن).
2. ساختار تو در تو:
- ریچ ارور میتونه به شما اجازه بده که خطاهای تو در تو رو مدیریت کنید. به این معنی که اگر یک خطا ناشی از یک خطای دیگه باشه میتونید به خطای اصلی برسید و درواقع خطایی از دست نمیره.
3. خیلی کارتونو راحت تر میکنه:
- تو مثال هایی که براتون زدم میفهمید که چقدر کارتون رو ساده تر میکنه همچنین باعث میشه کدتون منظم تر و یکپارچه بشه.
اگه هنوز درباره استفاده از Rich error دودلی اینم چند مزایای دیگه:
1. تشخیص بهتر مشکلات:
- با داشتن اطلاعات غنی درباره خطاها، تیمهای توسعه میتونن سریعتر و دقیقتر مشکلات رو شناسایی و حل کنن.
2. تجربه کاربری بهبود یافته:
- وقتی که خطاها به صورت واضح و با اطلاعات کافی به کاربر نمایش داده بشه، تجربه کاربری خیلی بهتر میشه.
3. توسعه سریعتر:
- با استفاده از RichError، سرعت توسعتون بیشتر میشه(طبق تجربه خودم)
5. سازگاری با سیستمهای دیگه:
- اطلاعات کافی و ساختارمند ریچ ارور میتونه به راحتی به سیستمهای دیگر منتقل بشه مثلا میتونید توی لاگرتون هم از اطلاعات ریچ ارور استفاده کنید.
چطور یک ریچ ارور خوب بنویسیم؟
تو ریپازیتوری زیر من ریچ اروری که تقریبا خودم استفاده میکنم رو قرار دادم. همچنین بخوبی درباره rich error توضیح دادم که اگه دوست دارید خودتون بنویسید چه مواردی رو باید رعایت کنید.
https://github.com/alireza-fa/rich-error
برای نصب:
pip install rich-error
ستاره فراموش نشه❤️
#rich_error #python
@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥5👌3
Syntax | سینتکس
ارور ثروتمند و یا RichError 😏 ریچ ارور یک الگوی مدیریت خطا در برنامهنویسی است که به شما این امکان رو میده تا اطلاعات دقیقتری درباره خطاها ها و لایه های مختلفی که این خطا رخ داده تا در نهایت به دست شما رسیده ذخیره کنید و بر اساس این اطلاعات جمع آوری شده،…
برای آشنایی بیشتر یه مثال هم اضافه کنم:
اگر از rich error استفاده نکنیم، برای هندل کردن ارور های مختلف مجبور بودیم از یک سولوشن دیگه بجز exception استفاده کنیم و یا اینکه بیایم و برای هر ارور به این صورت exceptionبنویسیم:
در handler هم باید این کار رو میکردیم:
در این صورت هرچقدر تعداد exceptionها بیشتر شود مدیریت کردن آنها نیز سخت تر خواهد شد. همچنین قدرت مشاهده گری سیستم با استفاده از exception ها نیز پایین می آید در صورتی که ما در rich error تمامی ارور هایی که در لایه های مختلف رخ داده باشند رو داشتیم.
اگه کد رو با rich error جایگزین کنیم:
از آنجا که ما یک ارور غنی داریم و از کد ها استفاده کردیم به راحتی میدانیم که این ارور به چه معنی است و حتی به سادگی http error مناسب را برگردانیم.
#rich_error #python
@Syntax_fa
اگر از rich error استفاده نکنیم، برای هندل کردن ارور های مختلف مجبور بودیم از یک سولوشن دیگه بجز exception استفاده کنیم و یا اینکه بیایم و برای هر ارور به این صورت exceptionبنویسیم:
class UserNotFoundErr(Exception):
pass
class IpBlockedErr(Exception):
pass
class TooManyRequestErr(Exception):
pass
class UserConflictErr(Exception):
pass
در handler هم باید این کار رو میکردیم:
from examples.without_rich_error.service import get_user_service
from examples.without_rich_error.exception import UserNotFoundErr, UserConflictErr, TooManyRequestErr, IpBlockedErr
def get_user_handler(user_id: int):
try:
print(service.get_user_by_id(user_id=user_id))
except UserNotFoundErr as err:
print("user not found code is 404", err)
except UserConflictErr as err:
print("user conflict code is 409", err)
except TooManyRequestErr as err:
print("too many request code is 429", err)
except IpBlockedErr as err:
print("ip blocked code is 403", err)
در این صورت هرچقدر تعداد exceptionها بیشتر شود مدیریت کردن آنها نیز سخت تر خواهد شد. همچنین قدرت مشاهده گری سیستم با استفاده از exception ها نیز پایین می آید در صورتی که ما در rich error تمامی ارور هایی که در لایه های مختلف رخ داده باشند رو داشتیم.
اگه کد رو با rich error جایگزین کنیم:
from examples.with_rich_error.api import base_response_with_error, base_response
def get_user_handler(user_id: int):
try:
...
except Exception as err:
return base_response_with_error(error=err)
از آنجا که ما یک ارور غنی داریم و از کد ها استفاده کردیم به راحتی میدانیم که این ارور به چه معنی است و حتی به سادگی http error مناسب را برگردانیم.
#rich_error #python
@Syntax_fa
👍8🔥5👏1
نکات مهم اجرای جنگو با Gunicorn
توضیح درباره Gunicorn
نمیخوام توضیحات زیادی بدم حوصلتون سر بره پس همون سه خط معرفی که تو وب سایت gunicorn نوشته رو براتون یکم شفافش میکنم:
اسمش مخفف green unicorn هستش
جی یونیکورن یک http سرور هستش که از استاندارد WSGI(Web server gateway interface) برای اجرای برنامه های وب پایتون استفاده میکنه.
استاندارد WSGI برای این بوجود اومد تا هر فریم ورک وب پایتونی روش خودشو واسه ارتباط پیاده نکنه و همه از یه استاندارد مشخص استفاده کنن.
در ادامه میگه gunicorn برای unix هستش و برای سیستم عامل هایی مثل مک و لینوکس طراحی شده.
بعدش میگه که جی یونیکورن از مدل pre-fork worker استفاده میکنه حالا این به چه معنیه؟
جی یونیکورن کاری که میکنه اینه قبل اینکه شروع به پردازش درخواست ها کنه، میاد و به اندازه ای که تنظیم کردید worker ایجاد میکنه که هر worker درخواست هارو بطور مستقل پردازش میکنه.
بعدشم میگه با فریم ورک های وب مختلفی سازگاره که اینم میتونیم دلیلش رو این بدونیم داره برای ارتباط از استاندارد WSGI استفاده میکنه.
قسمت آخرشم میگه light resource هستش و منابع کمی مصرف میکنه همچنین برای ترافیک بالا عملکرد خوبی داره.
خب جی یونیکورن این ادعا هارو میکنه اما بیاید با چند تا مثال شرایطی رو بررسی کنیم که شما به غلط دارید از جی یونیکورن استفاده میکنید:
مثال اول
اگه با این دستور جی یونیکورن رو اجرا کنید باید به این نکته دقت کنید بصورت پیشفرض براتون فقط یدونه worker میسازه که این اصلا خوب نیست. خود جی یونیکورن پیشنهاد میده حتی اگه یدونه core دارید 4 تا ورکر بسازید و یه فرمولی هم داده که میگه«تعداد هسته های سی پی یو رو ضربدر 2 به علاوه یک کنید»
همچنین به شما اطمینان داده همین تعداد ورکر هزاران ریکوئست رو میتونن پاسخ بدن پس تعداد ورکر هارو الکی زیادش نکنید.
البته به کیس شما هم بستگی داره.
دستور بهتر برای اجرا اینه تعداد ورکر هارو مشخص کنیم:
مثال دوم:
فرض کنید کاربر ها تو اپلیکیشن شما فایل هایی رو آپلود میکنن. شما پنج تا ورکر دارید.
وقتی پنج تا کاربر همزمان فایل آپلود کنن بنظرتون چه اتفاقی میوفته؟
پنج تا ورکر شما گیر یه io افتادن و مشغولن و درخواست های دیگه کاربرا انجام نمیشه. خب این وضعیتی نیست که باب میلیتون باشه!
برای حل این مشکل کافیه از gevent توی جی یونیکرون استفاده گنید؛
با فلگ -k نوع کلاس ورکر رو مشخص میکنیم. حالا چرا از gevent استفاده میکنیم؟
کتابخونه gevent برای مدریریت همزمانی طراحی شده. میشه گفت یک نمونه lightweight thread هستش که این مدل موقع عملیات های IO سوئیچینگ انجام میده و در این صورت اگه به io خوردید براتون هندل میکنه.
کلی نکات دیگه هم قطعا هست که تو یه پست جا نمیشه
امیدوارم براتون مفید باشه
#python #django #gunicorn #gevent
@Syntax_fa
توضیح درباره Gunicorn
نمیخوام توضیحات زیادی بدم حوصلتون سر بره پس همون سه خط معرفی که تو وب سایت gunicorn نوشته رو براتون یکم شفافش میکنم:
اسمش مخفف green unicorn هستش
جی یونیکورن یک http سرور هستش که از استاندارد WSGI(Web server gateway interface) برای اجرای برنامه های وب پایتون استفاده میکنه.
استاندارد WSGI برای این بوجود اومد تا هر فریم ورک وب پایتونی روش خودشو واسه ارتباط پیاده نکنه و همه از یه استاندارد مشخص استفاده کنن.
در ادامه میگه gunicorn برای unix هستش و برای سیستم عامل هایی مثل مک و لینوکس طراحی شده.
بعدش میگه که جی یونیکورن از مدل pre-fork worker استفاده میکنه حالا این به چه معنیه؟
جی یونیکورن کاری که میکنه اینه قبل اینکه شروع به پردازش درخواست ها کنه، میاد و به اندازه ای که تنظیم کردید worker ایجاد میکنه که هر worker درخواست هارو بطور مستقل پردازش میکنه.
بعدشم میگه با فریم ورک های وب مختلفی سازگاره که اینم میتونیم دلیلش رو این بدونیم داره برای ارتباط از استاندارد WSGI استفاده میکنه.
قسمت آخرشم میگه light resource هستش و منابع کمی مصرف میکنه همچنین برای ترافیک بالا عملکرد خوبی داره.
خب جی یونیکورن این ادعا هارو میکنه اما بیاید با چند تا مثال شرایطی رو بررسی کنیم که شما به غلط دارید از جی یونیکورن استفاده میکنید:
مثال اول
gunicorn --chdir config config.wsgi:application -b 0.0.0.0:8000
اگه با این دستور جی یونیکورن رو اجرا کنید باید به این نکته دقت کنید بصورت پیشفرض براتون فقط یدونه worker میسازه که این اصلا خوب نیست. خود جی یونیکورن پیشنهاد میده حتی اگه یدونه core دارید 4 تا ورکر بسازید و یه فرمولی هم داده که میگه«تعداد هسته های سی پی یو رو ضربدر 2 به علاوه یک کنید»
همچنین به شما اطمینان داده همین تعداد ورکر هزاران ریکوئست رو میتونن پاسخ بدن پس تعداد ورکر هارو الکی زیادش نکنید.
البته به کیس شما هم بستگی داره.
دستور بهتر برای اجرا اینه تعداد ورکر هارو مشخص کنیم:
gunicorn --workers 5 --chdir config config.wsgi:application -b 0.0.0.0:8000
مثال دوم:
فرض کنید کاربر ها تو اپلیکیشن شما فایل هایی رو آپلود میکنن. شما پنج تا ورکر دارید.
وقتی پنج تا کاربر همزمان فایل آپلود کنن بنظرتون چه اتفاقی میوفته؟
پنج تا ورکر شما گیر یه io افتادن و مشغولن و درخواست های دیگه کاربرا انجام نمیشه. خب این وضعیتی نیست که باب میلیتون باشه!
برای حل این مشکل کافیه از gevent توی جی یونیکرون استفاده گنید؛
gunicorn --workers 1 -k gevent --chdir config config.wsgi:application -b 0.0.0.0:8000
با فلگ -k نوع کلاس ورکر رو مشخص میکنیم. حالا چرا از gevent استفاده میکنیم؟
کتابخونه gevent برای مدریریت همزمانی طراحی شده. میشه گفت یک نمونه lightweight thread هستش که این مدل موقع عملیات های IO سوئیچینگ انجام میده و در این صورت اگه به io خوردید براتون هندل میکنه.
کلی نکات دیگه هم قطعا هست که تو یه پست جا نمیشه
امیدوارم براتون مفید باشه
#python #django #gunicorn #gevent
@Syntax_fa
👍15❤4🔥1🙏1
Linter & pylint
لینتر ابزاری است که برای تحلیل کد استفاده میشود تا مشکلات احتمالی در کد را شناسایی کند. این ابزارها به توسعهدهندگان کمک میکنند تا با شناسایی خطاهای سینتکس، استانداردهای کدنویسی و مسائلی مانند memory leak و ... را شناسایی کنند و کیفیت کد را بهبود بخشند.
کاربردهای Linter
1. شناسایی خطاهای سینتکسی:
لینتر میتوانند خطاهای سینتکسی را قبل از اجرای کد شناسایی کنند.
2. بهبود خوانایی کد:
با پیشنهادهایی برای رعایت استانداردهای کدنویسی می دهد، خوانایی کد را افزایش میدهند.
3. کاهش باگها:
با شناسایی مسائل بالقوه، به کاهش تعداد باگها کمک میکنند.
4. یکنواختی کد:
با اطمینان از رعایت استانداردهای یکسان در سراسر پروژه، یکنواختی کد را حفظ میکنند.
معرفی Pylint
پای لینت یک ابزار Linter برای زبان Python است که به تحلیل کد Python میپردازد تا مشکلات مختلفی مانند خطاهای سینتکسی عدم رعایت استانداردهای PEP 8 و مسائل منطقی را شناسایی کند.
ویژگیهای Pylint
- شناسایی خطاهای نحوی و منطقی:
Pylint میتواند خطاهای نحوی و منطقی را در کد شناسایی کند.
- پیشنهاد برای بهبود کد:
با ارائه پیشنهادهایی برای بهبود کد، توسعهدهندگان را در نوشتن کدهای تمیزتر و بهینهتر یاری میدهد.
- پشتیبانی از استانداردهای PEP 8:
با بررسی کد نسبت به استانداردهای PEP 8، به رعایت بهترین شیوههای کدنویسی کمک میکند.
- گزارشدهی جامع:
گزارشهای کاملی از مشکلات موجود در کد ارائه میدهد که شامل امتیازدهی به کیفیت کد نیز میباشد.
مثال نحوه استفاده از pylint:
بعد از نصب کردن با دستور
تمامی کد های پروژه را بررسی می کند.
خیلی مواقع نیاز است که لینتر ها و تنظیماتشان را تغییر بدهیم. برای اینکار دستور زیر را میزنیم تا فایل کانفیگ لینتر ساخته شود:
در فایل .pylintrc می توانید بر حسب نیاز خودتان برخی از لینتر هارا غیر فعال کنید یا تنظیماتشان را تغییر دهید.
نحوه استفاده کاربردی از لینتر:
میتوانید در github workflow از لینتر استفاده کنید و اگر مشکلی شناسایی شد اکشن با خطا مواجه شود. همچنین می توانید از ابزار pre commit استفاده کنید و لینتر را تعریف کنید تا هر زمانی که کامیت جدیدی زده میشود بررسی کند اگر خطایی وجود دارد جلوی کامیت را بگیرد.
#linter #pylint #python
@Syntax_fa
لینتر ابزاری است که برای تحلیل کد استفاده میشود تا مشکلات احتمالی در کد را شناسایی کند. این ابزارها به توسعهدهندگان کمک میکنند تا با شناسایی خطاهای سینتکس، استانداردهای کدنویسی و مسائلی مانند memory leak و ... را شناسایی کنند و کیفیت کد را بهبود بخشند.
کاربردهای Linter
1. شناسایی خطاهای سینتکسی:
لینتر میتوانند خطاهای سینتکسی را قبل از اجرای کد شناسایی کنند.
2. بهبود خوانایی کد:
با پیشنهادهایی برای رعایت استانداردهای کدنویسی می دهد، خوانایی کد را افزایش میدهند.
3. کاهش باگها:
با شناسایی مسائل بالقوه، به کاهش تعداد باگها کمک میکنند.
4. یکنواختی کد:
با اطمینان از رعایت استانداردهای یکسان در سراسر پروژه، یکنواختی کد را حفظ میکنند.
معرفی Pylint
پای لینت یک ابزار Linter برای زبان Python است که به تحلیل کد Python میپردازد تا مشکلات مختلفی مانند خطاهای سینتکسی عدم رعایت استانداردهای PEP 8 و مسائل منطقی را شناسایی کند.
ویژگیهای Pylint
- شناسایی خطاهای نحوی و منطقی:
Pylint میتواند خطاهای نحوی و منطقی را در کد شناسایی کند.
- پیشنهاد برای بهبود کد:
با ارائه پیشنهادهایی برای بهبود کد، توسعهدهندگان را در نوشتن کدهای تمیزتر و بهینهتر یاری میدهد.
- پشتیبانی از استانداردهای PEP 8:
با بررسی کد نسبت به استانداردهای PEP 8، به رعایت بهترین شیوههای کدنویسی کمک میکند.
- گزارشدهی جامع:
گزارشهای کاملی از مشکلات موجود در کد ارائه میدهد که شامل امتیازدهی به کیفیت کد نیز میباشد.
مثال نحوه استفاده از pylint:
pip install pylint
بعد از نصب کردن با دستور
pylint .
تمامی کد های پروژه را بررسی می کند.
خیلی مواقع نیاز است که لینتر ها و تنظیماتشان را تغییر بدهیم. برای اینکار دستور زیر را میزنیم تا فایل کانفیگ لینتر ساخته شود:
pylint --generate-rcfile > .pylintrc
در فایل .pylintrc می توانید بر حسب نیاز خودتان برخی از لینتر هارا غیر فعال کنید یا تنظیماتشان را تغییر دهید.
نحوه استفاده کاربردی از لینتر:
میتوانید در github workflow از لینتر استفاده کنید و اگر مشکلی شناسایی شد اکشن با خطا مواجه شود. همچنین می توانید از ابزار pre commit استفاده کنید و لینتر را تعریف کنید تا هر زمانی که کامیت جدیدی زده میشود بررسی کند اگر خطایی وجود دارد جلوی کامیت را بگیرد.
#linter #pylint #python
@Syntax_fa
1🔥6👍4
توی پایتون بجای isinstance از singledispatch استفاده کن!
۱. ابتدا دو کلاس با استفاده از
اینها دو نوع ایونت هستند: یکی برای زمانی که کاربر مشترک میشود و دیگری برای زمانی که اشتراکش را لغو میکند.
۲. روش اول با استفاده از
در این روش، برای هر نوع رویداد یک شرط
۳. روش دوم با استفاده از
در این روش، برای هر نوع رویداد یک تابع جداگانه تعریف میشود که فقط برای آن نوع خاص اجرا میشود.
مزایای استفاده از
۱. کد تمیزتر: به جای زنجیرهای از `if/elif`، هر منطق در یک تابع جداگانه قرار میگیرد.
۲. قابلیت توسعه بهتر: اضافه کردن نوع جدید فقط نیاز به اضافه کردن یک تابع جدید دارد، نه تغییر کد موجود.
۳. جداسازی مسئولیتها: هر تابع فقط مسئول پردازش یک نوع خاص است.
۴. کاهش پیچیدگی: به جای یک تابع بزرگ با شرطهای متعدد، چندین تابع کوچک و ساده داریم.
نحوه کار:
-
یک تابع پایه تعریف میکند
-
توابع مختلف را برای انواع مختلف ورودی ثبت میکند
- در زمان اجرا، بر اساس نوع ورودی، تابع مناسب فراخوانی میشود
کاربرد این الگو در مواردی مثل:
- پردازش انواع مختلف پیامها یا رویدادها
- تبدیل دادهها بین فرمتهای مختلف
- اعمال عملیاتهای متفاوت روی انواع مختلف داده
- پیادهسازی الگوی Observer یا Event Handler
نمونه استفاده نهایی:
این کد به طور خودکار تابع مناسب را برای هر نوع رویداد فراخوانی میکند.
#python #singledispatch
@Syntax_fa
۱. ابتدا دو کلاس با استفاده از
@dataclass تعریف میکنیم:@dataclass
class UserCanceledSubscription:
username: str
@dataclass
class UserSubscribed:
username: str
اینها دو نوع ایونت هستند: یکی برای زمانی که کاربر مشترک میشود و دیگری برای زمانی که اشتراکش را لغو میکند.
۲. روش اول با استفاده از
isinstance:def process(event):
if isinstance(event, UserSubscribed):
print(f"Enable access to user {event.username}")
elif isinstance(event, UserCanceledSubscription):
print(f"Disable access to user {event.username}")
در این روش، برای هر نوع رویداد یک شرط
if نوشته شده که نوع رویداد را چک میکند.۳. روش دوم با استفاده از
singledispatch:@singledispatch
def process(event):
pass
@process.register(UserCanceledSubscription)
def _(event):
print(f"Disable access to user {event.username}")
@process.register(UserSubscribed)
def _(event):
print(f"Enable access to user {event.username}")
در این روش، برای هر نوع رویداد یک تابع جداگانه تعریف میشود که فقط برای آن نوع خاص اجرا میشود.
مزایای استفاده از
singledispatch:۱. کد تمیزتر: به جای زنجیرهای از `if/elif`، هر منطق در یک تابع جداگانه قرار میگیرد.
۲. قابلیت توسعه بهتر: اضافه کردن نوع جدید فقط نیاز به اضافه کردن یک تابع جدید دارد، نه تغییر کد موجود.
۳. جداسازی مسئولیتها: هر تابع فقط مسئول پردازش یک نوع خاص است.
۴. کاهش پیچیدگی: به جای یک تابع بزرگ با شرطهای متعدد، چندین تابع کوچک و ساده داریم.
نحوه کار:
-
@singledispatch یک تابع پایه تعریف میکند
-
@process.register() توابع مختلف را برای انواع مختلف ورودی ثبت میکند
- در زمان اجرا، بر اساس نوع ورودی، تابع مناسب فراخوانی میشود
کاربرد این الگو در مواردی مثل:
- پردازش انواع مختلف پیامها یا رویدادها
- تبدیل دادهها بین فرمتهای مختلف
- اعمال عملیاتهای متفاوت روی انواع مختلف داده
- پیادهسازی الگوی Observer یا Event Handler
نمونه استفاده نهایی:
events = [
UserSubscribed(username="johndoe"),
UserCanceledSubscription(username="johndoe"),
]
for event in events:
process(event)
این کد به طور خودکار تابع مناسب را برای هر نوع رویداد فراخوانی میکند.
#python #singledispatch
@Syntax_fa
👍17❤🔥2🔥1😁1
فایل آپلود شده رو فقط با پسوندش چک میکنی؟ بیخیال!
تاحالا شده کاربر فایلی رو آپلود کنه و شما فقط پسوندش ( jpg یا pdf) رو چک کنید و با خوشحالی بگید کار تمومه؟ اگه اینطوره، باید بگم که یه جای کار حسابی میلنگه!
کاربر به راحتی میتونه یک فایل مخرب (مثلاً یه اسکریپت) رو به virus.png تغییر نام بده و سیستم شما رو دور بزنه.
راه حل چیه؟ کتابخونه python-magic
این پکیج یک رابط (Wrapper) برای کتابخونه قدرتمند libmagic در زبان C هست. کار اصلیش اینه که بیخیال اسم و پسوند فایل بشه و بره سراغ اصل مطلب محتوای خود فایل.
مجیک چند بایت اول یک فایل (که بهش هدر یا Magic Numbers میگن) رو میخونه و از روی اون امضای دیجیتالی، نوع واقعی فایل رو تشخیص میده.
مثال:
#libmagic #python_magic
@Syntax_fa
تاحالا شده کاربر فایلی رو آپلود کنه و شما فقط پسوندش ( jpg یا pdf) رو چک کنید و با خوشحالی بگید کار تمومه؟ اگه اینطوره، باید بگم که یه جای کار حسابی میلنگه!
کاربر به راحتی میتونه یک فایل مخرب (مثلاً یه اسکریپت) رو به virus.png تغییر نام بده و سیستم شما رو دور بزنه.
راه حل چیه؟ کتابخونه python-magic
این پکیج یک رابط (Wrapper) برای کتابخونه قدرتمند libmagic در زبان C هست. کار اصلیش اینه که بیخیال اسم و پسوند فایل بشه و بره سراغ اصل مطلب محتوای خود فایل.
مجیک چند بایت اول یک فایل (که بهش هدر یا Magic Numbers میگن) رو میخونه و از روی اون امضای دیجیتالی، نوع واقعی فایل رو تشخیص میده.
مثال:
import magic
from django.core.files.uploadedfile import InMemoryUploadedFile
def get_mime_type_from_content(file: InMemoryUploadedFile) -> str:
"""Reads the initial bytes of a file to determine its actual MIME type."""
try:
initial_bytes = file.read(2048)
file.seek(0)
return magic.from_buffer(initial_bytes, mime=True)
except Exception as err:
raise Exception(f"Failed to detect MIME type: {err}")
def check_file_is_image(file: InMemoryUploadedFile) -> bool:
"""Check if the uploaded file is an image based on its MIME type."""
try:
mime_type = get_mime_type_from_content(file)
return mime_type.startswith("image/")
except Exception as err:
print(f"[ERROR] check_file_is_image: {err}")
return False
#libmagic #python_magic
@Syntax_fa
❤13👍6