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

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

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

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

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
🔆مجموعه‌ای از بهترین کتابخانه‌های یادگیری ماشین برای زبان پایتون که هر هفته آپدیت میشه

🔹https://github.com/ml-tooling/best-of-ml-python

🐍 @python_rd
🔆 یکی از خطاهای رایج پایتون اینه:

user = User.objects.filter(username="ali").first()

print(user.email)

🔹اگر کاربری با نام ali وجود نداشته باشه، مقدار user برابر با None میشه و این خطا رو می‌گیریم:

AttributeError: 'NoneType' object has no attribute 'email'

🔹راه ساده اینه که قبل از استفاده، وجود کاربر رو بررسی کنیم:

user = User.objects.filter(username="ali").first()

if user is None:
print("کاربر پیدا نشد")
else:
print(user.email)

🔹اگر فقط می‌خوای یک کاربر مشخص رو پیدا کنی، می‌تونی از get_object_or_404 استفاده کنی:

from django.shortcuts import get_object_or_404

user = get_object_or_404(User, username="ali")
print(user.email)

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

🔹نکته مهم اینه که متد first() هیچ‌وقت خطا نمی‌ده؛ اگر چیزی پیدا نکنه، None برمی‌گردونه. پس هرجا از first() استفاده کردی، حواست به مقدار برگشتی باشه.

🐍 @python_rd
❤1
🔆 فرمول کثیف اما کاربردی sys._getframe تو پایتون؛ ابزاری که معمولاً تو کدبیس‌های معمولی نمی‌بینی اما برای دیباگ، لاگین پیشرفته و ساخت فریم‌ورک‌ها مثل معجزه عمل می‌کنه.


🔹 چطور بدون پاس دادن اسم تابع، بفهمیم کی کدمون رو صدا زده؟

فرض کن داری یک سیستم لاگین یا دیباگ می‌نویسی و می‌خوای دقیقاً بدونی تابع فعلی از کجا و توسط چه تابعی فراخوانی شده، بدون اینکه مجبور باشی دستی اسم تابع رو ورودی بدی.
import sys


def trace_caller():
# عدد 1 یعنی یک فریم برو عقب‌تر (جایی که این تابع صدا زده شده)
caller_frame = sys._getframe(1)

func_name = caller_frame.f_code.co_name
line_no = caller_frame.f_lineno
file_name = caller_frame.f_code.co_filename

print(f"📍 Called from: {func_name}() at line {line_no} in {file_name}")


def user_login():
# بدون پاس دادن هیچ پامتر اضافی!
trace_caller()


user_login()

🔹 چطوری کار می‌کنه؟

* sys._getframe(0):
فریم حال حاضر (همین جابی که هستیم).

* sys._getframe(1):
فریم فراخوان‌کننده (یک پله عقب‌تر در Stack call).

* f_code.co_name:
اسم تابعی که کد توش اجرا شده.

* f_locals:
حتی می‌تونی به متغیرهای محلیِ تابع فراخوان‌کننده هم دسترسی پیدا کنی!


🔹 نکته امنیتی/معماری:
پیشوند _ نشون می‌ده این یک متد درونی در CPython است. برای منطق اصلی برنامه (Business Logic) ازش استفاده نکن، اما برای دیباگرها، ساخت دکوراتورهای هوشمند و ابزارهای Logging یک سلاح مخفی و فوق‌العاده‌ست!


🐍 @python_rd
❤1
🔆 مفهوم قدرتمند و پنهان init_subclass در پایتون (معرفی‌شده از پایتون ۳.۶)؛ ابزاری شیک و تمیز که جایگزین کدنویسی پیچیده با Metaclassها میشه و بهت اجازه میده رفتار کلاس‌های فرزند (Subclasses) رو کنترل و مدیریت کنی.


🔹 چطور موقع ارث‌بری، کلاس فرزند رو خودکار اعتبارسنجی یا ثبت کنیم؟
فرض کن داری یک فریم‌ورک، Plugin System یا ساختار Modular می‌نویسی و می‌خوای هر وقت کلاسی از کلاس پایه تو ارث‌بری کرد، یک سری قوانین اجرا بشن (مثلاً حتماً یک attribute خاص داشته باشه) یا اسمش تو یک لیست مرکزی ثبت بشه.
قدیم برای این کار از MetaClass استفاده می‌شد، اما الان با init_subclass فوق‌العاده ساده‌تره:

