"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > كتابة البطة تجتمع مع تلميحات النوع: استخدام البروتوكولات في بايثون

كتابة البطة تجتمع مع تلميحات النوع: استخدام البروتوكولات في بايثون

تم النشر بتاريخ 2024-09-04
تصفح:786

Duck Typing Meets Type Hints: Using Protocols in Python

لقد تم الإشادة منذ فترة طويلة بالطبيعة الديناميكية لـ Python ودعمها لكتابة البطة لمرونتها. ومع ذلك، مع نمو قواعد التعليمات البرمجية بشكل أكبر وأكثر تعقيدًا، أصبحت فوائد التحقق من النوع الثابت واضحة بشكل متزايد. ولكن كيف يمكننا التوفيق بين مرونة كتابة البطة وسلامة التحقق من النوع الثابت؟ أدخل فئة بروتوكول بايثون.

في هذا البرنامج التعليمي، ستتعلم:

  1. ما هي كتابة البطة وكيف يتم دعمها في بايثون
  2. إيجابيات وسلبيات كتابة البطة
  3. كيف تحاول الفئات الأساسية المجردة (ABCs) حل مشكلات الكتابة
  4. كيفية استخدام البروتوكول للحصول على أفضل ما في كلا العالمين: مرونة الكتابة البطية مع التحقق من النوع الثابت

فهم كتابة البط

كتابة البطة هي مفهوم برمجة حيث يكون نوع أو فئة الكائن أقل أهمية من الأساليب التي يحددها. إنها مبنية على فكرة أنه "إذا كانت تبدو مثل البطة، وتسبح مثل البطة، وتصدر صوتًا مثل البطة، فمن المحتمل أنها بطة."

في بايثون، كتابة البطة مدعومة بالكامل. على سبيل المثال:

class Duck:
    def quack(self):
        print("Quack!")

class Person:
    def quack(self):
        print("I'm imitating a duck!")

def make_it_quack(thing):  # Note: No type hint here
    thing.quack()

duck = Duck()
person = Person()

make_it_quack(duck)    # Output: Quack!
make_it_quack(person)  # Output: I'm imitating a duck!

في هذا المثال، لا يهتم make_it_quack بنوع الشيء. يهمه فقط أن هذا الشيء لديه طريقة الدجال. لاحظ أنه لا يوجد تلميح للنوع لمعلمة thing، وهو أمر نموذجي في التعليمات البرمجية المكتوبة على شكل بطة ولكنه قد يؤدي إلى مشكلات في قواعد التعليمات البرمجية الأكبر.

إيجابيات وسلبيات كتابة البط

توفر كتابة البطة العديد من المزايا:

  1. المرونة: تسمح بتعليمات برمجية أكثر مرونة وغير مرتبطة بأنواع محددة.
  2. إعادة استخدام التعليمات البرمجية بشكل أسهل: يمكنك استخدام الفئات الموجودة في سياقات جديدة دون تعديل.
  3. التركيز على السلوك: يركز على ما يمكن أن يفعله الكائن، بدلاً من التركيز على ما هو عليه.

ولكن له أيضًا بعض العيوب:

  1. عدم الوضوح: قد يكون من غير الواضح ما هي الأساليب التي يحتاج الكائن إلى تنفيذها.
  2. أخطاء وقت التشغيل: يتم اكتشاف الأخطاء المتعلقة بالنوع فقط في وقت التشغيل.
  3. دعم أقل لـ IDE: تكافح IDEs لتوفير الإكمال التلقائي الدقيق والتحقق من الأخطاء.

الحل ABC

أحد الأساليب لمعالجة هذه المشكلات هو استخدام الفئات الأساسية المجردة (ABCs). إليك مثال:

from abc import ABC, abstractmethod

class Quacker(ABC):
    @abstractmethod
    def quack(self):
        pass

class Duck(Quacker):
    def quack(self):
        print("Quack!")

class Person(Quacker):
    def quack(self):
        print("I'm imitating a duck!")

def make_it_quack(thing: Quacker):
    thing.quack()

duck = Duck()
person = Person()

make_it_quack(duck)
make_it_quack(person)

على الرغم من أن هذا الأسلوب يوفر فحصًا أفضل للنوع وواجهات أكثر وضوحًا، إلا أنه له عيوب:

  1. يتطلب الوراثة، مما قد يؤدي إلى تسلسلات هرمية غير مرنة.
  2. لا يعمل مع الفئات الموجودة التي لا يمكنك تعديلها.
  3. إنه يتعارض مع فلسفة بايثون "كتابة البطة".

