PyCoders (پایتون)
4.11K subscribers
979 photos
148 videos
69 files
237 links
◇ #پایتون جادوگر دنیای برنامه نویسی!
◇ معرفی حوزه های کاری پایتون
◇ معرفی کتابخونه های کاربردی
◇ معرفی دوره های مفید
◇ معرفی تکنیک ها و نکات
◇ نقشه راه حوزه های مختلف
◇ اخبار و آپدیت های پایتون
◇ و هر چیزی در مورد پایتون!

■ گروه پایتون:
@programmers_py
Download Telegram
🔆 فیچرهای باحالی که با زبان پایتون میشه توی ماشین لرنینگ ازش استفاده کرد.

🔹https://github.com/chiphuyen/python-is-cool

🐍 @python_rd
🔆 ترفند مخفی | ساخت لودینگ متنی (Streaming Output)

🔹 وقتی از 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 (ارزیابی دیرهنگام) در پایتونه.


🔹 کد مشکل‌دار:

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
🔆 خیلی وقتا توی پروژه‌های جنگو یا حتی اسکریپت‌های معمولی، نیاز داری بدونی یه تابع یا یه تیکه کد چقدر زمان می‌بره تا اجرا بشه تا بتونی بهینه‌ش کنی. به جای استفاده از دستی گرفتن زمان با کتابخونه time، می‌تونی از یک دکوریتور (Decorator) ساده استفاده کنی که هر جا خواستی بذاریش و عملکرد کد رو بسنجی. این مدل کدنویسی خیلی تمیزتره و باعث میشه بدون تغییر دادن اصلِ منطقِ تابع، بتونی مانیتورینگ دقیق روی پرفورمنس برنامه‌ت داشته باشی و نقاط کند رو سریع پیدا کنی.

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
Python Errors Tables.pdf
572.7 KB
🔆 انواع خطاهای پایتون، توضیحش و دلیل اتفاق افتادنش توی این فایل جمع شده.

🐍 @python_rd
🔆 یکی از اشتباهات رایج و خطرناک توی پایتون، استفاده از ساختارهای تغییرپذیر مثل لیست یا دیکشنری به عنوان مقدار پیش‌فرض ورودی تابع هست که به Default Argument Trap معروفه. توی پایتون، مقادیر پیش‌فرض فقط یک‌بار موقع تعریف تابع ساخته میشن نه توی هر بار فراخوانی، بنابراین تمام فراخوانی‌ها به یک لیست مشترک توی حافظه ارجاع میدن و داده‌های قبلی ناخواسته حفظ میشن. راه استاندارد اینه که مقدار پیش‌فرض رو None بذاری و داخل بدنه تابع لیست جدید بسازی.

# روش غلط که باعث اشتراک حافظه میشه:
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 همه‌چیز توی ساده‌ترین و تمیزترین حالت ممکن انجام میشه. با اجرای دستور 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
🔆 کوییز!

🔹 خروجی چیه؟

data = [[]] * 3
data[0].append(42)
print(data)

🔹 گزینه‌ها:
۱) [[42], [], []]
۲) [[42], [42], [42]]
۳) [[42]]
۴) Error

🐍 @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
🔆 ترفند پیشرفته 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 هست. با این قابلیت به جای بلوک تکراری خطا، در یک خط پایتونی و خوانا می‌گی دقیقاً چه خطایی نادیده گرفته بشه بدون اینکه جریان برنامه به هم بریزه.

import os
from contextlib import suppress

with suppress(FileNotFoundError):
os.remove(".cache_temp.json")

🔹 این روش هم خوانایی کدت رو بالا می‌بره و هم دقیقاً به بقیه تیم نشون می‌ده که قصدت نادیده گرفتن کنترل‌شده یک خطای مشخص بوده نه خاموش کردن تمام باگ‌ها.

🐍 @python_rd
🔆 کد زیر رو با دقت نگاه کن و حدس بزن خروجی نهایی دستور پرینت چی می‌شه.

data = (1, 2, [30, 40])

