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

■ گروه پایتون:
@programmers_py
Download Telegram
🔆 قدرت Generator ها

چرا لیست‌های بزرگ توی پایتون حافظه رو می‌ترکونن؟

🔹 وقتی می‌نویسی
[x for x in range(1000000)]

تمام این لیست میره توی RAM. اگه به جای
[]

از پرانتز
()

استفاده کنی، داری از
Generator

استفاده می‌کنی.

🔹تفاوت؟ جنریتورها آیتم‌ها رو یکی‌یکی تولید می‌کنن (Lazy Evaluation). یعنی به جای اشغال کردن فضای زیاد، فقط وقتی لازم داری محاسبه می‌شن. برای پردازش فایل‌های بزرگ یا دیتای حجیم، جنریتورها بهترین دوست تو هستن.

🐍 @python_rd
👍6
🔆دیباگ حرفه‌ای در جنگو

🔹 با django-debug-toolbar رفیق شو!

🔹 خیلی وقت‌ها فکر می‌کنیم کدمون بهینه است، اما وقتی پنل دیباگ رو باز می‌کنیم، می‌بینیم ۱۰ تا کوئری تکراری به دیتابیس زدیم. این ابزار بهت نشون میده دقیقاً چند تا کوئری، در چه زمانی و با چه پارامترهایی اجرا شدن.

🔹 بهترین راه برای شناسایی مشکلاتی مثل N+1 Query همینه.

🐍 @python_rd
🔥1
🔆 چرا پایتون کندتر از C عه، ولی دنیای AI و Data Science رو فتح کرده؟

🔹همه‌مون شنیدیم که می‌گن «پایتون یک زبان کنده!». خب اگه کنده، چرا OpenAI، Google و Meta پروژه‌های هوش مصنوعی‌شون رو روی پایتون پیاده می‌کنن؟
راز داستان چیه؟

🔹 ۱. کتابخونه‌های C/C++ تحت پوشش:

کتابخونه‌های سنگینی مثل NumPy یا PyTorch روی پایتون اجرا می‌شن، اما هسته اصلیشون با C و C++ نوشته شده! پایتون فقط نقش یک «چسب» خوش‌دست رو بازی می‌کنه.

🔹 ۲. سرعت توسعه > سرعت اجرا:

در دنیای واقعی، زمانی که برنامه نویس صرف کدزدن می‌کنه گرون‌تر از زمان پردازش سروره!

🔹 ۳. GIL (Global Interpreter Lock):

قفلی که جلوی اجرای همزمان واقعی چند ترد (Multi-threading) رو می‌گرفت، حالا در نسخه‌های جدید پایتون (Python 3.13+) داره اختیاری/حذف میشه تا پایتون سریع‌تر از همیشه بشه.

🐍 @python_rd
🔆 افزایش ۱۰ برابری سرعت برنامه‌های پایتون فقط با ۱ خط کد!

🔹 تا حالا شده توی پایتون یک تابع محاسباتی سنگین (مثل فاکتوریل، فیبوناچی یا پردازش داده) داشته باشی که با ورودی‌های تکراری مدام اجرا بشه و سی‌پی‌یو رو درگیر کنه؟

🔹پایتون برای این کار یک ابزار فوق‌العاده توی کتابخونه داخلی functools داره به اسم @cache (یا @lru_cache).

🔹 روش عادی (اجرای مجدد محاسبات تکراری):
def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)

# برای n = 35 چند ثانیه طول می‌کشه و میلیون‌ها محاسبه تکراری انجام میده!
print(fibonacci(35))


🔹روش هوشمندانه با Cache (ذخیره نتایج قبلی در حافظه):
from functools import cache

@cache
def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)

# اجرای همون کد در کسری از میلی‌ثانیه (O(n) به جای O(2^n))!
print(fibonacci(35))

🔹 چطور کار می‌کنه؟
وقتی دکوراتور @cache رو بالای تابع می‌ذاری، پایتون ورودی‌ها و خروجی‌های تابع رو یادش می‌مونه. دفعه بعد که همون ورودی داده بشه، به جای محاسبه مجدد، بلافاصله جواب رو از رم برمی‌گردونه!

🐍 @python_rd
❤4🔥1
🔆دام خطرناک لیست پیش‌فرض در تابع

🔹این کد در نگاه اول درست به نظر می‌رسه:

def add_item(item, items=[]):
items.append(item)
return items

🔹اما لیست items فقط یک‌بار ساخته می‌شه و بین همه‌ی فراخوانی‌ها مشترکه!

راه درست:

def add_item(item, items=None):
if items is None:
items = []

items

🐍 @python_rd
👍2👎1
🔆 یک خط کد که جلوی باگ‌های عجیب رو می‌گیره!

🔹 به‌جای این‌که فایل رو دستی باز و بسته کنی، از with استفاده کن:
with open("data.txt", "r", encoding="utf-8") as file:
content = file.read()

🔹 حتی اگه وسط کار خطا رخ بده، پایتون فایل رو درست می‌بنده.

کد تمیزتر، مدیریت منابع بهتر، باگ کمتر.

🐍 @python_rd
🔆این ۳ تا سایت بصورت تقلب‌طور نکات کلی در مورد format string توی پایتون رو خلاصه کردن و با مثال توضیح دادن

🔹https://strftime.org/
🔹https://pyformat.info/
🔹https://www.strfti.me/

🐍 @python_rd
🔆کتاب خوبی برای یادگیری مفاهیم یادگیری عمیق به همراه notebook های پایتون که مربوط به کدهای داخل کتابه.

🔹https://udlbook.github.io/udlbook

🐍 @python_rd
🔆لیستی از سوالات مرتبط با سیستم type annotation در زبان پایتون که احتمالا قبلا بهشون برخورد نکرده بودید.

🔹https://python-type-challenges.zeabur.app

🐍 @python_rd
🔆 پیاده‌سازی پایتونی پروژه‌های کتاب معروف "the big book of small python projects"

🔹https://github.com/nihathalici/The-Big-Book-of-Small-Python-Projects

🐍 @python_rd
🙏1
🔆 ترفند: کد تمیزتر و سریع‌تر با dict.get() به جای if-else


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


🔹 روش معمولی و شلوغ:
user_data = {"name": "Reza", "role": "Developer"}

if "age" in user_data:
age = user_data["age"]
else:
age = 18 # مقدار پیش‌فرض

print(age)

🔹 روش حرفه‌ای:
user_data = {"name": "Reza", "role": "Developer"}

# اگر کلید نباشه، خودکار مقدار پیش‌فرض رو برمی‌گردونه
age = user_data.get("age", 18)

print(age)

🔹 چرا این روش بهتره؟

* کد کوتاه‌تر: ۴ خط کد تبدیل به ۱ خط میشه.
* جلوگیری از KeyError: اگر کلید وجود نداشته باشه، برنامه‌ت کرش نمیکنه.
* خوانایی بالا: کدت خواناتر و حرفه‌ای‌تر به‌نظر می‌رسه.

🔹 نکته: اگر مقدار دوم متد .get() رو مشخص نکنی، به صورت پیش‌فرض None برمی‌گردونه.

🐍 @python_rd
🔆 متد init واقعاً Constructor نیست! (داستان واقعی ساخت Object در پایتون)

🔹 خیلی‌ها فکر می‌کنند init شیء جدید را می‌سازد، اما در واقع این متد فقط شیء ساخته‌شده را مقداردهی اولیه (Initialize) می‌کند. سازندهٔ واقعی پایتون متد new است!

🔹 تفاوت اصلی در چیست؟

new:
یک classmethod است که خودِ متغیر cls را می‌گیرد، شیء جدید را ایجاد می‌کند و برمی‌گرداند.
init:
شیء ایجادشده (self) را می‌گیرد و ویژگی‌های آن را تنظیم می‌کند.


🔹 نمونه کاربرد واقعی: پیاده‌سازی الگوی Singleton

اگر بخواهی کلاس فقط و فقط یک نمونه (Instance) در کل برنامه داشته باشد، باید سراغ new بروی:
class DatabaseConnection:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            # ساخت شیء فقط برای بار اول
            cls._instance = super().__new__(cls)
        return cls._instance

# تست:
db1 = DatabaseConnection()
db2 = DatabaseConnection()

print(db1 is db2)  # Output: True (هر دو دقیقاً یک Object هستند)

🔹کاربرد دیگر: تغییر رفتار Typeهای Immutable (مثل تغییر دادن رفتار string یا tuple موقع ساخته شدن).

🐍 @python_rd
❤1
🔆 این سایت مسیرهای یادگیری گام به گام رو در اختیار شما قرار می ده که می تونید برای یادگیری حالت‌های مختلف concurrency در پایتون ازشون استفاده کنید.