class PluginBase:
# لیستی برای ثبت خودکار تمام پلاگین‌ها
registry = {}

def __init_subclass__(cls, plugin_name=None, **kwargs):
super().__init_subclass__(**kwargs)

# ۱. اجبار فرزند به داشتن ویژگی مشخص
if not hasattr(cls, "author"):
raise TypeError(
f"کلاس {cls.__name__} باید متغیر author داشته باشه!"
)

# ۲. ثبت خودکار کلاس فرزند در سیستم
name = plugin_name or cls.__name__
cls.registry[name] = cls


# --------------------------------------------------
# حالا کلاس‌های فرزند چطور رفتار می‌کنند؟


class PaymentPlugin(PluginBase, plugin_name="zarinpal"):
author = "Amir" # اگر این نبود، پایتون ارور می‌داد!


print(PluginBase.registry)
# خروجی: {'zarinpal': <class '__main__.PaymentPlugin'>}

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

* سادگی فوق‌العاده: نیnewدرگیر شدن با __new__ و مفاهیم سنگین Metaclasses نداری.

* قابلیت پاس دادن آرگومان: می‌تونی موقع ارث‌بری جلوی اسم کلاس والد، ورودی پاس بدی (PluginBase, plugin_name="zarinpal").

* کد تمیزتر (Clean Code): خوانایی برنامه رو برای باقی اعضای تیم چند برابر می‌کنه.


🔹 کاربرد اصلی: ساخت سیستم‌های Plugin، اتوماتیک‌سازی ثبت Modelها (مثل ORMها) و اعمال استانداردهای کدهای سازمانی روی کلاس‌های فرزند.

🐍 @python_rd
🔆اگر با پایتون کار کرده باشید احتمالا zen of python رو شنیدید که چندین جمله است که یه جورایی عصاره فکری پشت طراحی پایتونه. خیلیاش پیچیده‌ان و درکش در لحظه سخته. توی این gist با مثال برای هر کدوم توضیح داده شده.

🔹https://gist.github.com/evandrix/2030615

🐍 @python_rd
🔥 ۵۰۰ دوره آموزشی مکتب‌خونه رایگان شد!

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

🐍 پایتون، توسعه وب و طراحی سایت

🤖 هوش مصنوعی، یادگیری ماشین و علم داده

🖥️ کامپیوتر، لینوکس، شبکه و امنیت

دوره «یادگیری ماشین با پایتون» با تدریس جادی هم بین آموزش‌های رایگان این طرحه.

فقط تا ۸ شهریور فرصت داری؛ از طریق لینک زیر آموزش دلخواهت رو انتخاب کنی و با وارد کردن کد IRANMAHER، با تخفیف ۱۰۰٪ ثبت‌نامش کنی👇

🔗 لینک دوره‌ها:

https://mktb.me/vinj/
🔆 حذف آیتم‌های تکراری از لیست، بدون به‌هم‌ریختن ترتیب

🔹 فرض کن از API یه لیست دریافت کردی:

users = ["ali", "reza", "sara", "ali", "mohammad", "reza"]

می‌خوایم آیتم‌های تکراری حذف شن، اما ترتیب اصلی لیست حفظ بشه.

🔹 خب میگی اینکارو میکنم:

unique_users = list(set(users))
print(unique_users)

🔹 ولی مشکل اینجاست که set ترتیب آیتم‌ها رو تضمین نمی‌کنه.

🔹راه بهتر:

users = ["ali", "reza", "sara", "ali", "mohammad", "reza"]

unique_users = list(dict.fromkeys(users))

print(unique_users)

🔹خروجی:

['ali', 'reza', 'sara', 'mohammad']

🔹چرا کار می‌کنه؟

دیکشنری تو پایتون کلید تکراری قبول نمیکنه و ترتیب اضافه‌شدن کلیدها رو هم نگه می‌داره.
پس dict.fromkeys() آیتم‌های تکراری رو حذف می‌کنه و ترتیب لیست رو هم حفظ می‌کنه.

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

