Syntax | سینتکس
2.98K subscribers
423 photos
111 videos
35 files
392 links
Download Telegram
توی پایتون بجای isinstance از singledispatch استفاده کن!

۱. ابتدا دو کلاس با استفاده از @dataclass تعریف میکنیم:
@dataclass
class UserCanceledSubscription:
username: str

@dataclass
class UserSubscribed:
username: str

این‌ها دو نوع ایونت هستند: یکی برای زمانی که کاربر مشترک می‌شود و دیگری برای زمانی که اشتراکش را لغو می‌کند.

۲. روش اول با استفاده از isinstance:
def process(event):
if isinstance(event, UserSubscribed):
print(f"Enable access to user {event.username}")
elif isinstance(event, UserCanceledSubscription):
print(f"Disable access to user {event.username}")

در این روش، برای هر نوع رویداد یک شرط if نوشته شده که نوع رویداد را چک می‌کند.

۳. روش دوم با استفاده از singledispatch:
@singledispatch
def process(event):
pass

@process.register(UserCanceledSubscription)
def _(event):
print(f"Disable access to user {event.username}")

@process.register(UserSubscribed)
def _(event):
print(f"Enable access to user {event.username}")

در این روش، برای هر نوع رویداد یک تابع جداگانه تعریف می‌شود که فقط برای آن نوع خاص اجرا می‌شود.

مزایای استفاده از singledispatch:

۱. کد تمیزتر: به جای زنجیره‌ای از `if/elif`، هر منطق در یک تابع جداگانه قرار می‌گیرد.

۲. قابلیت توسعه بهتر: اضافه کردن نوع جدید فقط نیاز به اضافه کردن یک تابع جدید دارد، نه تغییر کد موجود.

۳. جداسازی مسئولیت‌ها: هر تابع فقط مسئول پردازش یک نوع خاص است.

۴. کاهش پیچیدگی: به جای یک تابع بزرگ با شرط‌های متعدد، چندین تابع کوچک و ساده داریم.

نحوه کار:
- @singledispatch
یک تابع پایه تعریف می‌کند
- @process.register()
توابع مختلف را برای انواع مختلف ورودی ثبت می‌کند
- در زمان اجرا، بر اساس نوع ورودی، تابع مناسب فراخوانی می‌شود

کاربرد این الگو در مواردی مثل:
- پردازش انواع مختلف پیام‌ها یا رویدادها
- تبدیل داده‌ها بین فرمت‌های مختلف
- اعمال عملیات‌های متفاوت روی انواع مختلف داده
- پیاده‌سازی الگوی Observer یا Event Handler

نمونه استفاده نهایی:
events = [
UserSubscribed(username="johndoe"),
UserCanceledSubscription(username="johndoe"),
]

for event in events:
process(event)


این کد به طور خودکار تابع مناسب را برای هر نوع رویداد فراخوانی می‌کند.

#python #singledispatch

@Syntax_fa
👍17❤‍🔥2🔥1😁1
فایل آپلود شده رو فقط با پسوندش چک می‌کنی؟ بیخیال!

تاحالا شده کاربر فایلی رو آپلود کنه و شما فقط پسوندش ( jpg یا pdf) رو چک کنید و با خوشحالی بگید کار تمومه؟ اگه اینطوره، باید بگم که یه جای کار حسابی می‌لنگه!

کاربر به راحتی می‌تونه یک فایل مخرب (مثلاً یه اسکریپت) رو به virus.png تغییر نام بده و سیستم شما رو دور بزنه.

راه حل چیه؟ کتابخونه python-magic

این پکیج یک رابط (Wrapper) برای کتابخونه قدرتمند libmagic در زبان C هست. کار اصلیش اینه که بیخیال اسم و پسوند فایل بشه و بره سراغ اصل مطلب محتوای خود فایل.

مجیک چند بایت اول یک فایل (که بهش هدر یا Magic Numbers می‌گن) رو می‌خونه و از روی اون امضای دیجیتالی، نوع واقعی فایل رو تشخیص می‌ده.

مثال:
import magic
from django.core.files.uploadedfile import InMemoryUploadedFile

def get_mime_type_from_content(file: InMemoryUploadedFile) -> str:
"""Reads the initial bytes of a file to determine its actual MIME type."""
try:
initial_bytes = file.read(2048)
file.seek(0)
return magic.from_buffer(initial_bytes, mime=True)
except Exception as err:
raise Exception(f"Failed to detect MIME type: {err}")

def check_file_is_image(file: InMemoryUploadedFile) -> bool:
"""Check if the uploaded file is an image based on its MIME type."""
try:
mime_type = get_mime_type_from_content(file)
return mime_type.startswith("image/")
except Exception as err:
print(f"[ERROR] check_file_is_image: {err}")
return False


#libmagic #python_magic

@Syntax_fa
13👍6