🔹https://superfastpython.com/learning-paths

🐍 @python_rd
❤‍🔥1❤1
🔆 مدیریت منابع مثل حرفه‌ای‌ها: چطور با with مدیریت خطای تمیز بنویسیم؟

🔹دستور with رو همه برای باز کردن فایل (open) می‌شناسند، اما قدرتش خیلی بیشتر از این حرف‌هاست. هر جایی که نیاز به الگوی "آماده‌سازی -> اجرا -> تمیزکاری" داری، Context Manager نجات‌دهنده است.

🔹دو روش ساخت Context Manager سفارشی:

.روش اول: استفاده از Magic Methodها

با تعریف متدهای enter و exit در کلاس:
import time

class Timer:
def __enter__(self):
self.start = time.perf_counter()
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.perf_counter()
print(f"زمان اجرا: {self.end - self.start:.4f} ثانیه")
# اگر True برگردانی، خطاهای داخل بلوک with سائلنت می‌شوند!
return False

with Timer():
# کدی که می‌خواهی زمان اجرای آن سنجیده شود
sum(i**2 for i in range(1_000_000))

🔹روش دوم: راهکار سریع‌تر با contextlib

بدون نیاز به نوشتن کلاس و فقط با یک Generator:
from contextlib import contextmanager

@contextmanager
def managed_resource():
print("۱. تخصیص منبع (Connect / Open)")
try:
yield "Resource Object"
finally:
print("۲. آزادسازی منبع (Disconnect / Close)")

# استفاده:
with managed_resource() as res:
print(f"در حال کار با {res}")

🔹 به چه دردی میخوره؟

مدیریت Transactionهای دیتابیس، قفل‌های Multithreading، و اندازه‌گیری زمان اجرای سرویس‌ها.

🐍 @python_rd
❤1
🔆سایت منابع و نکاتی برای بهتر ساختن اپلیکیشن‌های با کیفیت بالا که البته بیشتر در مورد پایتون و جنگو و فلسک مطلب داره.

🔹https://testdriven.io

🐍 @python_rd
🔆 تا حالا دیدی توی پایتون از علامت @ بین دو تا متغیر استفاده بشه؟!

🔹وقتی صحبت از @ توی پایتون می‌شه، ۹۹٪ افراد یاد Decorator ها می‌افتن. اما پایتون ۳.۵ به بعد، یک عملگر اختصاصی برای ضرب ماتریس‌ها اضافه کرد که دقیقاً همین شکله‌

🔹داستان چیه؟

توی ریاضیات و یادگیری ماشین، ضرب معمولی (درایه‌به‌درایه) با ضرب ماتریسی فرق داره.

* 👈 ضرب درایه‌ای (Element-wise)
@ 👈 ضرب ماتریسی (Matrix Multiplication)

🔹 کد نمونه با کتابخانه NumPy:
import numpy as np

A = np.array([[1, 2],
[3, 4]])

B = np.array([[5, 6],
[7, 8]])

# ضرب درایه‌ای (معمولی)
print(A * B)
# [[ 5 12]
# [21 32]]

# ضرب ماتریسی با عملگر @
print(A @ B)
# [[19 22]
# [43 50]]

🔹 نکته: خودت هم می‌تونی پیاده‌سازیش کنی!

پایتون برای این عملگر یک متد جادویی (Magic Method) به اسم matmul داره. یعنی می‌تونی توی کلاس‌های شخصی خودت هم تعریفش کنی:
class Matrix:
def __init__(self, data):
self.data = data

def __matmul__(self, other):
# اینجا منطق ضرب ماتریس رو می‌نویسی
print("ضرب ماتریسی اجرا شد!")

m1 = Matrix([1, 2])
m2 = Matrix([3, 4])

m1 @ m2 # خروجی: ضرب ماتریسی اجرا شد!

🐍 @python_rd
❤1
🔆با گذاشتن وقت کمی توی ۳۰ روز به تسلط نسبی در زبان پایتون برسید (البته میشه سرعت رو کندتر کرد و ۱۰۰ روزه اینکارو کرد)

🔹https://github.com/Asabeneh/30-Days-Of-Python