🐍 @python_rd
👍2❤1
🔆 بچه ها از یکی خوشتون اومد اینجوری حستونو بهش بگید🥹😂

🦾 @python_rd
🥴5😁3🤣3👏1
🔆 قدرت List Comprehension در پایتون

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

🔹روش سنتی و طولانی:
numbers = [1, 2, 3, 4, 5, 6]
even_squares = []

for n in numbers:
if n % 2 == 0:
even_squares.append(n**2)

print(even_squares) # [4, 16, 36]

🔹روش حرفه‌ای بهتر:
numbers = [1, 2, 3, 4, 5, 6]

even_squares = [n**2 for n in numbers if n % 2 == 0]

print(even_squares) # [4, 16, 36]

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

🔹 به چه دردی میخوره؟
کد کوتاه‌تر، سرعت بیشتر و ظاهر حرفه‌ای‌تر.

🐍 @python_rd
🔆 تست پایتون: خروجی این کد چی میشه؟

data = [1, 2, 3]
result = [lambda x: x * i for i in data]

print([f(2) for f in result])

🔹گزینه‌ها:
۱) [2, 4, 6]
۲) [6, 6, 6]
۳) [1, 2, 3]
۴) Error

🐍 @python_rd
🔥1
🔆 قابلیت کاربردی و کم‌تر دیده شده (functools.singledisplay)

🔹 اگر توی پایتون کدی داری که بر اساس نوع داده ورودی (int, list, str و...) رفتارهای متفاوتی نشون میده، به‌جای نوشتن if-elif-else های طولانی و کثیف، می‌تونی از دکوراتور فوق‌العاده singledispatch استفاده کنی!

from functools import singledispatch


# تابع اصلی برای حالت پیش‌فرض
@singledispatch
def process(data):
raise NotImplementedError("نوع داده پشتیبانی نمی‌شود!")


# رفتار تابع وقتی ورودی string است
@process.register(str)
def _(data):
return f"متن: {data.strip().upper()}"


# رفتار تابع وقتی ورودی int است
@process.register(int)
def _(data):
return f"عدد: {data * 10}"


# رفتار تابع وقتی ورودی list است
@process.register(list)
def _(data):
return f"تعداد عناصر لیست: {len(data)}"


# 🧪 تست:
print(process(" python ")) # خروجی: متن: PYTHON
print(process(5)) # خروجی: عدد: 50
print(process([1, 2, 3])) # خروجی: تعداد عناصر لیست: 3

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

کدت کاملاً تمیز، ماژولار و بر اساس اصل Open/Closed در SOLID میشه. هر زمان نوع داده جدیدی اضافه شد، کافیه یک تابع جدید @register کنی بدون اینکه کد قبلی رو دستکاری کنی!

🐍 @python_rd
❤2
🔆 خیلی وقتا توی پایتون کدهایی می‌بینیم که برای پیمایش روی یک لیست، هم‌زمان با اندیس، میان یه متغیر شمارنده دستی تعریف می‌کنن یا از range(len(items)) استفاده می‌کنن.

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

fruits = ['apple', 'banana', 'orange']

for index, fruit in enumerate(fruits, start=1):
print(f"{index}: {fruit}")

🔹هم کد خواناتر میشه و هم احتمال خطاهای دستی به صفر می‌رسه

🐍 @python_rd
❤1👌1
🔆 تست پایتون!
x = 10
res = [x for x in range(3)]

print(x)

خروجی چیه؟
۱) 2
۲) 10
۳) UnboundLocalError
۴) None

🐍 @python_rd
❤1🥱1
🔆 چرا در پایتون به معنای واقعی نمیتوانیم thread داشته باشیم. توی این مقاله جالب بصورت ملموس در مورد GIL در پایتون صحبت میشه.

🔹https://pythonspeed.com/articles/python-gil

🐍 @python_rd
🔆داکیومنت خوبی برای class-base view توی جنگو که به همراه متدها و attribute های هر قسمت کامل توضیح داده شده.

🔹https://ccbv.co.uk