try:
data[2] += [50]
except TypeError:
pass

print(data)

1. به نظرت برنامه با ارور متوقف می‌شه
2. تاپل اصلاً دست‌نخورده باقی می‌مونه
3. مقدار ۵۰ به لیست داخل تاپل اضافه می‌شه

🔹تحلیلت رو توی کامنت‌ها بنویس

🐍 @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
🌐 ولیدیشن سریع دیتا با پای‌دنتیک

🔹 بررسی دستی دیکشنری‌ها برای اطمینان از اینکه سن کاربر عدده یا ایمیلش فرمت درستی داره، کاری تکراری، خسته‌کننده و مستعد بروز خطاست.

🔹 کتابخانه پای‌دنتیک بهت اجازه می‌ده با تعریف یک کلاس ساده و استفاده از تایپ‌هینت‌های پایتون، ورود هرگونه داده نامعتبر رو به لایه‌های عمیق برنامه در همان لحظه اول متوقف کنی.

from pydantic import BaseModel, EmailStr

class UserProfile(BaseModel):
name: str
age: int
email: EmailStr

# اعتبارسنجی خودکار و تبدیل تایپ‌ها
user = UserProfile(name="علی", age=25, email="ali@example.com")
print(user.model_dump())

🔹 این ابزار هسته اصلی فریم‌ورک‌های مدرنی مثل فست‌ای‌پی‌آی هست و نوشتن کدهای بک‌اند رو امن، تمیز و کاملاً تایپ‌سیف می‌کنه.

🐍 @python_rd
🔥2❤1
🔆 تله کپی سطحی در ساختارهای تودرتو

🔹 خیلی از دولوپرهای پایتون تفاوت بین کپی معمولی و دیپ‌کپی رو نمی‌دونن و وقتی دیتای یک دیکشنری یا لیست تو در تو رو کپی می‌کنن، با تغییر مقدار یکی، اون یکی هم ناخواسته تغییر می‌کنه. خروجی کد زیر رو بررسی کن:

original = [[1, 2], [3, 4]]
shallow_copy = list(original)

shallow_copy[0][0] = 999

print(original[0][0])

🔹 خروجی عدد ۹۹۹ خواهد بود نه عدد ۱! دلیلش اینه که متد کپی سطحی فقط رفرنس لیست‌های داخلی رو کپی می‌کنه. اگر می‌خوای کپی کاملاً ایزوله‌ای بسازی که با تغییر دادنش آسیبی به اصل داده نرسه، باید از متد دیپ‌کپی در ماژول استاندارد کپی استفاده کنی.

🐍 @python_rd
🔆 اشتباه رایج: هندل کردن استثناها بدون ذکر نوع خطا

🔹 نوشتن یک عبارت اگزپت خالی یا گرفتن کلاس کلی اکسپشن یکی از بدترین عادت‌های کدنویسیه، چون تمام خطاهای سیستمی مثل بستن برنامه با کنترل سی یا خطاهای نگارشی رو مخفی می‌کنه.

🔹 کد پر از ریسک خطاهای نامرتبط رو پنهان می‌کنه، در حالی که راهکار درست اینه که دقیقاً نوع خطایی که انتظار داری رخ بده رو شکار کنی و ثبتش کنی.

# کد پر از باگ و مخفی‌کننده مشکلات
# try:
# val = int(user_input)
# except:
# pass

# راهکار استاندارد و شفاف
try:
val = int(user_input)
except ValueError as e:
print(f"فرمت ورودی نامعتبر است: {e}")

🔹 با این کار اگر توی تابع باگ عمیق‌تری مثل خطای دسترسی به حافظه یا نام‌گذاری اشتباه وجود داشته باشه، لاگ می‌شه و از دید تیم فنی مخفی نمی‌مونه.


🐍 @python_rd
🔆 یه وبسایت خوب برای یادگیری بازی‌سازی ساده با پایتون و pygame به همراه پروژه های عملی

🔹programarcadegames.com

🐍 @python_rd
❤3