Python Coding Academy
🐍 آموزش جامع Python — پست ۲۳۹
مدیریت خطاهای سفارشی در پروژههای Python
در پست قبل یاد گرفتیم ورودیهای Repository را اعتبارسنجی کنیم.
حالا میخواهیم بهجای استفاده از خطاهای عمومی در تمام بخشهای برنامه، Exceptionهای اختصاصی برای پروژه خودمان بسازیم.
این روش باعث میشود مدیریت خطاها دقیقتر و کد خواناتر شود.
🔹 ساخت Exception اختصاصی
در Python میتوانیم با ارثبری از Exception، خطای مخصوص پروژه بسازیم:
class UserError(Exception):
pass
class InvalidUserError(UserError):
pass
class UserNotFoundError(UserError):
pass
در اینجا:
UserError خطای پایه مربوط به کاربران است.
InvalidUserError برای ورودی نامعتبر است.
UserNotFoundError برای کاربر پیدا نشده است.
چون دو خطای آخر از UserError ارثبری میکنند، میتوانیم همه آنها را با گرفتن UserError مدیریت کنیم.
🔹 استفاده در Repository
در فایل user_repository.py:
class UserRepository:
def __init__(self, connection):
self.connection = connection
def add_user(self, name):
if not isinstance(name, str):
raise InvalidUserError("Name must be a string")
name = name.strip()
if not name:
raise InvalidUserError("Name cannot be empty")
cursor = self.connection.execute(
"INSERT INTO users (name) VALUES (?)",
(name,)
)
return cursor.lastrowid
def get_by_id(self, user_id):
cursor = self.connection.execute(
"SELECT id, name FROM users WHERE id = ?",
(user_id,)
)
user = cursor.fetchone()
if user is None:
raise UserNotFoundError(
f"User with ID {user_id} was not found"
)
return user
در این مثال فرض شده کلاسهای Exception در همین فایل تعریف شدهاند.
🔹 مدیریت خطا در برنامه اصلی
در main.py:
try:
user = users.get_by_id(999)
except UserNotFoundError as error:
print("User error:", error)
except UserError as error:
print("Invalid operation:", error)
اگر کاربر با شناسه 999 وجود نداشته باشد، پیام مناسب نمایش داده میشود.
🔹 چرا ترتیب except مهم است؟
فرض کنیم:
class UserError(Exception):
pass
class UserNotFoundError(UserError):
pass
اگر ابتدا بنویسیم:
except UserError:
...
except UserNotFoundError:
...
خطای UserNotFoundError ابتدا توسط UserError گرفته میشود؛ بنابراین بخش دوم اجرا نخواهد شد.
به همین دلیل، ابتدا خطاهای اختصاصیتر و سپس خطاهای عمومیتر را بنویس.
⚠️ نکته مهم
Exception اختصاصی را برای خطاهایی بساز که معنای مشخصی در پروژه دارند. لازم نیست برای هر شرط ساده یک کلاس جدید ایجاد کنیم.
همچنین خطاهای دیتابیس، مانند sqlite3.IntegrityError، همچنان ممکن است رخ دهند و باید متناسب با نیاز پروژه مدیریت شوند.
🧠 خلاصه
Exception
↓
UserError
├── InvalidUserError
└── UserNotFoundError
با Exceptionهای اختصاصی میتوانیم خطاهای پروژه را بهتر دستهبندی و مدیریت کنیم.
🎯 تمرین
یک Exception به نام DuplicateUserError بساز که از UserError ارثبری کند.
سپس آن را در Repository به کار ببر تا اگر نام کاربری تکراری بود، خطای مشخصی ایجاد شود.
پست ۲۳۹ از دوره جامع Python 🐍
9 ·