البروتوكولات: أفضل ما في العالمين

قدم بايثون 3.8 فئة البروتوكول، والتي تسمح لنا بتعريف الواجهات دون الحاجة إلى الميراث. وإليك كيف يمكننا استخدامه:

from typing import Protocol

class Quacker(Protocol):
    def quack(self):...

class Duck:
    def quack(self):
        print("Quack!")

class Person:
    def quack(self):
        print("I'm imitating a duck!")

def make_it_quack(thing: Quacker):
    thing.quack()

duck = Duck()
person = Person()

make_it_quack(duck)
make_it_quack(person)

دعونا نقسم هذا:

  1. نحدد بروتوكول Quacker الذي يحدد الواجهة التي نتوقعها.
  2. لا تحتاج فئتا Duck وPerson لدينا إلى الوراثة من أي شيء.
  3. يمكننا استخدام تلميحات الكتابة مع make_it_quack لتحديد أنها تتوقع Quacker.

يمنحنا هذا النهج العديد من الفوائد:

  1. التحقق من النوع الثابت: يمكن لـ IDEs ومدققي النوع اكتشاف الأخطاء قبل وقت التشغيل.
  2. لا يشترط الميراث: تعمل الفصول الموجودة طالما أن لديها الأساليب الصحيحة.
  3. واجهات واضحة: يحدد البروتوكول بوضوح الطرق المتوقعة.

إليك مثال أكثر تعقيدًا يوضح كيف يمكن أن تكون البروتوكولات معقدة حسب الحاجة (الشكل)، مع الحفاظ على فئات المجال الخاص بك (دائرة، مستطيل) مسطحة:

from typing import Protocol, List

class Drawable(Protocol):
    def draw(self): ...

class Resizable(Protocol):
    def resize(self, factor: float): ...

class Shape(Drawable, Resizable, Protocol):
    pass

def process_shapes(shapes: List[Shape]):
    for shape in shapes:
        shape.draw()
        shape.resize(2.0)

# Example usage
class Circle:
    def draw(self):
        print("Drawing a circle")

    def resize(self, factor: float):
        print(f"Resizing circle by factor {factor}")

class Rectangle:
    def draw(self):
        print("Drawing a rectangle")

    def resize(self, factor: float):
        print(f"Resizing rectangle by factor {factor}")

# This works with any class that has draw and resize methods,
# regardless of its actual type or inheritance
shapes: List[Shape] = [Circle(), Rectangle()]
process_shapes(shapes)

في هذا المثال، لا ترث الدائرة والمستطيل من الشكل أو أي فئة أخرى. إنهم ببساطة ينفذون الأساليب المطلوبة (الرسم وتغيير الحجم). يمكن أن تعمل الدالةprocess_shapes مع أي كائنات تحتوي على هذه الطرق، وذلك بفضل بروتوكول الشكل.

ملخص

توفر البروتوكولات في Python طريقة قوية لجلب الكتابة الثابتة إلى التعليمات البرمجية المكتوبة على شكل بطة. إنها تسمح لنا بتحديد الواجهات في نظام الكتابة دون الحاجة إلى الوراثة، والحفاظ على مرونة الكتابة البطية مع إضافة فوائد التحقق من النوع الثابت،

باستخدام البروتوكولات، يمكنك:

  1. تحديد واجهات واضحة للكود الخاص بك
  2. احصل على بيئة تطوير متكاملة (IDE) أفضل، (التحقق من النوع الثابت)، والدعم واكتشف الأخطاء مبكرًا
  3. الحفاظ على مرونة كتابة البطة
  4. الاستفادة من التحقق من النوع للفئات التي لا تستطيع تعديلها.

إذا كنت تريد معرفة المزيد حول البروتوكولات وتلميحات الكتابة في Python، فراجع وثائق Python الرسمية في وحدة الكتابة، أو استكشف أدوات التحقق من النوع الثابت المتقدمة مثل mypy.

سعيد في البرمجة، وأتمنى أن يكون بطك دائمًا مجتهدًا في مجال سلامة الكتابة!

يمكنك العثور على المزيد من المحتوى الخاص بي، بما في ذلك رسالتي الإخبارية هنا

بيان الافراج تم إعادة إنتاج هذه المقالة على: https://dev.to/samkeen/duck-typing-meets-type-hints-using-protocols-in-python-4d8l?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3