🐍 @python_rd
❤1🔥1
🔆 ۶ تکنیک طلایی برای نوشتن کدهای پایتونی تمیزتر و حرفه‌ای‌تر

🔹۱. استفاده از List Comprehension به جای حلقه‌های طولانی:

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

🔹۲. مدیریت فایل‌ها و کانکشن‌ها با Context Manager:

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

🔹 ۳. نام‌گذاری بر اساس استانداردهای PEP 8:

نام توابع و متغیرها را با حروف کوچک و زیرخط (snake_case) و نام کلاس‌ها را با حروف بزرگ (PascalCase) بنویسید تا خوانایی پروژه برای هم‌تیمی‌ها حفظ شود.

🔹 ۴. بهره‌گیری از Type Hinting:

با مشخص کردن نوع ورودی و خروجی توابع، اشکال‌زدایی پروژه بسیار ساده‌تر می‌شود و ویرایشگر کدهایتان خطاهای نوع داده را سریع‌تر پیدا می‌کند.

🔹 ۵. جایگزینی f-string با فرمت‌های قدیمی:

فرمت‌بندی با f-string سریع‌ترین، خواناترین و تمیزترین روش برای الحاق متغیرها به رشته‌هاست.

🔹 ۶. کنترل خطا با ساختار try-except دقیق:

از بلاک‌های کلی except: خودداری کنید و همیشه خطاهای مشخص و احتمالی مثل KeyError یا ValueError را مدیریت کنید تا خطاهای پیش‌بینی‌نشده مخفی نمانند.

🐍 @python_rd
❤2✍1
🌐 دکوریتورها (Decorators) توی پایتون مثل یک «روکش» برای توابع هستن. فرض کن می‌خوای به چند تا تابع، قابلیت لاگ‌گیری یا زمان‌سنجی اضافه کنی بدون اینکه کدهای اصلیشون رو تغییر بدی. دکوریتور این کار رو خیلی تمیز برات انجام می‌ده و کدت رو ماژولار نگه می‌داره.

🔹 مثلاً این کدِ یک زمان‌سنج ساده‌ست که نشون می‌ده تابع چقدر طول می‌کشه اجرا بشه:

import time

def timer(func):
def wrapper():
start = time.time()
func()
print(f"زمان اجرا: {time.time() - start:.4f} ثانیه")
return wrapper

@timer
def say_hello():
time.sleep(1)
print("سلام به دنیای پایتون!")

say_hello()

🔹 می‌بینی که چطور با قرار دادن @timer بالای تابع say_hello، بدون اینکه حتی یک خط از منطق داخل خودِ تابع رو دستکاری کنیم، قابلیت زمان‌سنجی بهش اضافه شد. هر جا دیدی یه چیزی با @ شروع می‌شه و بالای تعریف یه تابع نشسته، بدون که داره اون تابع رو با قابلیت‌های جدید "دکور" می‌کنه.

🐍 @python_rd
🔥2❤1
🔆 کتابی در مورد پترن‌های ساده برای ساختن اپلیکیشن‌های پیچیده با پایتون که به رایگان و آنلاین قابل مطالعه است.

🔹https://www.cosmicpython.com/book/preface.html

🐍 @python_rd
❤3
🔆 خروجی این تکه کد پایتون چی میشه؟

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

print(add_item(1))
print(add_item(2))

🔹 گزینه‌ها:

۱) [1] و [2]

۲) [1] و [1, 2]

۳) خطا میده

۴) [2] و [2]

🐍 @python_rd
🔆 اگر توی پایتون تابعی داری که محاسبات سنگین انجام میده یا ورودی‌های تکراری داره، نیازی نیست هر بار از اول اجرا بشه! با استفاده از دکوراتور lru_cache می‌تونی خروجی‌ها رو کَش (Cache) کنی.
from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)

# اجرای این کد بدون lru_cache زمان زیادی می‌بره.
print(fibonacci(100))

🔹 به چه دردی میخوره؟
این روش برای توابعی عالیه که با ورودی یکسان، همیشه خروجی یکسانی میدن (Pure Functions).

🐍 @pyrhon_rd
👍1