09982292579
info@mehraeen.ac.ir
فارسی پرچم
فارسی
یک زبان را انتخاب کنید
فارسی پرچم
فارسی
0
دسته ها
خانه تقویم‌آموزشی مدرس وبلاگ چارت‌‌دروس تماس‌با‌ما درباره‌ما انجمن‌ها
برنامه سازی پیشرفته

جلسه 18 Reflection

خلاصه نکات کلیدی: تعریف: بازتاب قابلیت بررسی، تجزیه و تحلیل و تغییر ساختار و رفتار برنامه در زمان اجرا است. کاربردها: دسترسی و اصلاح متادیتای کلاس‌ها، متدها و ویژگی‌ها. فراخوانی پویا متدها و دسترسی به ویژگی‌ها بر اساس نام. ساخت پویا اشیاء و کلاس‌ها. توسعه فریمورک‌ها، ابزارهای تست، ORMها (Object-Relational Mappers) و سیستم‌های پیکربندی.

مقدمه:

بازتاب (Reflection) به قابلیت یک برنامه در حال اجرا برای بررسی، تجزیه و تحلیل و اصلاح ساختار و رفتار خود در طول زمان اجرا اشاره دارد. در زمینه مهندسی نرم‌افزار، این مفهوم به ویژه در زبان‌های برنامه‌نویسی شیءگرا کاربرد دارد و امکان دسترسی و تغییر متادیتا (metadata) مانند کلاس‌ها، متدها، ویژگی‌ها و غیره را فراهم می‌کند. درک بازتاب برای نوشتن کدهای انعطاف‌پذیر، قابل توسعه و قابل نگهداری ضروری است، به خصوص در فریمورک‌ها، ابزارهای تست و سیستم‌های پویا.

مثال‌ها:


  1. دسترسی به ویژگی‌های کلاس در زمان اجرا:

فرض کنید کلاسی به نام User دارید:

python
class User:
def __init__(self, name, email):
self.name = name
self.email = email

user_instance = User("Alice", "alice@example.com")

# استفاده از بازتاب برای دسترسی به نام ویژگی‌ها و مقادیر آنها
for attr_name in dir(user_instance):
if not attr_name.startswith("__"): # نادیده گرفتن متدهای داخلی
attr_value = getattr(user_instance, attr_name)
print(f"{attr_name}: {attr_value}")

خروجی:

text
name: Alice
email: alice@example.com

این مثال نشان می‌دهد که چگونه می‌توانیم در زمان اجرا، نام و مقدار ویژگی‌های یک شیء را بدون دانستن قبلی نام آن‌ها، استخراج کنیم.


  1. فراخوانی متدها در زمان اجرا:

فرض کنید متدهایی در کلاس Calculator دارید:

python
class Calculator:
def add(self, a, b):
return a + b
def subtract(self, a, b):
return a - b

calc_instance = Calculator()
method_name = "add"
args = (5, 3)

# استفاده از بازتاب برای فراخوانی متد
if hasattr(calc_instance, method_name):
method = getattr(calc_instance, method_name)
result = method(*args)
print(f"Result of {method_name}: {result}")

خروجی:

text
Result of add: 8

این مثال چگونگی فراخوانی پویا یک متد بر اساس نام آن در زمان اجرا را نشان می‌دهد.


  1. ساخت اشیاء در زمان اجرا:

فرض کنید نام کلاس‌ها را به صورت رشته دریافت می‌کنید و نیاز دارید اشیاء متناظر را بسازید:

python
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print(f"{self.name} says Woof!")

class Cat:
def __init__(self, name):
self.name = name
def meow(self):
print(f"{self.name} says Meow!")

def create_animal(animal_type, name):
# دریافت کلاس بر اساس نام رشته
AnimalClass = globals()[animal_type]
# ساخت نمونه جدید
return AnimalClass(name)

my_dog = create_animal("Dog", "Buddy")
my_dog.bark()

my_cat = create_animal("Cat", "Whiskers")
my_cat.meow()

خروجی:

text
Buddy says Woof!
Whiskers says Meow!

این نمونه نشان می‌دهد که چگونه می‌توان کلاس‌ها را بر اساس نامشان در زمان اجرا پیدا کرد و نمونه‌هایی از آن‌ها ایجاد نمود.

تمرین پایان فصل:


  1. کلاس ConfigurationLoader: یک کلاس به نام ConfigurationLoader بنویسید که یک فایل پیکربندی (مانند JSON یا INI) را بخواند. این کلاس باید متدهایی داشته باشد که بتواند مقادیر پیکربندی را بر اساس نام کلیدها در زمان اجرا بازیابی کند. از بازتاب برای ایجاد متدهای getter پویا استفاده کنید؛ یعنی اگر در فایل پیکربندی کلید database_url وجود داشت، کلاس باید متد get_database_url() را به صورت پویا ایجاد کند که مقدار مربوطه را برگرداند.

  2. سیستم پلاگین ساده: یک سیستم پلاگین بسیار ساده طراحی کنید. یک کلاس پایه Plugin تعریف کنید. سپس کلاس‌های مختلف پلاگین (مثلاً GreetingPlugin، CalculationPlugin) را بسازید که از Plugin ارث‌بری کنند. یک برنامه اصلی بنویسید که بتواند پلاگین‌های موجود در یک پوشه خاص را بارگذاری کند (با استفاده از بازتاب برای یافتن و نمونه‌سازی کلاس‌ها) و متد اصلی هر پلاگین را فراخوانی کند.

  3. اعتبارسنجی خودکار (Self-Validation): یک کلاس DataValidator ایجاد کنید. این کلاس باید بتواند ورودی‌های خود را بر اساس ویژگی‌های (attributes) خاصی که با دکوراتورها (decorators) علامت‌گذاری شده‌اند، اعتبارسنجی کند. به عنوان مثال، یک دکوراتور @required برای فیلدهای اجباری و @numeric برای فیلدهای عددی. از بازتاب برای پیمایش ویژگی‌های یک شیء و اعمال قوانین اعتبارسنجی استفاده کنید.

خلاصه نکات کلیدی:


























  • تعریف: بازتاب قابلیت بررسی، تجزیه و تحلیل و تغییر ساختار و رفتار برنامه در زمان اجرا است.

  • کاربردها:

  • دسترسی و اصلاح متادیتای کلاس‌ها، متدها و ویژگی‌ها.

  • فراخوانی پویا متدها و دسترسی به ویژگی‌ها بر اساس نام.

  • ساخت پویا اشیاء و کلاس‌ها.

  • توسعه فریمورک‌ها، ابزارهای تست، ORMها (Object-Relational Mappers) و سیستم‌های پیکربندی.

  • توابع کلیدی (بسته به زبان برنامه‌نویسی):

  • getattr(), setattr(), hasattr(), delattr(): برای کار با ویژگی‌ها.

  • dir(): برای لیست کردن ویژگی‌ها و متدها.

  • isinstance(): برای بررسی نوع شیء.

  • type(): برای دریافت نوع (کلاس) یک شیء.

  • globals(), locals(): برای دسترسی به فضاهای نام.

  • exec(), eval(): برای اجرای کد داینامیک (با احتیاط فراوان).
درس متنی 18/19
در حال مشاهده
جلسه 18 Reflection