مفهوم تعدد الاشكال في بايثون
تعدد الأشكال في بايثون يشير إلى قدرة دالة معينة على قبول متغيرات مختلفة من حيث النوع أو العدد والتعامل معها بشكل صحيح. وبهذه الطريقة، يمكن استخدام نفس الدالة للقيام بمهام مختلفة باستخدام متغيرات مختلفة، مما يجعل الكود أكثر قابلية لإعادة الاستخدام وأكثر فعالية.
في بايثون، يمكن تحقيق التعدد في الأشكال باستخدام "المعاملات المتغيرة" (Variable Arguments) و "المعاملات الاسمية" (Keyword Arguments). المعاملات المتغيرة تتيح للدالة قبول عدد غير محدود من المتغيرات، بينما المعاملات الاسمية تتيح للدالة قبول متغيرات في شكل أزواج "اسم-قيمة"، مما يسمح بتمرير المتغيرات بطريقة أكثر وضوحًا وسهولة قراءة.
على سبيل المثال، يمكن تعريف دالة لجمع قائمة من الأرقام باستخدام المعاملات المتغيرة كالتالي:
def sum_numbers(*numbers):
result = 0
for num in numbers:
result += num
return result
ويمكن استخدام هذه الدالة بشكل مختلف باستخدام أعداد مختلفة من المتغيرات الداخلية، مثل:
print(sum_numbers(1, 2, 3)) # Output: 6
print(sum_numbers(4, 5, 6, 7)) # Output: 22
print(sum_numbers(10, 20)) # Output: 30
وباستخدام المعاملات الاسمية، يمكن استخدام نفس الدالة لإجراء عمليات حسابية مختلفة، مثل:
print(sum_numbers(num1=1, num2=2, num3=3)) # Output: TypeError: sum_numbers() got an unexpected keyword argument 'num1'
حيث يظهر خطأ لأن الدالة لا تقبل المتغيرات الاسمية.
دوال جاهزة في بايثون تطبق مبدأ تعدد الأشكال
هناك العديد من الدوال في بايثون التي تطبق مبدأ تعدد الأشكال (Polymorphism)، ومن أهم هذه الدوال:
- دالة الطباعة print() والتي يمكنها طباعة قيم متغيرات مختلفة من نوعات مختلفة، سواء كانت أنواع رقمية مثل int و float أو أنواع نصية مثل str.
- دالة len() والتي تستخدم لحساب عدد العناصر في أي تسلسل مثل القوائم (lists) والتراكيب البيانية (tuples) والمجموعات (sets) والنصوص (strings).
- دالة type() والتي تُستخدم للحصول على نوع المتغير سواء كان ذلك int أو str أو float أو غيرها.
- دالة sum() والتي تقوم بجمع جميع الأرقام في قائمة معيّنة، ويمكن استخدام هذه الدالة مع أي قائمة تحتوي على أعداد.
هذه بعض الأمثلة الموضحة لتطبيق المبدأ:
def polymorphic_function(arg):
print(arg)
polymorphic_function(5)
polymorphic_function("Hello World")
polymorphic_function([1, 2, 3])
في هذا المثال، يمكن استدعاء الدالة
polymorphic_function()
مع أي نوع من البيانات، سواء كان ذلك عددًا صحيحًا (int)، أو نصًا (str)، أو قائمة (list)، وهو ما يجعلها تطبق مبدأ تعدد الأشكال.بناء دالة تطبق مبدأ تعدد الأشكال
يمكن بناء دالة تطبق مبدأ تعدد الأشكال في بايثون على النحو التالي:
def polymorphic_function(argument):
if isinstance(argument, int):
return argument ** 2
elif isinstance(argument, str):
return argument.upper()
elif isinstance(argument, list):
return [elem * 2 for elem in argument]
else:
return "Unsupported type"
في هذه الدالة، نستخدم isinstance للتحقق من نوع البيانات الممررة إلى الدالة. إذا كان النوع يسمح بالعملية المطلوبة، فإن الدالة تقوم بتنفيذ هذه العملية وتعيد النتيجة. إذا كان النوع غير مدعوم، فإن الدالة تعيد رسالة خطأ.
يمكن استخدام هذه الدالة لتطبيق مبدأ تعدد الأشكال على أي نوع من البيانات. على سبيل المثال، يمكن استخدامها لتحويل جميع الأحرف في سلسلة إلى حروف كبيرة، أو لضرب كل عنصر في قائمة بالعدد 2، أو لإيجاد التربيع التكعيبي لأي عدد صحيح.
تطبيق مبدأ تعدد الأشكال مع الوراثة
يمكن تطبيق مبدأ تعدد الأشكال مع الوراثة في بايثون باستخدام التركيبة inheritance و polymorphism. يمكن تعريف كلاسات مختلفة تورث من نفس الأب، وتحتوي على طرق بنفس الاسم لكن بتنفيذات مختلفة.
على سبيل المثال، يمكن تعريف كلاس الحيوان:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("Subclass must implement abstract method")
ثم، يمكن تعريف كلاسات فرعية مختلفة تورث من الكلاس الأساسي Animal وتنفذ طريقة speak بطريقة مختلفة:
class Cat(Animal):
def speak(self):
return "Meow"
class Dog(Animal):
def speak(self):
return "Woof"
وبإمكاننا استخدام هذه الكلاسات في الشفرة بالطريقة التالية:
cat = Cat("Fluffy")
dog = Dog("Buddy")
print(cat.speak()) # Output: "Meow"
print(dog.speak()) # Output: "Woof"
هذا هو مبدأ التعدد في الأشكال مع الوراثة، حيث يتم تنفيذ نفس الطريقة باستخدام أشكال مختلفة.
تطبيق مبدأ تعدد الأشكال مع المصفوفات
تطبيق مبدأ تعدد الأشكال أو polymorphism يتيح للمبرمجين إنشاء وظائف وكائنات قادرة على التعامل مع أنواع بيانات مختلفة. يمكن تحقيق هذا في بايثون باستخدام المصفوفات.
فيما يلي مثال على تطبيق مبدأ تعدد الأشكال مع المصفوفات:
class Shape:
def area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Triangle(Shape):
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
return 0.5 * self.base * self.height
shapes = [Rectangle(3, 4), Triangle(2, 5)]
for shape in shapes:
print(shape.area())
في هذا المثال، تم إنشاء فئة Shape التي تحتوي على وظيفة area() التي سيتم استخدامها في الفئات المشتقة منها. ثم تم إنشاء فئات Rectangle و Triangle، حيث تم تعريف وظيفة area() بشكل مختلف في كل فئة.
وأخيرًا، تم إنشاء قائمة shapes تحتوي على كائنات Rectangle و Triangle وتم استدعاء وظيفة area() لكل كائن في القائمة باستخدام حلقة for. هذا يظهر كيف يمكن استخدام المصفوفات لتطبيق مبدأ تعدد الأشكال.