🐍 @python_rd
🔆 یک کامپایلر برای زبان C که با پایتون نوشته شده و برای مقاصد آموزشی و یادگیری نحوه کارکرد کامپایلرها میتونه عالی باشه. به راحتی میتونین دیباگ‌اش کنید با Pycharm و کلی چیز جدید یاد بگیرید.

🔹https://github.com/ShivamSarodia/ShivyC

🐍 @python_rd
🔆 یکی از قدرتمندترین و در عین حال کم‌کاربردترین ابزارهای پایتون، functools.lru_cache هست.

🔹این دکوراتور مثل یک سیستم کشینگ (Caching) درون‌برنامه‌ای عمل می‌کنه و نتایج توابع سنگین یا محاسباتی رو ذخیره می‌کنه تا توی اجراهای بعدی با همون ورودی، بدون محاسبات مجدد و در صدم‌ثانیه نتیجه رو برگردونه!


🔹 بدون کشینگ (کند و اجرای مجدد محاسبات):
import time

def get_user_data(user_id):
# فرض کنید این تابع به دیتابیس وصل میشه و ۲ ثانیه طول می‌کشه
time.sleep(2)
return f"User Data for ID: {user_id}"

# هر بار فراخوانی ۲ ثانیه زمان می‌بره
print(get_user_data(101)) # 2 seconds
print(get_user_data(101)) # 2 seconds (دوباره همان زمان!)

🔹 با lru_cache (بهینه‌سازی فوق‌العاده با اضافه کردن ۱ خط):
from functools import lru_cache
import time

@lru_cache(maxsize=128) # حداکثر ۱۲۸ نتیجه اخیر را کش می‌کند
def get_user_data(user_id):
time.sleep(2)
return f"User Data for ID: {user_id}"

print(get_user_data(101)) # اجرا میشه (۲ ثانیه)
print(get_user_data(101)) # آنی و بدون معطلی برمی‌گرده! (0.00 seconds)

🔹 نکات کلیدی:

. پارامتر maxsize: ظرفیت کش را مشخص می‌کند (None یعنی بدون محدودیت).

. شرط مهم: آرگومان‌های تابعی که دکوراتور @lru_cache می‌گیرد باید Hashable باشند (مثل string, int, tuple) نه لیست یا دیکشنری.

. کاربرد: فراخوانی‌های مکرر API، محاسبات سنگین ریاضی، یا کوئری‌های ثابت دیتابیس.


🔹 بونس: اگر خواستید کش را به صورت دستی خالی کنید:
get_user_data.cache_clear()

🐍 @python_rd
❤1
🔆 تا حالا شده یک تابع داشته باشی که مجبور باشه چند نوع ورودی مختلف رو پردازش کنه؟

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

🔹روش معمولی احتمالاً این شکلیه:

def process_log(data):
if isinstance(data, str):
print(f"Text log: {data.upper()}")

elif isinstance(data, list):
print(f"{len(data)} errors found")

elif isinstance(data, dict):
print(f"Log source: {data.get('source')}")

else:
print("Unknown data type")

🔹این کد فعلاً کار می‌کنه، اما هر بار که بخوای نوع جدیدی اضافه کنی، باید همین تابع رو تغییر بدی.

🔹اینجاست که singledispatch وارد میشه.

from functools import singledispatch


@singledispatch
def process_log(data):
print(f"نوع داده پشتیبانی نمی‌شود: {type(data).__name__}")


@process_log.register
def _(data: str):
print(f"لاگ متنی: {data.upper()}")


@process_log.register
def _(data: list):
print(f"تعداد خطاها: {len(data)}")


@process_log.register
def _(data: dict):
print(f"منبع لاگ:گ متنی: SERVER IS DOWN

process_log(["404 is down")
# لاگ متنی: SERVER IS DOWN

process_log(["404", "Timeout", "Database Error"])
# تعداد خطاها: 3

process_log({"source": "AuthService"})
# منبع لاگ: AuthService

🔹تابع اصلی فقط برای حالت پیش‌فرض استفاده میشه و هر نوع داده، پردازش مخصوص خودش رو داره.

🔹مزیتش اینه که به‌جای ساختن یک تابع بزرگ پر از if/elif، منطق هر نوع ورودی رو جدا می‌نویسی.

🔹البته یک نکته مهم وجود داره: singledispatch فقط بر اساس نوع اولین آرگومان تصمیم می‌گیره، نه بر اساس مقدار یا تعداد آرگومان‌ها.

🐍 @python_rd