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

■ گروه پایتون:
@programmers_py
Download Telegram
🔆 فایل pip.conf؛ امن کردن Pip جلوی حملات Supply Chain!

🔹 خیلی وقت‌ها توی پروژه‌ها پکیج‌های شخصی یا سازمانی نصب می‌کنیم. حمله‌ای به اسم Dependency Confusion وجود داره که اگر نام پکیج داخلی شما با یک پکیج عمومی روی PyPI یکی باشه، Pip ممکنه نسخه مخرب عمومی رو دانلود کنه!

🔹 راه حل: ایجاد یک فایل کانفیگ اختصاصی برای Pip تا اولویت دانلود رو فقط روی مخزن امن تنظیم کنه:

# مسیر فایل: ~/.config/pip/pip.conf
[global]
index-url = https://your-private-repo.com/simple
extra-index-url = https://pypi.org/simple
require-hashes = true

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

با اضافه کردن require-hashes = true حتی اگر کسی پکیجی روی PyPI رو هک کنه و تغییر بده، تا زمانی که Hash اون تغییر نکرده باشه Pip اجازه نصب نمیده. این نکته برای کسانی که پروژه واقعی و تجاری می‌زنن عالیه.

🐍 @python_rd
🔆 تکنیک ناشناخته و حرفه‌ای functools.singledispatch (اورلود کردن توابع در پایتون بدون if/elseهای طولانی!)

​🔹 چطوری تو پایتون تابع Overloading تمیز بنویسیم؟

​خیلی وقت‌ها پیش میاد که میخوایم یه تابع بستگی به اینکه چه جنس ورودی‌ای (String, List, Dict...) بهش میدیم، رفتار متفاوتی داشته باشه. روش مبتدیانه چیه؟ نوشتن یه سلسله if isinstance(...) طولانی!

​اما روش سینیورها توی پایتون استفاده از singledispatch از کتابخونه استاندارد functools هست.

from functools import singledispatch

@singledispatch
def process_data(data):
raise NotImplementedError("این تایپ پشتیبانی نمیشه!")

@process_data.register(str)
def _(data):
return f"متن پردازش شد: {data.upper()}"

@process_data.register(list)
def _(data):
return f"لیست پردازش شد با طول: {len(data)}"

@process_data.register(dict)
def _(data):
return f"کلیدهای دیکشنری: {list(data.keys())}"

# تست تابع
print(process_data("hello")) # متن پردازش شد: HELLO
print(process_data([1, 2, 3])) # لیست پردازش شد با طول: 3

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

کد بسیار کپسوله، خلوت و خوانا میشه.
اصل Open/Closed رعایت میشه (میتونی بعداً بدون دست زدن به تابع اصلی، تایپ جدید اضافه کنی).

🐍 @python_rd
👍2
🔆 مجموعه‌ای از نکات و تقلب‌‌نامه‌هایی برای زبان برنامه‌نویسی پایتون

🔹https://gto76.github.io/python-cheatsheet

🐍 @python_rd
❤1
🔆 مدیریت منابع با contextlib

🔹 از تکرار try...finally برای بستن فایل‌ها و اتصال‌ها خسته شدی؟

🔹 پایتون ابزاری به نام Context Manager داره که با دستور with استفاده میشه. اما اگر بخوای خودت یک Context Manager سفارشی بسازی، نیازی نیست حتماً کلاس با متدهای enter و exit بنویسی!
با ماژول contextlib و دکوراتور @contextmanager می‌تونی خیلی تمیز این کار رو انجام بدی:

from contextlib import contextmanager

@contextmanager
def managed_resource():
print("-> باز کردن اتصال/فایل")
yield "Resource Object"
print("-> بستن ایمن اتصال/فایل")

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

🐍 @python_rd
🔆 خروجی این تکه کد چیه؟

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

print(add_item(1))
print(add_item(2))
print(add_item(3, [9, 9]))
print(add_item(4))

🔹گزینه‌ها:

الف) [1], [2], [9, 9, 3], [4]
ب) [1], [1, 2], [9, 9, 3], [1, 2, 4]
ج) [1], [2], [3], [4]

🐍 @python_rd
🔆 چرا برای داده‌های حجیم نباید از return استفاده کنی؟

🔹 وقتی یک تابع لیست بزرگی از داده‌ها رو با return برمی‌گرداند، کل داده‌ها باید همزمان توی رم (RAM) لود بشن که باعث مصرف شدید حافظه و کندی سیستم میشه.

🔹 اما اگر به جای return از yield استفاده کنی، تابع تبدیل به یک Generator میشه که داده‌ها رو به صورت تک‌به‌تک و تنبل (Lazy Evaluation) تولید می‌کنه:

def read_large_file(file_path):
with open(file_path, 'r') as f:
for line in f:
yield line.strip() # هر بار فقط یک خط را در حافظه نگه می‌دارد

🔹با این روش می‌تونی فایل‌های چند گیگابایتی رو با مصرف چند مگابایت رم پردازش کنی!

🐍 @python_rd
🔆 مدیریت تمیز منابع با Context Managerهای سفارشی (contextlib)

🔹 ساخت Context Managerها معمولاً با نوشتن کلاس و متدهای enter و exit انجام می‌شود. اما با دکوراتور contextmanager@ از ماژول contextlib می‌توانید این کار را خیلی سریع‌تر و پایتونیک‌تر انجام دهید.

from contextlib import contextmanager
import time


@contextmanager
def measure_time(task_name: str):
start_time = time.perf_counter()
print(f"--- شروع: {task_name} ---")
try:
yield # کنترل اجرا در این نقطه به بدنه with منتقل می‌شود
finally:
elapsed = time.perf_counter() - start_time
print(f"--- پایان: {task_name} | زمان اجرا: {elapsed:.4f} ثانیه ---\n")


# استفاده کاربردی
with measure_time("پردازش سنگین داده‌ها"):
# شبیه‌سازی یک کار سنگین
total = sum(i**2 for i in range(10_000_000))
print(f"نتیجه محاسبات: {total}")

🐍 @python_rd
🔆 حذف تاریخی GIL از پایتون (Free-threaded Python)

🔹 یک رویداد تاریخی: حذف قفل مفسر (GIL) از هسته CPython رسماً کلید خورد!

🔹 سرانجام پس از سال‌ها بحث و مناظره در بنیاد نرم‌افزار پایتون (PSF)، طرح PEP 703 (معروف به Free-threaded CPython) تصویب و گام‌های اجرایی آن آغاز شد. با این تغییر، مفسر پایتون می‌تواند از تمام هسته‌های پردازنده (Multi-Core CPU) در Multi-threading به صورت واقعی بهره ببرد بدون اینکه گلوگاه قفل مفسر سر راهش باشد.

🔹 نکات کلیدی این تحول:

▪️ پشتیبانی اولیه به صورت بیلد آزمایشی (Experimental / --disable-gil) در دسترس قرار گرفته است.

▪️ تیم‌های توسعه کتابخانه‌های بزرگ مانند NumPy و PyTorch در حال بازنویسی بخش‌های C-API خود برای سازگاری با حالت بدون GIL هستند.

▪️ طبق پیش‌بینی هسته مرکزی، پایتون در پردازش‌های سنگین موازی تا چند برابر افزایش کارایی را تجربه خواهد کرد.

🔹 منبع رسمی:

• مستندات رسمی PEP 703: peps.python.org/pep-0703
• اعلامیه Steering Council پایتون: discuss.python.org

🐍 @python_rd
🔆 راز مکانیزم پیاده‌سازی و تغییر جهت NaN در الگوریتم مرتب‌سازی پایتون (Timsort)

🔹 باگ ریاضیاتی پنهان: چرا پایتون هیچ‌وقت نمی‌تواند لیستی از NaNها را مرتب کند؟!

🔹 در پایتون، مقدار float('nan') (Not a Number) خصوصیت عجیبی دارد:

nan طبق استاندارد IEEE-754 با خودش هم برابر نیست!
float('nan') == float('nan') ⬅️ خروجی False است!
float('nan') < 5 ⬅️ باز هم False است!

🔹 حالا شگفتی ماجرا در متد .sort() پایتون است:

الگوریتم مرتب‌سازی CPython یعنی Timsort بر اصل تقارن و ترتیبی بودن مقایسه‌ها استوار است. اگر شما لیستی شامل اعداد و NaN را با .sort() مرتب کنید:


🔹 نتیجه خروجی به ترتیب قرارگیری اولیه عناصر بستگی دارد و غیرقابل‌پیش‌بینی است!

🔹 پایتون هیچ خطایی (Error) raise نمی‌کند، اما خروجی نهایی مرتب‌شده نخواهد بود!

🔹 مهندسان CPython سال‌هاست که در گیت‌هاب پایتون روی این موضوع بحث دارند و تصمیم گرفته‌اند برای حفظ پرفورمنس Timsort، هیچ لایه اعتبارسنجی اضافی اضافه نکنند و این مسئولیت را روی دوش برنامه‌نویس بگذارند!

🐍@python_rd
کوییز پایتون

🔆 خروجی اجرای کد زیر چیست؟

t = (1, 2, [3, 4])

try:
t[2] += [5]
except TypeError:
pass

print(t)

🔹 گزینه‌ها:

1️⃣ (1, 2, [3, 4])
2️⃣ (1, 2, [3, 4, 5])
3️⃣ خطای مدیریت‌نشده رخ می‌دهد و برنامه متوقف می‌شود
4️⃣ خروجی (1, 2, [5]) خواهد بود


🐍@python_rd