python - مكتبة - الفرق بين الطبقة المجردة والواجهة في بايثون




مكتبة اكواد بايثون (4)

ما الفرق بين الطبقة المجردة والواجهة في بايثون؟

واجهة ، لكائن ، هي مجموعة من الأساليب والسمات على هذا الكائن.

في بايثون ، يمكننا استخدام فئة أساسية مجردة لتعريف وتطبيق الواجهة.

استخدام فئة أساسية Abstract

على سبيل المثال ، لنفترض أننا نريد استخدام إحدى الفئات الأساسية التجريبية من وحدة collections :

import collections
class MySet(collections.Set):
    pass

إذا حاولنا استخدامها ، نحصل على TypeError لأن الفئة التي أنشأناها لا تدعم السلوك المتوقع للمجموعات:

>>> MySet()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MySet with abstract methods
__contains__, __iter__, __len__

لذلك نحن مطالبون بتنفيذ ما لا يقل عن __contains__ ، __iter__ ، و __len__ . لنستخدم مثال التنفيذ هذا من documentation :

class ListBasedSet(collections.Set):
    """Alternate set implementation favoring space over speed
    and not requiring the set elements to be hashable. 
    """
    def __init__(self, iterable):
        self.elements = lst = []
        for value in iterable:
            if value not in lst:
                lst.append(value)
    def __iter__(self):
        return iter(self.elements)
    def __contains__(self, value):
        return value in self.elements
    def __len__(self):
        return len(self.elements)

s1 = ListBasedSet('abcdef')
s2 = ListBasedSet('defghi')
overlap = s1 & s2

التنفيذ: إنشاء فئة أساسية مجردة

يمكننا إنشاء فئة الأساس التجريدي الخاص بنا عن طريق تعيين metaclass إلى abc.ABCMeta واستخدام الديكور abc.abstractmethod على الطرق ذات الصلة. سيتم إضافة metaclass الدالات المزين إلى سمة __abstractmethods__ ، منع إنشاء مثيل حتى يتم تعريفها.

import abc

على سبيل المثال ، يتم تعريف "effable" على أنه شيء يمكن التعبير عنه بالكلمات. لنقل أننا أردنا تحديد فئة أساسية مجردة قابلة للتنفيذ ، في Python 2:

class Effable(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def __str__(self):
        raise NotImplementedError('users must define __str__ to use this base class')

أو في Python 3 ، مع التغيير الطفيف في تعريف metaclass:

class Effable(object, metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def __str__(self):
        raise NotImplementedError('users must define __str__ to use this base class')

الآن إذا حاولنا إنشاء كائن قابل للبث بدون تنفيذ الواجهة:

class MyEffable(Effable): 
    pass

ومحاولة لتأكيد ذلك:

>>> MyEffable()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MyEffable with abstract methods __str__

قيل لنا أننا لم ننتهي من العمل.

الآن إذا امتثلنا من خلال توفير الواجهة المتوقعة:

class MyEffable(Effable): 
    def __str__(self):
        return 'expressable!'

يمكننا بعد ذلك استخدام النسخة الملموسة من الطبقة المستمدة من النسخة المجردة:

>>> me = MyEffable()
>>> print(me)
expressable!

هناك أشياء أخرى يمكننا القيام بها مع هذا ، مثل تسجيل الفئات الفرعية الافتراضية التي تقوم بالفعل بتطبيق هذه الواجهات ، ولكن أعتقد أن هذا يتجاوز نطاق هذا السؤال. أما الطرق الأخرى الموضحة هنا ، فيجب أن تكيف هذه الطريقة باستخدام وحدة abc للقيام بذلك.

استنتاج

لقد أثبتنا أن إنشاء فئة أساسية Abstract يُعرّف واجهات للكائنات المخصصة في Python.

ما الفرق بين الطبقة المجردة والواجهة في بايثون؟


Python> = 2.6 يحتوي على فئات أساسية Abstract .

تستكمل الطبقات الأساسية المجردة (ABC المختصرة) كتابة البطة من خلال توفير طريقة لتعريف الواجهات عندما تكون التقنيات الأخرى مثل hasattr () خرقاء. تأتي Python مع العديد من ABCs المبنية لهياكل البيانات (في وحدة المجموعات) ، والأرقام (في وحدة الأرقام) ، والجداول (في وحدة io). يمكنك إنشاء ABC الخاص بك باستخدام وحدة abc.

هناك أيضا وحدة Zope Interface ، التي تستخدمها المشاريع خارج نطاق zope ، مثل الملتوية. أنا لست على دراية به ، ولكن هناك صفحة wiki here قد تساعد.

بشكل عام ، أنت لا تحتاج إلى مفهوم الطبقات المجردة ، أو واجهات في python (تحرير - انظر الإجابة S.Lott للحصول على التفاصيل).


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

تميل اللغات التي تدعم نموذج الوراثة المتعددة إلى استخدام فئات فقط أو فئات أساسية مجردة وليست واجهات. نظرًا لأن Python يدعم الوراثة المتعددة ، فإنه لا يستخدم الواجهات وكنت تريد استخدام فئات أساسية أو فئات أساسية مجردة.

http://docs.python.org/library/abc.html


في طريقة أكثر أساسية لشرح: الواجهة هي بمثابة وعاء مافن فارغ. إنه ملف فئة مع مجموعة من تعريفات الطرق التي لا تحتوي على تعليمات برمجية.

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

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





abstract-class