Ninja Learn | نینجا لرن
خب خب خب دکوریتورها (Decorators) در پایتون: تغییر رفتار توابع و کلاسها 🐍 سلام دوستان امروز میخوایم در مورد یکی از ویژگیهای خیلی قوی و در عین حال جذاب پایتون صحبت کنیم: دکوریتورها. این قابلیت به شما اجازه میده تا بدون دست زدن به کد اصلی توابع یا کلاسها،…
میریم اینو کامل تر کنیم و به جزعیات بپردازیم :)
👍9
بعضی دوستان پیشنهاد دادن که کانال ادمین داشته باشه برای تولید محتوای بیشتر.
دیدم ایده بدی نیست.
هرکسی که دوست داره تو کانال تولید محتوا بکنه، درمورد موضوع:
یه پست بنویسه بفرسته به ایدی
@mohammad_strout
بررسی کنم (ساختار و کیفیتش مثل پستای خود کانال باشه)، بین کسایی که فرستادن یه نفر که بهتر بوده رو انتخاب میکنم ادمین کانال بشه و تو پستا کمک کنه.
➖➖➖➖➖➖➖➖➖
دیدم ایده بدی نیست.
هرکسی که دوست داره تو کانال تولید محتوا بکنه، درمورد موضوع:
ساختمان داده ها
یه پست بنویسه بفرسته به ایدی
@mohammad_strout
بررسی کنم (ساختار و کیفیتش مثل پستای خود کانال باشه)، بین کسایی که فرستادن یه نفر که بهتر بوده رو انتخاب میکنم ادمین کانال بشه و تو پستا کمک کنه.
#⃣ #notif
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
👌8👍2
خب خب خب پشت صحنه دکوریتورها در پایتون: چه اتفاقی پشت پرده میافته؟ 🚀
تو پست قبلی یه نگاه کلی به دکوریتورها داشتیم و دیدیم چقدر میتونن کاربردی باشن. ولی بیاین یه کم عمیقتر بشیم و ببینیم وقتی یه دکوریتور روی تابع یا کلاس اعمال میشه، دقیقاً چه اتفاقی پشت صحنه رخ میده؟ حتی قبل از اینکه کد اجرا بشه.
1⃣ پایتون چطوری کد رو اجرا میکنه؟ 📜
قبل از اینکه بریم سراغ دکوریتورها، یه نکته مهم:
پایتون یه زبان مفسریه، یعنی خطبهخط کد رو اجرا میکنه. ولی قبل از اجرا، اول کد رو به بایتکد تبدیل میکنه و بعد اون رو میفرسته برای ماشین مجازی پایتون (PVM).
تو این فرآیند، هر تابع و کلاس یه آبجکت جداگانه توی حافظه میشه و همینجاست که دکوریتورها وارد عمل میشن 🚀
2⃣ دکوریتورها دقیقاً چیکار میکنن؟ 🔧
1⃣ وقتی @ میذاریم، واقعاً چی میشه؟
وقتی یه تابع رو با @my_decorator دکوریت میکنیم، پایتون پشت صحنه این کارو انجام میده:
میشه این:
یعنی تابع اصلی ساخته میشه، بعد به دکوریتور داده میشه و خروجی دکوریتور جایگزین تابع اصلی میشه. این اتفاق در لحظه تعریف تابع رخ میده، نه وقتی تابع اجرا میشه
2⃣ ترتیب اجرا چطوریه؟
وقتی دکوریتور روی تابع اعمال میشه:
پس، از این به بعد هر وقت تابع رو صدا بزنید، در واقع دارید خروجی دکوریتور رو اجرا میکنید، نه تابع اصلی رو
3⃣ چه بلایی سر تابع میاد؟ 🔍
1⃣ تابع اصلی تبدیل میشه به...
هر تابع تو پایتون یه آبجکته، پس دکوریتورها میتونن روش تغییرات زیادی بدن:
قبل از اجرا یه کار انجام بدن (مثلاً لاگ بگیرن).
تابع اصلی رو اجرا کنن.
بعد از اجرا هم یه کار دیگه انجام بدن (مثلاً خروجی رو دستکاری کنن).
یا حتی یه چیز کاملاً جدید برگردونن
در نتیجه، اسم تابع دیگه به اون چیزی که اول تعریف کردید اشاره نمیکنه، بلکه به خروجی دکوریتور اشاره داره.
2⃣ مشکل متادیتا و راهحل functools.wraps
یه مشکل اینه که دکوریتور باعث میشه اطلاعات تابع (مثل نام، توضیحات و...) از بین بره. برای حل این مشکل، باید از functools.wraps استفاده کنیم:
اینطوری، متادیتای تابع اصلی حفظ میشه وdoc __doc__ دسترسی داشت. 😎
3⃣ دکوریتورهای پشت سر هم (Chaining Decorators)
اگه چندتا دکوریتور رو روی یه تابع بذاریم، ترتیبش مهمه. به این مثال دقت کن:
اول decorator_b اجرا میشه و خروجیش میره تو decorator_a. پس ترتیب اجرا به این شکله:
پس، دکوریتوری که پایینتر نوشته شده، زودتر اجرا میشه 🔄
4⃣ پشت صحنه در زمان کامپایل و اجرا 🕒
1⃣ دکوریتور کی اجرا میشه؟
دکوریتورها همون موقعی که تابع یا کلاس تعریف میشه اجرا میشن، نه وقتی که تابع رو صدا میزنید. پس این کد:
در لحظهای که پایتون به این خط کد میرسه، my_decorator(my_func) اجرا میشه و خروجیش جایگزین my_func میشه.
2⃣ ذخیره تابع در فضای نام (Namespace Binding)
بعد از این فرآیند، اسم تابع به تابع دکوریتشده اشاره میکنه. پس اگه تابع اصلی رو نگه نداشته باشید، دیگه بهش دسترسی ندارید
3⃣ تأثیر روی بهینهسازی
چون دکوریتورها میتونن کد تابع رو تغییر بدن، ممکنه باعث بشن که بهینهسازیهایی که پایتون انجام میده، دیگه درست کار نکنه. برای مثال، اگه دکوریتور یه حلقه اضافه کنه یا اجرای تابع رو تغییر بده، بایتکد نهایی کاملاً متفاوت میشه.
5⃣ نکات مهم که باید رعایت کنید 💡
✅ از functools.wraps استفاده کنید
اگه دکوریتورتون متادیتای تابع رو تغییر میده، این کار باعث میشه اطلاعات تابع اصلی حفظ بشه.
✅ ترتیب دکوریتورها مهمه
اگه چند دکوریتور دارید، حتماً ترتیب اجرا رو بررسی کنید که به مشکل نخورید.
✅ موقع اشکالزدایی حواستون باشه
چون دکوریتورها موقع تعریف اجرا میشن، اگه کدتون مشکل داشته باشه، ممکنه سختتر اشکالزدایی بشه. پس بهتره با print یا لاگ گرفتن، مراحل اجرا رو چک کنید.
➖➖➖➖➖➖➖➖➖
تو پست قبلی یه نگاه کلی به دکوریتورها داشتیم و دیدیم چقدر میتونن کاربردی باشن. ولی بیاین یه کم عمیقتر بشیم و ببینیم وقتی یه دکوریتور روی تابع یا کلاس اعمال میشه، دقیقاً چه اتفاقی پشت صحنه رخ میده؟ حتی قبل از اینکه کد اجرا بشه.
1⃣ پایتون چطوری کد رو اجرا میکنه؟ 📜
قبل از اینکه بریم سراغ دکوریتورها، یه نکته مهم:
پایتون یه زبان مفسریه، یعنی خطبهخط کد رو اجرا میکنه. ولی قبل از اجرا، اول کد رو به بایتکد تبدیل میکنه و بعد اون رو میفرسته برای ماشین مجازی پایتون (PVM).
تو این فرآیند، هر تابع و کلاس یه آبجکت جداگانه توی حافظه میشه و همینجاست که دکوریتورها وارد عمل میشن 🚀
2⃣ دکوریتورها دقیقاً چیکار میکنن؟ 🔧
1⃣ وقتی @ میذاریم، واقعاً چی میشه؟
وقتی یه تابع رو با @my_decorator دکوریت میکنیم، پایتون پشت صحنه این کارو انجام میده:
@my_decorator
def func(...):
...
میشه این:
def func(...):
...
func = my_decorator(func)
یعنی تابع اصلی ساخته میشه، بعد به دکوریتور داده میشه و خروجی دکوریتور جایگزین تابع اصلی میشه. این اتفاق در لحظه تعریف تابع رخ میده، نه وقتی تابع اجرا میشه
2⃣ ترتیب اجرا چطوریه؟
وقتی دکوریتور روی تابع اعمال میشه:
تابع اصلی به عنوان یه آبجکت ساخته میشه.
دکوریتور اجرا میشه و تابع اصلی رو میگیره.
خروجی دکوریتور جایگزین تابع اصلی میشه.
پس، از این به بعد هر وقت تابع رو صدا بزنید، در واقع دارید خروجی دکوریتور رو اجرا میکنید، نه تابع اصلی رو
3⃣ چه بلایی سر تابع میاد؟ 🔍
1⃣ تابع اصلی تبدیل میشه به...
هر تابع تو پایتون یه آبجکته، پس دکوریتورها میتونن روش تغییرات زیادی بدن:
قبل از اجرا یه کار انجام بدن (مثلاً لاگ بگیرن).
تابع اصلی رو اجرا کنن.
بعد از اجرا هم یه کار دیگه انجام بدن (مثلاً خروجی رو دستکاری کنن).
یا حتی یه چیز کاملاً جدید برگردونن
در نتیجه، اسم تابع دیگه به اون چیزی که اول تعریف کردید اشاره نمیکنه، بلکه به خروجی دکوریتور اشاره داره.
2⃣ مشکل متادیتا و راهحل functools.wraps
یه مشکل اینه که دکوریتور باعث میشه اطلاعات تابع (مثل نام، توضیحات و...) از بین بره. برای حل این مشکل، باید از functools.wraps استفاده کنیم:
import functools
def log_calls(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"قبل از اجرای {func.__name__}")
result = func(*args, **kwargs)
print(f"بعد از اجرای {func.__name__}")
return result
return wrapper
اینطوری، متادیتای تابع اصلی حفظ میشه وdoc __doc__ دسترسی داشت. 😎
3⃣ دکوریتورهای پشت سر هم (Chaining Decorators)
اگه چندتا دکوریتور رو روی یه تابع بذاریم، ترتیبش مهمه. به این مثال دقت کن:
@decorator_a
@decorator_b
def func():
pass
اول decorator_b اجرا میشه و خروجیش میره تو decorator_a. پس ترتیب اجرا به این شکله:
func = decorator_b(func)
func = decorator_a(func)
پس، دکوریتوری که پایینتر نوشته شده، زودتر اجرا میشه 🔄
4⃣ پشت صحنه در زمان کامپایل و اجرا 🕒
1⃣ دکوریتور کی اجرا میشه؟
دکوریتورها همون موقعی که تابع یا کلاس تعریف میشه اجرا میشن، نه وقتی که تابع رو صدا میزنید. پس این کد:
@my_decorator
def my_func():
pass
در لحظهای که پایتون به این خط کد میرسه، my_decorator(my_func) اجرا میشه و خروجیش جایگزین my_func میشه.
2⃣ ذخیره تابع در فضای نام (Namespace Binding)
بعد از این فرآیند، اسم تابع به تابع دکوریتشده اشاره میکنه. پس اگه تابع اصلی رو نگه نداشته باشید، دیگه بهش دسترسی ندارید
3⃣ تأثیر روی بهینهسازی
چون دکوریتورها میتونن کد تابع رو تغییر بدن، ممکنه باعث بشن که بهینهسازیهایی که پایتون انجام میده، دیگه درست کار نکنه. برای مثال، اگه دکوریتور یه حلقه اضافه کنه یا اجرای تابع رو تغییر بده، بایتکد نهایی کاملاً متفاوت میشه.
5⃣ نکات مهم که باید رعایت کنید 💡
✅ از functools.wraps استفاده کنید
اگه دکوریتورتون متادیتای تابع رو تغییر میده، این کار باعث میشه اطلاعات تابع اصلی حفظ بشه.
✅ ترتیب دکوریتورها مهمه
اگه چند دکوریتور دارید، حتماً ترتیب اجرا رو بررسی کنید که به مشکل نخورید.
✅ موقع اشکالزدایی حواستون باشه
چون دکوریتورها موقع تعریف اجرا میشن، اگه کدتون مشکل داشته باشه، ممکنه سختتر اشکالزدایی بشه. پس بهتره با print یا لاگ گرفتن، مراحل اجرا رو چک کنید.
#⃣ #python #programming
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
❤14👍6🔥3👎1👏1👌1
Ninja Learn | نینجا لرن
بعضی دوستان پیشنهاد دادن که کانال ادمین داشته باشه برای تولید محتوای بیشتر. دیدم ایده بدی نیست. هرکسی که دوست داره تو کانال تولید محتوا بکنه، درمورد موضوع: ساختمان داده ها یه پست بنویسه بفرسته به ایدی @mohammad_strout بررسی کنم (ساختار و کیفیتش مثل پستای…
خب یه دوست گرامی انتخاب شد
با تشکر از همگی
با تشکر از همگی
❤5
خب سلام دوستان رسیدیم به ساختمان داده ها؛ ساختار هایی که برای مدیریت داده ها خیلی کاربردی ان💡
همونطور که میدونید، داخل برنامه هامون نیاز داریم داده ها را به صورتی ذخیره و مدیریت کنیم که پردازش سریعتر و مصرف حافظه بهینه تر بشه.
🧱 چند نوع ساختمان داده داریم؟
به طور کلی به دو دسته تقسیم میشه:
1️⃣ ساختارهای اولیه (Primitive Data Types)
🔸پایه ای ترین نوع ذخیره داده ها مثل int ، float ، char و boolean
2️⃣ ساختارهای غیراولیه (Non-Primitive)
🔸برای مدیریت مجموعه های بزرگ و پیچیده داده ها استفاده میشن و عمدتا به دو گروه تقسیم میشن:
1️⃣ ساختارهای خطی (Linear):
🔸داده ها به صورت ترتیبی چیده میشن مثل: آرایه (Array)، پشته (Stack)، صف (Queue)، لیست پیوندی (Linked List).
2️⃣ ساختارهای غیرخطی (Non-Linear):
🔸داده ها به صورت سلسله مراتبی یا شبکه ای ذخیره میشن و از نمونه هاشون میشه به درخت (Tree)، گراف (Graph)، جدول هش (Hash Table) اشاره کرد
در پستهای آینده، هر یک از این ساختارها رو
ببیشتر بررسی میکنیم 🚀
اگر سوالی یا پیشنهادی دارید خوشحال میشم کامنت بگذارید! 💬
➖➖➖➖➖➖➖➖➖
همونطور که میدونید، داخل برنامه هامون نیاز داریم داده ها را به صورتی ذخیره و مدیریت کنیم که پردازش سریعتر و مصرف حافظه بهینه تر بشه.
به طور مثال میخوایم کاربران یک اپلیکیشن را مدیریت کنیم یا مسیرهای کوتاه تر بین دو شهر را در نقشه پیدا کنیم!🔍 ساختمان داده چه کاربردی داره؟
🔸اینجا ساختار مناسب خیلی میتونه مفید باشه! ✨
🔸کاهش زمان عملیات ها (مثل جستجو، افزودن یا حذف داده)
🔸بهینه سازی مصرف حافظه (ذخیره هوشمندانه داده ها بدون اتلاف فضا)
🧱 چند نوع ساختمان داده داریم؟
به طور کلی به دو دسته تقسیم میشه:
1️⃣ ساختارهای اولیه (Primitive Data Types)
🔸پایه ای ترین نوع ذخیره داده ها مثل int ، float ، char و boolean
این تایپ ها تشکیل دهنده پایه ساختمان داده های پیچیده تر هستن!
2️⃣ ساختارهای غیراولیه (Non-Primitive)
🔸برای مدیریت مجموعه های بزرگ و پیچیده داده ها استفاده میشن و عمدتا به دو گروه تقسیم میشن:
1️⃣ ساختارهای خطی (Linear):
🔸داده ها به صورت ترتیبی چیده میشن مثل: آرایه (Array)، پشته (Stack)، صف (Queue)، لیست پیوندی (Linked List).
و از کاربرد هاشون میشه به مدیریت صف پیامها، ذخیره اطلاعات کاربران به ترتیب ثبتنام اشاره کرد.
2️⃣ ساختارهای غیرخطی (Non-Linear):
🔸داده ها به صورت سلسله مراتبی یا شبکه ای ذخیره میشن و از نمونه هاشون میشه به درخت (Tree)، گراف (Graph)، جدول هش (Hash Table) اشاره کرد
و نمونه کاربرد هاشون هم پیدا کردن کوتاه ترین مسیر در نقشه (با گراف)، جستجوی سریع در دیکشنری (با درخت دودویی) هست.
در پستهای آینده، هر یک از این ساختارها رو
ببیشتر بررسی میکنیم 🚀
اگر سوالی یا پیشنهادی دارید خوشحال میشم کامنت بگذارید! 💬
#️⃣ #data_structure #programming
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
👍10❤6
خب خب خب جلوگیری از Race Condition در جنگو با select_for_update 🔒🚀
توی این پست در مورد Race Condition صحبت کردیم و گفتیم چطور ممکنه چندتا درخواست همزمان بیان و دیتا رو خراب کنن. حالا بریم ببینیم جنگو چه ترفندهایی برای کنترل این مشکل داره و چطور میتونیم از select_for_update استفاده کنیم.
مشکل چیه؟ 🤔
فرض کن یه سیستم بانکی داری و کاربرا دارن پول جابهجا میکنن. حالا دو نفر همزمان میخوان از حسابشون پول بردارن و موجودی حساب فقط 100 تومنه. اگه این درخواستها بدون قفل کردن دیتا پردازش بشن، ممکنه هر دو برداشت موفق بشن و سیستم بدهکار بشه 😬
چطوری select_for_update مشکل رو حل میکنه؟ 🔐
وقتی از select_for_update استفاده میکنی، رکورد دیتابیس قفل میشه تا هیچ درخواست دیگهای نتونه همزمان تغییرش بده. این یعنی هر درخواستی که بعد از اولین درخواست بیاد، باید منتظر بمونه تا قفل آزاد بشه و بعد پردازش بشه.
مثال 1: جلوگیری از برداشت همزمان از حساب بانکی 🏦
✅ این کد مطمئن میشه که وقتی یه درخواست داره موجودی رو چک میکنه و کم میکنه، هیچ درخواست دیگهای همزمان وارد عمل نشه.
مثال 2: انتقال وجه بین دو حساب 💳
حالا یه چالش سختتر انتقال پول از یه حساب به حساب دیگه. باید هر دو حساب همزمان قفل بشن تا مشکلات همزمانی پیش نیاد.
✅ اینجا هر دو حساب رو قفل میکنیم تا حتی اگه دو درخواست انتقال پول به صورت همزمان بیاد، هیچکدوم نتونن وسط کار رو همدیگه تأثیر بذارن.
چندتا نکته 🚀
🔹 انتخاب نوع قفل (select_for_update(nowait=True))
اگه بخوای درخواستهای معطل رو سریع رد کنی، میتونی nowait=True بذاری که اگه رکورد قفل بود، درخواست جدید منتظر نمونه و مستقیم خطا بده.
☝️ این باعث میشه که اگه رکورد قفل باشه، جنگو بلافاصله یه DatabaseError بده و منتظر نمونه.
🔹 قفل کردن رکوردها بدون مسدود کردن خواندن (select_for_update(skip_locked=True))
اگه درخواستهای زیادی داری و نمیخوای که یک درخواست کل سیستم رو بلاک کنه، میتونی از skip_locked=True استفاده کنی که درخواستهای دیگه بتونن رکوردهای آزاد رو پردازش کنن.
☝️ این کار باعث میشه که اگه یه رکورد قفل بود، درخواست بیخیال اون رکورد بشه و فقط رکوردهایی که قفل نیستن رو انتخاب کنه.
🔹 مدیریت تایماوت قفل (set statement_timeout)
اگه نمیخوای که درخواستها مدت زیادی بلاک بشن، توی PostgreSQL میتونی یه تایماوت برای قفل تعیین کنی:
☝️ این یعنی اگه یه درخواست بیشتر از ۵ ثانیه قفل بمونه، بهش خطا داده میشه و میره بیرون.
جمعبندی ✍
select_for_update یکی از قویترین ابزارها برای جلوگیری از Race Condition توی جنگوئه. مهمترین نکاتش اینان:
✅ قفل کردن رکوردهای دیتابیس موقع آپدیت برای جلوگیری از دستکاری همزمان
✅ استفاده از nowait=True برای جلوگیری از انتظار بیش از حد
✅ استفاده از skip_locked=True برای رد کردن رکوردهای قفلشده و ادامه پردازش.
➖➖➖➖➖➖➖➖➖
توی این پست در مورد Race Condition صحبت کردیم و گفتیم چطور ممکنه چندتا درخواست همزمان بیان و دیتا رو خراب کنن. حالا بریم ببینیم جنگو چه ترفندهایی برای کنترل این مشکل داره و چطور میتونیم از select_for_update استفاده کنیم.
مشکل چیه؟ 🤔
فرض کن یه سیستم بانکی داری و کاربرا دارن پول جابهجا میکنن. حالا دو نفر همزمان میخوان از حسابشون پول بردارن و موجودی حساب فقط 100 تومنه. اگه این درخواستها بدون قفل کردن دیتا پردازش بشن، ممکنه هر دو برداشت موفق بشن و سیستم بدهکار بشه 😬
اینجا همون جاییه که select_for_update میاد وسط و دیتا رو از فاجعه نجات میده.
چطوری select_for_update مشکل رو حل میکنه؟ 🔐
وقتی از select_for_update استفاده میکنی، رکورد دیتابیس قفل میشه تا هیچ درخواست دیگهای نتونه همزمان تغییرش بده. این یعنی هر درخواستی که بعد از اولین درخواست بیاد، باید منتظر بمونه تا قفل آزاد بشه و بعد پردازش بشه.
مثال 1: جلوگیری از برداشت همزمان از حساب بانکی 🏦
from django.db import transaction
from myapp.models import Account
def withdraw_money(account_id, amount):
with transaction.atomic(): # شروع تراکنش
account = Account.objects.select_for_update().get(pk=account_id) # قفل کردن رکورد
if account.balance >= amount:
account.balance -= amount
account.save()
print("برداشت موفقیتآمیز بود!")
else:
print("موجودی کافی نیست!") # جلوگیری از برداشت بیش از حد
✅ این کد مطمئن میشه که وقتی یه درخواست داره موجودی رو چک میکنه و کم میکنه، هیچ درخواست دیگهای همزمان وارد عمل نشه.
مثال 2: انتقال وجه بین دو حساب 💳
حالا یه چالش سختتر انتقال پول از یه حساب به حساب دیگه. باید هر دو حساب همزمان قفل بشن تا مشکلات همزمانی پیش نیاد.
from django.db import transaction
from myapp.models import Account
def transfer_money(from_id, to_id, amount):
with transaction.atomic():
accounts = Account.objects.select_for_update().filter(pk__in=[from_id, to_id]).order_by("id")
sender = accounts[0]
receiver = accounts[1]
if sender.balance >= amount:
sender.balance -= amount
receiver.balance += amount
sender.save()
receiver.save()
print("انتقال وجه موفقیتآمیز بود!")
else:
print("موجودی کافی نیست!") # جلوگیری از انتقال اشتباه
✅ اینجا هر دو حساب رو قفل میکنیم تا حتی اگه دو درخواست انتقال پول به صورت همزمان بیاد، هیچکدوم نتونن وسط کار رو همدیگه تأثیر بذارن.
چندتا نکته 🚀
🔹 انتخاب نوع قفل (select_for_update(nowait=True))
اگه بخوای درخواستهای معطل رو سریع رد کنی، میتونی nowait=True بذاری که اگه رکورد قفل بود، درخواست جدید منتظر نمونه و مستقیم خطا بده.
account = Account.objects.select_for_update(nowait=True).get(pk=1)
☝️ این باعث میشه که اگه رکورد قفل باشه، جنگو بلافاصله یه DatabaseError بده و منتظر نمونه.
🔹 قفل کردن رکوردها بدون مسدود کردن خواندن (select_for_update(skip_locked=True))
اگه درخواستهای زیادی داری و نمیخوای که یک درخواست کل سیستم رو بلاک کنه، میتونی از skip_locked=True استفاده کنی که درخواستهای دیگه بتونن رکوردهای آزاد رو پردازش کنن.
account = Account.objects.select_for_update(skip_locked=True).get(pk=1)
☝️ این کار باعث میشه که اگه یه رکورد قفل بود، درخواست بیخیال اون رکورد بشه و فقط رکوردهایی که قفل نیستن رو انتخاب کنه.
🔹 مدیریت تایماوت قفل (set statement_timeout)
اگه نمیخوای که درخواستها مدت زیادی بلاک بشن، توی PostgreSQL میتونی یه تایماوت برای قفل تعیین کنی:
SET statement_timeout = '5s';
☝️ این یعنی اگه یه درخواست بیشتر از ۵ ثانیه قفل بمونه، بهش خطا داده میشه و میره بیرون.
جمعبندی ✍
select_for_update یکی از قویترین ابزارها برای جلوگیری از Race Condition توی جنگوئه. مهمترین نکاتش اینان:
✅ قفل کردن رکوردهای دیتابیس موقع آپدیت برای جلوگیری از دستکاری همزمان
✅ استفاده از nowait=True برای جلوگیری از انتظار بیش از حد
✅ استفاده از skip_locked=True برای رد کردن رکوردهای قفلشده و ادامه پردازش.
#️⃣ #python #programming #db
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
1👍20🔥4❤2👌1
Ninja Learn | نینجا لرن
خب خب خب جلوگیری از Race Condition در جنگو با select_for_update 🔒🚀 توی این پست در مورد Race Condition صحبت کردیم و گفتیم چطور ممکنه چندتا درخواست همزمان بیان و دیتا رو خراب کنن. حالا بریم ببینیم جنگو چه ترفندهایی برای کنترل این مشکل داره و چطور میتونیم از…
خیلی وقت بود پست جنگو نداشته بودیم 😬
👏10
🎥
داستان فیلم 🎬
پیشنهاد میکنم ببینید :)
➖➖➖➖➖➖➖➖➖
The social network
داستان فیلم 🎬
ـ“The Social Network” داستان تأسیس شبکه اجتماعی فیسبوک توسط مارک زاکربرگ و چالشهایی که در مسیر این راه با آن مواجه شد را روایت میکند. فیلم به نمایش مسائل حقوقی، درگیریها و کشمکشهای شخصی در مسیر ساخت یکی از بزرگترین شبکههای اجتماعی دنیا میپردازد.
پیشنهاد میکنم ببینید :)
#️⃣ #movie
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
❤7👍2🤣2
Ninja Learn | نینجا لرن
🎥 The social network داستان فیلم 🎬 ـ“The Social Network” داستان تأسیس شبکه اجتماعی فیسبوک توسط مارک زاکربرگ و چالشهایی که در مسیر این راه با آن مواجه شد را روایت میکند. فیلم به نمایش مسائل حقوقی، درگیریها و کشمکشهای شخصی در مسیر ساخت یکی از بزرگترین…
یکی از دلایلی که پیشنهادش میکنم اینه که نشون میده مارک زاکر برگ چه ادم دزد و مزخرفیه.
👍15
جنگو کنده، پس نباید استفاده کنیم؟ 🙂↔️
یکی از بحثهای همیشگی توی گروه های جنگو اینه که "جنگو کنده، پس بریم سمت FastAPI یا Go یا ...". این حرفو زیاد شنیدم، خودمم یه زمانی فکر میکردم سرعت، همهچیزه ولی بیاین یه بار منطقی بررسی کنیم، بدون تعصب.
چرا میگن جنگو کنده؟
خب راستشو بخواین، جنگو واقعا کنده (نسبت به فریمورکهای async بیس مثل FastAPI و زبانهای کامپایلری مثل Go که توی I/O bound حرف اولو میزنن). ولی چرا؟
جنگو سینکروسه 🥸
جنگو از اساس برای وباپلیکیشنهای سنتی طراحی شده(طبیعیم هست چون ۲۰ سال پیش ساخته شد اون موقع مفهومی به اسم async به این صورت نبود).
ولی فریمورکهایی مثل FastAPI میتونن همزمان چند درخواست رو مدیریت کنن (به لطف async).
Overhead بالای ORM 🏋️♂️
ORM جنگو سنگینه. هر کوئری که میزنی، کلی پردازش اضافه انجام میده تا کارتو راحت کنه، ولی همین باعث میشه کندتر از ORMهای سبکتر باشه.
Middleware و Request Cycle پیچیدهتره 🌀
جنگو یه سری پردازشهای اضافه برای هر درخواست انجام میده (مانند middleware ها، سیگنالها، template rendering و ...)، که باعث میشه به طور طبیعی کمی کندتر باشه.
پس چرا بازم از جنگو استفاده کنیم؟
حالا که جنگو کنده، یعنی نباید سمتش بریم؟ نه بابا بذار تجربه خودمو بگم.
1⃣ سرعت، همیشه مهمترین فاکتور نیست
اکثر پروژهها، گلوگاه سرعت، فریمورک نیست، بلکه دیتابیس، شبکه، و لاجیکهای بیزینسی هستن. یه اپلیکیشن CRUD ساده که روزی ۱۰۰۰ تا درخواست داره، با FastAPI یا جنگو، تفاوت محسوسی نداره.
2⃣ توسعه سریعتر = زمان و پول بیشتر
جنگو کلی چیز آماده داره. سیستم مدیریت کاربر، فرمها، ORM، ادمین پنل، و کلی ماژول دیگه. این یعنی تو به جای ساختن همهچی از صفر، فقط تمرکزت روی بیزینس لاجیکه. توسعه سریعتر = هزینه کمتر.
3⃣ امنیت، یکپارچگی، و قابلیت اطمینان
جنگو به طور پیشفرض مقاوم در برابر حملات XSS، CSRF، SQL Injection و غیرهست. ولی FastAPI؟ باید خودت امنیت رو درست کنی و Middleware بنویسی، که اگه اشتباه کنی، فاجعه میشه
کی بریم سمت FastAPI یا Go یا هرچیز سریع؟
1⃣ وقتی واقعا به Async نیاز داری
اگه داری یه چتاپ، وبساکت، یا یه سیستم پردازش سنگین با درخواستهای همزمان بالا مینویسی، FastAPI و Go گزینههای بهتری هستن.
2⃣ وقتی هر میلیثانیه مهمه
توی سرویسهای real-time مثل سیستمهای تریدینگ، گیمینگ، یا پردازش داده سنگین، Go و Rust گزینههای بهتری هستن، چون کامپایل میشن و خیلی سریعتر از پایتون اجرا میشن.
پس چی کار کنیم؟
سرعت، همه چیز نیست، بلکه بستگی داره که چه چیزی برات مهمتره و نیاز داری بهش
➖➖➖➖➖➖➖➖➖
یکی از بحثهای همیشگی توی گروه های جنگو اینه که "جنگو کنده، پس بریم سمت FastAPI یا Go یا ...". این حرفو زیاد شنیدم، خودمم یه زمانی فکر میکردم سرعت، همهچیزه ولی بیاین یه بار منطقی بررسی کنیم، بدون تعصب.
چرا میگن جنگو کنده؟
خب راستشو بخواین، جنگو واقعا کنده (نسبت به فریمورکهای async بیس مثل FastAPI و زبانهای کامپایلری مثل Go که توی I/O bound حرف اولو میزنن). ولی چرا؟
جنگو سینکروسه 🥸
جنگو از اساس برای وباپلیکیشنهای سنتی طراحی شده(طبیعیم هست چون ۲۰ سال پیش ساخته شد اون موقع مفهومی به اسم async به این صورت نبود).
ولی فریمورکهایی مثل FastAPI میتونن همزمان چند درخواست رو مدیریت کنن (به لطف async).
Overhead بالای ORM 🏋️♂️
ORM جنگو سنگینه. هر کوئری که میزنی، کلی پردازش اضافه انجام میده تا کارتو راحت کنه، ولی همین باعث میشه کندتر از ORMهای سبکتر باشه.
Middleware و Request Cycle پیچیدهتره 🌀
جنگو یه سری پردازشهای اضافه برای هر درخواست انجام میده (مانند middleware ها، سیگنالها، template rendering و ...)، که باعث میشه به طور طبیعی کمی کندتر باشه.
پس چرا بازم از جنگو استفاده کنیم؟
حالا که جنگو کنده، یعنی نباید سمتش بریم؟ نه بابا بذار تجربه خودمو بگم.
1⃣ سرعت، همیشه مهمترین فاکتور نیست
اکثر پروژهها، گلوگاه سرعت، فریمورک نیست، بلکه دیتابیس، شبکه، و لاجیکهای بیزینسی هستن. یه اپلیکیشن CRUD ساده که روزی ۱۰۰۰ تا درخواست داره، با FastAPI یا جنگو، تفاوت محسوسی نداره.
2⃣ توسعه سریعتر = زمان و پول بیشتر
جنگو کلی چیز آماده داره. سیستم مدیریت کاربر، فرمها، ORM، ادمین پنل، و کلی ماژول دیگه. این یعنی تو به جای ساختن همهچی از صفر، فقط تمرکزت روی بیزینس لاجیکه. توسعه سریعتر = هزینه کمتر.
3⃣ امنیت، یکپارچگی، و قابلیت اطمینان
جنگو به طور پیشفرض مقاوم در برابر حملات XSS، CSRF، SQL Injection و غیرهست. ولی FastAPI؟ باید خودت امنیت رو درست کنی و Middleware بنویسی، که اگه اشتباه کنی، فاجعه میشه
کی بریم سمت FastAPI یا Go یا هرچیز سریع؟
1⃣ وقتی واقعا به Async نیاز داری
اگه داری یه چتاپ، وبساکت، یا یه سیستم پردازش سنگین با درخواستهای همزمان بالا مینویسی، FastAPI و Go گزینههای بهتری هستن.
2⃣ وقتی هر میلیثانیه مهمه
توی سرویسهای real-time مثل سیستمهای تریدینگ، گیمینگ، یا پردازش داده سنگین، Go و Rust گزینههای بهتری هستن، چون کامپایل میشن و خیلی سریعتر از پایتون اجرا میشن.
پس چی کار کنیم؟
اگه سرعت برات مهمه: Go بزن Java بزن یا ...
اگه یه API سبک و سریع لازم داری: FastAPI بزن
اگه میخوای سریع یه اپلیکیشن کامل و امن بالا بیاری: Django بهترین گزینهست
سرعت، همه چیز نیست، بلکه بستگی داره که چه چیزی برات مهمتره و نیاز داری بهش
خوشحال میشم نظرتون رو بشنوم
تو کامنتای همین پست بگید 👇
#️⃣ #programming #django #backend
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
👍32❤4
حواسم هست حمایت نمیکنی 🗿🫵
هنوزم دیر نیست لطفاً ریکشن بزن و شیر کن پستارو
🔪☺️
🌚 (این یک درخواست نبود)
هنوزم دیر نیست لطفاً ریکشن بزن و شیر کن پستارو
🔪☺️
🌚 (این یک درخواست نبود)
👍35🤣6💔2👎1
یکی از اعضای کامیونیتی سایت عالی رو معرفی کرده بود که منم تصمیم گرفتم توی کانالم بهتون معرفی کنم.
وبسایت CodeCrafters (لینک زیر) مجموعهای از پروژههای برنامهنویسی رو ارائه میده که میتونید با توجه به سطح مهارت فعلیتون، پروژههایی با سختیهای مختلف انتخاب کنید. از پروژههایی مثل نوشتن Shell گرفته تا پروژه های پیشرفته مثل نوشتن مسیج بروکرهایی مثل Kafka (اونم با هر زبانی که دوست دارید) ، این سایت گزینههای متنوعی برای ارتقای مهارتهای برنامهنویسیتون داره و واقعا لذت بردم.
حتماً از این لینک استفاده کنید:
اگه از طریق این لینک ثبتنام کنید، یک هفته دسترسی رایگان به تمام تمرینات داده شده دریافت میکنید. ( به منم یه هفته میده 😁)
برای دوستاتونم بفرستید که اوناهم استفاده کنن
➖➖➖➖➖➖➖➖➖
وبسایت CodeCrafters (لینک زیر) مجموعهای از پروژههای برنامهنویسی رو ارائه میده که میتونید با توجه به سطح مهارت فعلیتون، پروژههایی با سختیهای مختلف انتخاب کنید. از پروژههایی مثل نوشتن Shell گرفته تا پروژه های پیشرفته مثل نوشتن مسیج بروکرهایی مثل Kafka (اونم با هر زبانی که دوست دارید) ، این سایت گزینههای متنوعی برای ارتقای مهارتهای برنامهنویسیتون داره و واقعا لذت بردم.
حتماً از این لینک استفاده کنید:
https://app.codecrafters.io/r/smiling-trout-679054
اگه از طریق این لینک ثبتنام کنید، یک هفته دسترسی رایگان به تمام تمرینات داده شده دریافت میکنید. ( به منم یه هفته میده 😁)
برای دوستاتونم بفرستید که اوناهم استفاده کنن
#️⃣ #reference
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
CodeCrafters
The Software Pro's Best Kept Secret.
Real-world proficiency projects designed for experienced engineers. Develop software craftsmanship by recreating popular devtools from scratch.
👍13❤5🔥2
Ninja Learn | نینجا لرن
یکی از اعضای کامیونیتی سایت عالی رو معرفی کرده بود که منم تصمیم گرفتم توی کانالم بهتون معرفی کنم. وبسایت CodeCrafters (لینک زیر) مجموعهای از پروژههای برنامهنویسی رو ارائه میده که میتونید با توجه به سطح مهارت فعلیتون، پروژههایی با سختیهای مختلف انتخاب…
ممنون میشم اگه هم نخواستید استفاده کنید روی این لینک بزنید تا به منم امتیاز بده
👍6❤2
Ninja Learn | نینجا لرن pinned «یکی از اعضای کامیونیتی سایت عالی رو معرفی کرده بود که منم تصمیم گرفتم توی کانالم بهتون معرفی کنم. وبسایت CodeCrafters (لینک زیر) مجموعهای از پروژههای برنامهنویسی رو ارائه میده که میتونید با توجه به سطح مهارت فعلیتون، پروژههایی با سختیهای مختلف انتخاب…»
خب خب خب ورژنبندی اپلیکیشنها چیه؟ 📌
احتمالاً توی پروژهها دیدی که نسخه نرمافزارها یه چیزی مثل 1.2.3 هست. ولی این اعداد چه معنیای دارن؟ آیا یه ورژن 1.2.3 بهتر از 1.2.2ـه؟ بیاید یه بار برای همیشه اینو ببینیم
📌 استاندارد ورژنبندی (Semantic Versioning - SemVer)
ساختار استاندارد ورژنبندی معنایی (Semantic Versioning) معمولاً این شکلیه:
X (Major - تغییرات بزرگ)
وقتی این عدد تغییر کنه، یعنی کلی چیز عوض شده مثلاً سازگاری عقبگرد (backward compatibility) شکسته شده و ممکنه کدهای قدیمی دیگه کار نکنن یا به عبارتی BREAKING CHANGE به وجود اومده.
Y (Minor - قابلیتهای جدید)
اگه این عدد تغییر کنه، یعنی قابلیتای جدید اضافه شده ولی همچنان سازگاری با نسخه قبلی حفظ شده.
Z (Patch - رفع باگها و بهبودها)
فقط باگ فیکس یا بهینهسازیای جزئی انجام شده و هیچ قابلیت جدیدی اضافه نشده.
🔹 مثال عملی از ورژنبندی
فرض کن داریم روی یه اپلیکیشن کار میکنیم:
✅ 1.0.0 → نسخه اولیه منتشر شد.
✅ 1.1.0 → یه قابلیت جدید مثل ورود با گوگل اضافه شد.
✅ 1.1.1 → یه باگ توی صفحه لاگین فیکس شد.
✅ 2.0.0 → ساختار دیتابیس عوض شد و نسخههای قبلی دیگه کار نمیکنن.
🔍 پس کی باید Major، Minor یا Patch رو تغییر بدیم؟
وقتی API رو تغییر دادی و ممکنه کدای قدیمی دیگه کارنکنن؟
Major رو ببر بالا 🚀
یه فیچر جدید اضافه کردی ولی چیزی از قبل به مشکل نمیخوره؟
Minor رو ببر بالا 📈
فقط یه باگ کوچیک فیکس کردی؟
Patch رو ببر بالا 🛠️
🔹 انواع مختلف ورژن بندی؟
گاهی وقتا میبینی که ورژنا این شکلیه:
🔸 1.2.3-alpha → نسخه آزمایشی (قبل از انتشار اصلی)
🔸 1.2.3-beta → نسخه بتا، برای تست کاربرا
🔸 1.2.3-rc1 → نسخه Release Candidate که تقریباً آماده است
جمعبندی ✍
ورژنبندی معنایی باعث میشه بفهمیم یه نسخه چقدر تغییر کرده و آیا آپدیتش برای ما مشکلی ایجاد میکنه یا نه.
➖➖➖➖➖➖➖➖➖
احتمالاً توی پروژهها دیدی که نسخه نرمافزارها یه چیزی مثل 1.2.3 هست. ولی این اعداد چه معنیای دارن؟ آیا یه ورژن 1.2.3 بهتر از 1.2.2ـه؟ بیاید یه بار برای همیشه اینو ببینیم
📌 استاندارد ورژنبندی (Semantic Versioning - SemVer)
ساختار استاندارد ورژنبندی معنایی (Semantic Versioning) معمولاً این شکلیه:
X.Y.Z
X (Major - تغییرات بزرگ)
وقتی این عدد تغییر کنه، یعنی کلی چیز عوض شده مثلاً سازگاری عقبگرد (backward compatibility) شکسته شده و ممکنه کدهای قدیمی دیگه کار نکنن یا به عبارتی BREAKING CHANGE به وجود اومده.
Y (Minor - قابلیتهای جدید)
اگه این عدد تغییر کنه، یعنی قابلیتای جدید اضافه شده ولی همچنان سازگاری با نسخه قبلی حفظ شده.
Z (Patch - رفع باگها و بهبودها)
فقط باگ فیکس یا بهینهسازیای جزئی انجام شده و هیچ قابلیت جدیدی اضافه نشده.
🔹 مثال عملی از ورژنبندی
فرض کن داریم روی یه اپلیکیشن کار میکنیم:
✅ 1.0.0 → نسخه اولیه منتشر شد.
✅ 1.1.0 → یه قابلیت جدید مثل ورود با گوگل اضافه شد.
✅ 1.1.1 → یه باگ توی صفحه لاگین فیکس شد.
✅ 2.0.0 → ساختار دیتابیس عوض شد و نسخههای قبلی دیگه کار نمیکنن.
🔍 پس کی باید Major، Minor یا Patch رو تغییر بدیم؟
وقتی API رو تغییر دادی و ممکنه کدای قدیمی دیگه کارنکنن؟
Major رو ببر بالا 🚀
یه فیچر جدید اضافه کردی ولی چیزی از قبل به مشکل نمیخوره؟
Minor رو ببر بالا 📈
فقط یه باگ کوچیک فیکس کردی؟
Patch رو ببر بالا 🛠️
🔹 انواع مختلف ورژن بندی؟
گاهی وقتا میبینی که ورژنا این شکلیه:
🔸 1.2.3-alpha → نسخه آزمایشی (قبل از انتشار اصلی)
🔸 1.2.3-beta → نسخه بتا، برای تست کاربرا
🔸 1.2.3-rc1 → نسخه Release Candidate که تقریباً آماده است
جمعبندی ✍
ورژنبندی معنایی باعث میشه بفهمیم یه نسخه چقدر تغییر کرده و آیا آپدیتش برای ما مشکلی ایجاد میکنه یا نه.
#️⃣ #programming #backend
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
👌18👍1
Forwarded from Linux Zone | لینوکس زون
🐧کانال لینوکس زون | برای عاشقان لینوکس و دنیای نرم افزار متن باز🗃
🚀 چی قراره یاد بگیریم؟
💡 هر روز یه قدم به حرفهایتر شدن نزدیکتر شو
🎯 | Channel: @LinuxZone
💬 | Group: @LinuxZoneGap
⚡️ بزن بریم دنیای لینوکس رو کشف کنیم 🐧🚀
🚀 چی قراره یاد بگیریم؟
🛠 دستورات، ترفندها و آموزشهای حرفهای لینوکس
⚡️ بهینهسازی و مدیریت سرورهای لینوکسی
📦 معرفی ابزارها و تکنولوژیهای متنباز
🔐 امنیت، شبکه و مفاهیم کلیدی لینوکسی
💎 اشتراک تجربهها و چالشهای واقعی دنیای لینوکس
📢 جدیدترین اخبار دنیای نرم افزار آزاد
💡 هر روز یه قدم به حرفهایتر شدن نزدیکتر شو
🎯 | Channel: @LinuxZone
💬 | Group: @LinuxZoneGap
⚡️ بزن بریم دنیای لینوکس رو کشف کنیم 🐧🚀
❤4