🔆 اگه تو پروژههات با لیستهای حجیم کار میکنی، استفاده از Generator Expression بهجای List Comprehension معجزه میکنه.
🔹 تفاوتش فقط توی پرانتز گذاشتن به جای براکته، ولی مصرف رم رو بهینه میکنه.
مثلاً اگه بنویسی:
🔹 پایتون کل لیست رو یکجا تو حافظه میسازه،
اما اگه بنویسی:
🔹فقط یه شیء ژنراتور داری که دیتا رو دونهدونه موقع نیاز تولید میکنه.
🔹این ترفند کوچیک میتونه مصرف رم سرورت رو تو پردازشهای سنگین از گیگابایت به کیلوبایت کاهش بده.
🐍 @python_rd
🔹 تفاوتش فقط توی پرانتز گذاشتن به جای براکته، ولی مصرف رم رو بهینه میکنه.
مثلاً اگه بنویسی:
data = [i*2 for i in range(1000000)]🔹 پایتون کل لیست رو یکجا تو حافظه میسازه،
اما اگه بنویسی:
data = (i*2 for i in range(1000000)) 🔹فقط یه شیء ژنراتور داری که دیتا رو دونهدونه موقع نیاز تولید میکنه.
🔹این ترفند کوچیک میتونه مصرف رم سرورت رو تو پردازشهای سنگین از گیگابایت به کیلوبایت کاهش بده.
🐍 @python_rd
❤2👍1
🔆سادهترین کتابخانه برای تشخیص چهره که با زبان پایتون ساختهشده و به راحتی قابل استفاده است.
🔹https://github.com/ageitgey/face_recognition
🐍 @python_rd
🔹https://github.com/ageitgey/face_recognition
🐍 @python_rd
🔆 دیکشنری با متد setdefault
🔹شاید برات پیش اومده باشه که بخوای توی یه دیکشنری دادهها رو گروهبندی کنی و هی با خطای KeyError مواجه نشی. خیلیا اول چک میکنن کلید هست یا نه و بعد لیست جدید میسازن، ولی با setdefault کل این ماجرا توی یه خط خلاصه میشه. این متد اگه کلید وجود نداشته باشه با مقداری که بهش دادی میسازدش و همون لحظه مرجعش رو برمیگردونه تا بتونی روش عملیات بزنی.
🔹به چه دردی میخوره؟
این متد نسبت به نوشتن if و else های دستی هم خوانایی کد رو بالاتر میبره و هم توی پروژههای واقعی مدیریت دیکشنریهای تو در تو رو خیلی راحتتر میکنه.
🐍 @python_rd
🔹شاید برات پیش اومده باشه که بخوای توی یه دیکشنری دادهها رو گروهبندی کنی و هی با خطای KeyError مواجه نشی. خیلیا اول چک میکنن کلید هست یا نه و بعد لیست جدید میسازن، ولی با setdefault کل این ماجرا توی یه خط خلاصه میشه. این متد اگه کلید وجود نداشته باشه با مقداری که بهش دادی میسازدش و همون لحظه مرجعش رو برمیگردونه تا بتونی روش عملیات بزنی.
words = ["python", "django", "pandas", "docker", "fastapi"]
grouped = {}
# دستهبندی کلمات بر اساس حرف اول
for word in words:
first_letter = word[0]
grouped.setdefault(first_letter, []).append(word)
print(grouped)
# خروجی: {'p': ['python', 'pandas'], 'd': ['django', 'docker'], 'f': ['fastapi']}
🔹به چه دردی میخوره؟
این متد نسبت به نوشتن if و else های دستی هم خوانایی کد رو بالاتر میبره و هم توی پروژههای واقعی مدیریت دیکشنریهای تو در تو رو خیلی راحتتر میکنه.
🐍 @python_rd
🔆 کتابهای رایگان در مورد پایتون و استفاده بهتر از shell و regex و کلی چیز دیگه.
🔹learnbyexample.github.io/books
🐍 @python_rd
🔹learnbyexample.github.io/books
🐍 @python_rd
🔆 ترفند unpacking با ستاره (*)
🔹 خیلی وقتا یه لیست یا تاپل داری و فقط به اولین یا آخرین عضوش نیاز داری و بقیه برات مهم نیستن یا میخوای جداگونه جمع بشن. به جای اینکه دست به اسلایس و ایندکسگذاریهای گیجکننده بزنی، میتونی از عملگر ستاره برای آنپک کردن دادهها استفاده کنی تا کد خلوت و پایتونیکی داشته باشی.
🔹 به چه دردی میخوره؟
این ترفند موقع لاگین یا کار با دادههای استریم که اول و آخر پیام فرمت خاصی داره ولی بخش میانی طولش متغیره، کدت رو فوقالعاده خوانا و شیک میکنه.
🐍 @python_rd
🔹 خیلی وقتا یه لیست یا تاپل داری و فقط به اولین یا آخرین عضوش نیاز داری و بقیه برات مهم نیستن یا میخوای جداگونه جمع بشن. به جای اینکه دست به اسلایس و ایندکسگذاریهای گیجکننده بزنی، میتونی از عملگر ستاره برای آنپک کردن دادهها استفاده کنی تا کد خلوت و پایتونیکی داشته باشی.
scores = [18, 19, 14, 16, 20, 17]
# جدا کردن اولین نمره، نمرات وسط و آخرین نمره
first, *middle, last = scores
print("اولین:", first) # 18
print("وسطیها:", middle) # [19, 14, 16, 20]
print("آخرین:", last) # 17
🔹 به چه دردی میخوره؟
این ترفند موقع لاگین یا کار با دادههای استریم که اول و آخر پیام فرمت خاصی داره ولی بخش میانی طولش متغیره، کدت رو فوقالعاده خوانا و شیک میکنه.
🐍 @python_rd
❤3
🔆 فیچرهای باحالی که با زبان پایتون میشه توی ماشین لرنینگ ازش استفاده کرد.
🔹https://github.com/chiphuyen/python-is-cool
🐍 @python_rd
🔹https://github.com/chiphuyen/python-is-cool
🐍 @python_rd
🔆 ترفند مخفی | ساخت لودینگ متنی (Streaming Output)
🔹 وقتی از AI مدلها استفاده میکنی، دیدی متنشون کلمه به کلمه مثل تایپ شدن چاپ میشه؟ بهش میگن Streaming! نیازی به لایبرری خاصی نداری؛ با خود پایتون تو چند خط پیادهش کن:
🔹 به چه دردی میخوره؟
وقتی داری ابزارهای CLI یا اسکریپتهای تعاملی مینویسی، حس زنده بودن به برنامهت میده و UI متنی رو ۱۰۰ درجه جذابتر میکنه.
🐍 @python_rd
🔹 وقتی از AI مدلها استفاده میکنی، دیدی متنشون کلمه به کلمه مثل تایپ شدن چاپ میشه؟ بهش میگن Streaming! نیازی به لایبرری خاصی نداری؛ با خود پایتون تو چند خط پیادهش کن:
import sys
import time
def stream_text(text, delay=0.04):
for char in text:
sys.stdout.write(char)
sys.stdout.flush()
time.sleep(delay)
print()
stream_text("سلام! این یک خروجی استریمشده است...")
🔹 به چه دردی میخوره؟
وقتی داری ابزارهای CLI یا اسکریپتهای تعاملی مینویسی، حس زنده بودن به برنامهت میده و UI متنی رو ۱۰۰ درجه جذابتر میکنه.
🐍 @python_rd
❤2🔥1
🔆 کارایی و ساختار | پدیده Late Binding در Lambdaهای پایتون
🔹 تا حالا شده توی یک حلقه چندتا لمداسازی (Lambda) کنی و موقع اجرا ببینی همه با هم یک جواب تکراری میدن؟! این دقیقاً به خاطر پدیده Late Binding (ارزیابی دیرهنگام) در پایتونه.
🔹 کد مشکلدار:
🔹 دلیلش چیه؟
پایتون مقدار متغیر i رو موقع تعریف لمدا ذخیره نمیکنه، بلکه موقع اجرا (Call) به سراغ مقدار نهایی i توی حافظه میره!
🔹 راه حل استاندارد (با استفاده از Default Argument):
🔹 به چه دردی میخوره؟
این باگ توی پروژههای واقعی (مثل ساخت Callback برای دکمههای UI یا تعاریف Dynamic توی دیتابیس و کارهای Async) خیلی زیاد اتفاق میافته و فهمیدنش جلوی ساعتها دیباگینگ گیجکننده رو میگیره.
🐍 @python_rd
🔹 تا حالا شده توی یک حلقه چندتا لمداسازی (Lambda) کنی و موقع اجرا ببینی همه با هم یک جواب تکراری میدن؟! این دقیقاً به خاطر پدیده Late Binding (ارزیابی دیرهنگام) در پایتونه.
🔹 کد مشکلدار:
funcs = [lambda: i for i in range(3)]
for f in funcs:
print(f()) # خروجی: 2, 2, 2 !
🔹 دلیلش چیه؟
پایتون مقدار متغیر i رو موقع تعریف لمدا ذخیره نمیکنه، بلکه موقع اجرا (Call) به سراغ مقدار نهایی i توی حافظه میره!
🔹 راه حل استاندارد (با استفاده از Default Argument):
funcs = [lambda x=i: x for i in range(3)]
for f in funcs:
print(f()) # خروجی: 0, 1, 2 (درست شد!)
🔹 به چه دردی میخوره؟
این باگ توی پروژههای واقعی (مثل ساخت Callback برای دکمههای UI یا تعاریف Dynamic توی دیتابیس و کارهای Async) خیلی زیاد اتفاق میافته و فهمیدنش جلوی ساعتها دیباگینگ گیجکننده رو میگیره.
🐍 @python_rd
❤1
🔆 این ریپازیتوری مجموعهای از آموزشهای پایتون در زمینههای مختلفه از چیزهای ابتدایی گرفته تا ML یا کتابخونههای کاربردی مثل numpy و pandas
🔹https://github.com/codebasics/py
🐍 @python_rd
🔹https://github.com/codebasics/py
🐍 @python_rd
GitHub
GitHub - codebasics/py: Repository to store sample python programs for python learning
Repository to store sample python programs for python learning - codebasics/py
🔆 خیلی وقتا توی پروژههای جنگو یا حتی اسکریپتهای معمولی، نیاز داری بدونی یه تابع یا یه تیکه کد چقدر زمان میبره تا اجرا بشه تا بتونی بهینهش کنی. به جای استفاده از دستی گرفتن زمان با کتابخونه time، میتونی از یک دکوریتور (Decorator) ساده استفاده کنی که هر جا خواستی بذاریش و عملکرد کد رو بسنجی. این مدل کدنویسی خیلی تمیزتره و باعث میشه بدون تغییر دادن اصلِ منطقِ تابع، بتونی مانیتورینگ دقیق روی پرفورمنس برنامهت داشته باشی و نقاط کند رو سریع پیدا کنی.
🐍 @python_rd
import time
import functools
def timer(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
print(f"زمان اجرا: {time.perf_counter() - start:.4f} ثانیه")
return result
return wrapper
@timer
def heavy_task():
time.sleep(1)
heavy_task()
🐍 @python_rd
❤1
🔆 یکی از اشتباهات رایج و خطرناک توی پایتون، استفاده از ساختارهای تغییرپذیر مثل لیست یا دیکشنری به عنوان مقدار پیشفرض ورودی تابع هست که به Default Argument Trap معروفه. توی پایتون، مقادیر پیشفرض فقط یکبار موقع تعریف تابع ساخته میشن نه توی هر بار فراخوانی، بنابراین تمام فراخوانیها به یک لیست مشترک توی حافظه ارجاع میدن و دادههای قبلی ناخواسته حفظ میشن. راه استاندارد اینه که مقدار پیشفرض رو None بذاری و داخل بدنه تابع لیست جدید بسازی.
🐍 @python_rd
# روش غلط که باعث اشتراک حافظه میشه:
def add_item_wrong(item, target_list=[]):
target_list.append(item)
return target_list
print(add_item_wrong("Python")) # خروجی: ['Python']
print(add_item_wrong("Django")) # خروجی غیرمنتظره: ['Python', 'Django']
# روش درست و اصولی:
def add_item_correct(item, target_list=None):
if target_list is None:
target_list = []
target_list.append(item)
return target_list
print(add_item_correct("Django")) # خروجی درست: ['Django']
🐍 @python_rd
🔆 کتابخونه loguru (جایگزین جذاب logging)
🔹 وقتی توی پروژههای پایتونی میخوایم لاگ بندازیم، ماژول پیشفرض logging کلی کانفیگ خستهکننده میخواد، اما با پکیج loguru همهچیز توی سادهترین و تمیزترین حالت ممکن انجام میشه. با اجرای دستور
🔹این دکوراتور catch دقیقاً متغیرها و استک تریس رو قشنگ بهتون نشون میده بدون اینکه سیستم کرش کنه و لاگ گم بشه.
🐍 @python_rd
🔹 وقتی توی پروژههای پایتونی میخوایم لاگ بندازیم، ماژول پیشفرض logging کلی کانفیگ خستهکننده میخواد، اما با پکیج loguru همهچیز توی سادهترین و تمیزترین حالت ممکن انجام میشه. با اجرای دستور
pip install loguru میتونید خیلی سریع لاگهای رنگی، ساختاریافته و با جزئیات کامل خطا ذخیره کنید. فقط کافیه ایمپورتش کنید و استفاده کنید:from loguru import logger
# تنظیم ذخیره لاگ در فایل با قابلیت چرخش روزانه و فشردهسازی
logger.add("app.log", rotation="500 MB", retention="10 days", compression="zip")
@logger.catch # رهگیری خودکار ارورها و نمایش دقیق خط وقوع خطا
def divide(a, b):
return a / b
logger.info("برنامه با موفقیت شروع به کار کرد")
divide(10, 0)
🔹این دکوراتور catch دقیقاً متغیرها و استک تریس رو قشنگ بهتون نشون میده بدون اینکه سیستم کرش کنه و لاگ گم بشه.
🐍 @python_rd
❤1
🔆 کوییز!
🔹 خروجی چیه؟
🔹 گزینهها:
۱)
۲)
۳)
۴)
🐍 @python_rd
🔹 خروجی چیه؟
data = [[]] * 3
data[0].append(42)
print(data)
🔹 گزینهها:
۱)
[[42], [], []]۲)
[[42], [42], [42]]۳)
[[42]]۴)
Error🐍 @python_rd
🔆 معجزه
🔹 دیگه با دست دیتای ورودی رو چک نکن! (اعتبارسنجی مدرن در پایتون با Pydantic)
🔹 خیلی وقتا دیتایی از ورودی، کاربر یا API به دستمون میرسه (مثلاً JSON) و کلی خط کد مینویسیم تا چک کنیم سن حتماً عدد باشه، ایمیل فرمت درست داشته باشه و فیلدها خالی نباشن.
🔹 کتابخونه Pydantic این کار رو با تایپ هینتهای خود پایتون فوقالعاده ساده و تمیز کرده:
🔹 نمونه کد عملی:
🔹 چرا کاربردیه؟ هسته اصلی ابزارهایی مثل FastAPI و لانگچین همین Pydantic هست و تبدیل دادهها (Data Parsing) رو بهشدت امن و سریع میکنه.
🐍 @python_rd
Pydantic برای اعتبارسنجی و تبدیل تمیز دادهها🔹 دیگه با دست دیتای ورودی رو چک نکن! (اعتبارسنجی مدرن در پایتون با Pydantic)
🔹 خیلی وقتا دیتایی از ورودی، کاربر یا API به دستمون میرسه (مثلاً JSON) و کلی خط کد مینویسیم تا چک کنیم سن حتماً عدد باشه، ایمیل فرمت درست داشته باشه و فیلدها خالی نباشن.
🔹 کتابخونه Pydantic این کار رو با تایپ هینتهای خود پایتون فوقالعاده ساده و تمیز کرده:
🔹 نمونه کد عملی:
from datetime import datetime
from pydantic import BaseModel, EmailStr, Field, field_validator
class UserRegisterSchema(BaseModel):
name: str = Field(..., min_length=3, max_length=50)
email: EmailStr
age: int = Field(..., ge=18, le=100) # سن باید بین ۱۸ تا ۱۰۰ باشه
joined_at: datetime = Field(default_factory=datetime.now)
@field_validator("name")
def name_must_not_contain_numbers(cls, value):
if any(char.isdigit() for char in value):
raise ValueError("نام نباید شامل عدد باشد")
return value
# تست با دیتای خام:
raw_data = {
"name": "Ali Dolati",
"email": "ali@example.com",
"age": "25" # خود پایتون استرینگ رو تبدیل به عدد میکنه!
}
try:
user = UserRegisterSchema(**raw_data)
print("دیتای تمیز و معتبر:", user.model_dump())
except Exception as e:
print("خطای ولیدیشن:", e)
🔹 چرا کاربردیه؟ هسته اصلی ابزارهایی مثل FastAPI و لانگچین همین Pydantic هست و تبدیل دادهها (Data Parsing) رو بهشدت امن و سریع میکنه.
🐍 @python_rd
🔆 فهرستی ارزشمند برای برنامهنویسان حرفهای. مناسب برای توسعهدهندگان بکاند، فرانتاند، دواپس و برنامهنویسان عمومی.
🔹https://github.com/charlax/professional-programming
🐍 @python_rd
🔹https://github.com/charlax/professional-programming
🐍 @python_rd
GitHub
GitHub - charlax/professional-programming: A collection of learning resources for curious software engineers
A collection of learning resources for curious software engineers - charlax/professional-programming
🔆 ترفند پیشرفته
🔹 چطوری با ۶ خط کد، سرعت اجرای توابع رو بدون تغییر دادنشون بسنجیم؟
🔹 بهجای اینکه هر بار قبل و بعد از یک بلاک کد
🔹 نمونه کد عملی:
🔹 نتیجه: حتی اگه خطایی وسط کد بیفته، بخش
🐍 @python_rd
contextlib و تمیزکاری خودکار🔹 چطوری با ۶ خط کد، سرعت اجرای توابع رو بدون تغییر دادنشون بسنجیم؟
🔹 بهجای اینکه هر بار قبل و بعد از یک بلاک کد
time.time() بنویسید یا برای باز و بسته کردن کانکشنها کلی try/finally کثیف بزنید، با ماژول استاندارد contextlib میتونید کانتکست منیجر اختصاصی خودتون رو مثل آب خوردن با دستور with پیاده کنید!🔹 نمونه کد عملی:
import time
from contextlib import contextmanager
@contextmanager
def execution_timer(task_name: str):
start = time.perf_counter()
print(f"⏳ شروع عملیات: {task_name}...")
try:
yield # کدهای داخل بلوک with اینجا اجرا میشن
finally:
elapsed = time.perf_counter() - start
print(f"✅ پایان عملیات {task_name} | زمان اجرا: {elapsed:.4f} ثانیه")
# استفاده خیلی شیک و خوانا در هر کجای پروژه:
with execution_timer("پردازش دیتاهای سنگین"):
total = sum(i ** 2 for i in range(2_000_000))
🔹 نتیجه: حتی اگه خطایی وسط کد بیفته، بخش
finally اجرا میشه و هیچ ریسورسی (مثل فایل، قفل، یا کانکشن) باز نمیمونه.🐍 @python_rd
🔆 خیلی وقتا توی پایتون میخوایم یه کاری مثل حذف یک فایل موقت یا پاک کردن یک کلید از دیکشنری رو انجام بدیم و مطمئن نیستیم وجود داره یا نه. راه سنتی اینه که چهار خط try و except بنویسیم و آخرش pass بذاریم که کدمون رو شلوغ و ناخوانا میکنه.
🔹 یک راهکار خیلی تمیزتر استفاده از ماژول بیلتاین contextlib و متد suppress هست. با این قابلیت به جای بلوک تکراری خطا، در یک خط پایتونی و خوانا میگی دقیقاً چه خطایی نادیده گرفته بشه بدون اینکه جریان برنامه به هم بریزه.
🔹 این روش هم خوانایی کدت رو بالا میبره و هم دقیقاً به بقیه تیم نشون میده که قصدت نادیده گرفتن کنترلشده یک خطای مشخص بوده نه خاموش کردن تمام باگها.
🐍 @python_rd
🔹 یک راهکار خیلی تمیزتر استفاده از ماژول بیلتاین contextlib و متد suppress هست. با این قابلیت به جای بلوک تکراری خطا، در یک خط پایتونی و خوانا میگی دقیقاً چه خطایی نادیده گرفته بشه بدون اینکه جریان برنامه به هم بریزه.
import os
from contextlib import suppress
with suppress(FileNotFoundError):
os.remove(".cache_temp.json")
🔹 این روش هم خوانایی کدت رو بالا میبره و هم دقیقاً به بقیه تیم نشون میده که قصدت نادیده گرفتن کنترلشده یک خطای مشخص بوده نه خاموش کردن تمام باگها.
🐍 @python_rd
🔆 کد زیر رو با دقت نگاه کن و حدس بزن خروجی نهایی دستور پرینت چی میشه.
1. به نظرت برنامه با ارور متوقف میشه
2. تاپل اصلاً دستنخورده باقی میمونه
3. مقدار ۵۰ به لیست داخل تاپل اضافه میشه
🔹تحلیلت رو توی کامنتها بنویس
🐍 @python_rd
data = (1, 2, [30, 40])
try:
data[2] += [50]
except TypeError:
pass
print(data)
1. به نظرت برنامه با ارور متوقف میشه
2. تاپل اصلاً دستنخورده باقی میمونه
3. مقدار ۵۰ به لیست داخل تاپل اضافه میشه
🔹تحلیلت رو توی کامنتها بنویس
🐍 @python_rd
🌐 تکنیک عمیق: ژنراتورها در برابر اشغال حافظه
🔹 اگه توی پایتون بخوای یک فایل چند گیگابایتی لاگ رو بخونی یا روی چند میلیون عدد عملیات انجام بدی، ساختن یک لیست معمولی رم سیستمت رو کامل پر میکنه و سیستم قفل میکنه.
🔹 راهکار پایتونیک استفاده از ژنراتورها به جای لیست کامپرهنشنه. با عوض کردن کروشه به پرانتز معمولی، پایتون به جای ساختن کل دیتا در رم، فرمول تولید اون رو ذخیره میکنه و آیتمها رو تکبهتک تحویلت میده.
🔹 این مفهوم دقیقاً تفاوت اصلی دولوپرهای حرفهای رو موقع کار با دادههای سنگین، وب اسکرپینگ یا لاگآنالایزرها رقم میزنه.
🐍 @python_rd
🔹 اگه توی پایتون بخوای یک فایل چند گیگابایتی لاگ رو بخونی یا روی چند میلیون عدد عملیات انجام بدی، ساختن یک لیست معمولی رم سیستمت رو کامل پر میکنه و سیستم قفل میکنه.
🔹 راهکار پایتونیک استفاده از ژنراتورها به جای لیست کامپرهنشنه. با عوض کردن کروشه به پرانتز معمولی، پایتون به جای ساختن کل دیتا در رم، فرمول تولید اون رو ذخیره میکنه و آیتمها رو تکبهتک تحویلت میده.
# روش سنگین برای رم (میلیونها عدد یکجا ساخته میشن)
# numbers_list = [x * 2 for x in range(10_000_000)]
# روش بهینه با ژنراتور (مصرف رم نزدیک به صفر)
numbers_gen = (x * 2 for x in range(10_000_000))
print(next(numbers_gen))
print(next(numbers_gen))
🔹 این مفهوم دقیقاً تفاوت اصلی دولوپرهای حرفهای رو موقع کار با دادههای سنگین، وب اسکرپینگ یا لاگآنالایزرها رقم میزنه.
🐍 @python_rd