Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

مفهوم Duck Typing

جزء من قسم Object Oriented Programming في رحلة Python على Coddy — الدرس 24 من 64.

يركز Duck typing على ما يمكن للكائن فعله، وليس على ماهيته. إذا كان الكائن يحتوي على methods التي تحتاجها، يمكنك استخدامه - بغض النظر عن نوع class الخاص به.

إليك فئتان غير مرتبطتين لهما نفس الدوال (methods):

class Duck:
    def swim(self):
        return "Duck swimming"
    
    def quack(self):
        return "Quack!"

class Person:
    def swim(self):
        return "Person swimming"
    
    def quack(self):
        return "Person imitating a duck: Quack!"

لاحظ أن Duck و Person لا يرثان من نفس الفئة الأب (parent class)، ولكن كليهما يمتلكان الدالتين swim() و quack().

أنشئ دالة تعمل مع أي كائن "يشبه البطة":

def make_it_swim_and_quack(duck_like_object):
    print(duck_like_object.swim())
    print(duck_like_object.quack())

هذه الدالة لا تهتم بنوع الكائن - بل تهتم فقط بأن الكائن يمتلك الأساليب (methods) المطلوبة.

استخدم الدالة مع كلا الفئتين:

make_it_swim_and_quack(Duck())
make_it_swim_and_quack(Person())

المخرجات:

Duck swimming
Quack!
Person swimming
Person imitating a duck: Quack!

أضف فئة أخرى "شبيهة بالبطة":

class Robot:
    def swim(self):
        return "Robot swimming with propellers"
    
    def quack(self):
        return "Robot sound: BEEP BEEP!"

make_it_swim_and_quack(Robot())

المخرجات:

Robot swimming with propellers
Robot sound: BEEP BEEP!

نقطة رئيسية: يسمح نمط البطة (Duck typing) بتعدد الأشكال (polymorphism) بدون وراثة. إذا كان الكائن يحتوي على الدوال (methods) التي تحتاجها، يمكنك استخدامه. وهذا يجعل كود بايثون مرنًا ويتبع المبدأ القائل "طلب السماح أسهل من طلب الإذن".

challenge icon

التحدي

متوسط

في هذا التحدي، ستقوم بتنفيذ نظام يوضح مفهوم البرمجة بالبطة (duck typing) مع كائنات مختلفة تشبه الملفات:

  • textfile.py: قم بتنفيذ فئة TextFile مع دوال read() و write(data)
  • database.py: قم بتنفيذ فئة Database بتواقيع دوال مطابقة
  • networkresource.py: قم بتنفيذ فئة NetworkResource بتواقيع دوال مطابقة
  • driver.py - قم بتنفيذ حالات اختبار للتحقق من أن تنفيذك يعمل بشكل صحيح

يحتوي كل ملف على تعليقات TODO مفصلة لتوجيه تنفيذك.

ورقة مرجعية

يركز أسلوب "Duck typing" (كتابة البطة) على ما يمكن للكائن فعله، وليس على ماهيته. إذا كان الكائن يحتوي على الأساليب (methods) التي تحتاجها، فيمكنك استخدامه بغض النظر عن نوع فئته (class type).

مثال على "duck typing" مع فئات غير مرتبطة تشترك في نفس الأساليب:

class Duck:
    def swim(self):
        return "Duck swimming"
    
    def quack(self):
        return "Quack!"

class Person:
    def swim(self):
        return "Person swimming"
    
    def quack(self):
        return "Person imitating a duck: Quack!"

إنشاء دالة تعمل مع أي كائن "يشبه البطة":

def make_it_swim_and_quack(duck_like_object):
    print(duck_like_object.swim())
    print(duck_like_object.quack())

# Works with any object that has swim() and quack() methods
make_it_swim_and_quack(Duck())
make_it_swim_and_quack(Person())

يسمح "Duck typing" بتعدد الأشكال (polymorphism) بدون وراثة - إذا كان الكائن يحتوي على الأساليب التي تحتاجها، فيمكنك استخدامه. وهذا يجعل كود بايثون مرناً ويتبع مبدأ "طلب المغفرة أسهل من طلب الإذن".

جرّب بنفسك

# TODO: استيراد فئة TextFile من textfile.py
# TODO: استيراد فئة Database من database.py
# TODO: استيراد فئة NetworkResource من networkresource.py

def process_data(data_source, data):
    # TODO: استدعاء التابع read() على data_source وطباعة النتيجة
    # TODO: استدعاء التابع write(data) على data_source وطباعة النتيجة
    pass


# Test with different data sources - DO NOT MODIFY THIS TEST CODE
text_file = TextFile()
database = Database()
network = NetworkResource()

print("Processing text file:")
process_data(text_file, "Hello, world!")

print("\
Processing database:")
process_data(database, "User record")

print("\
Processing network resource:")
process_data(network, "GET request")
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming