سؤال

أرغب في إنشاء مجموعة مخصصة تقوم تلقائيًا بتحويل الكائنات إلى نموذج مختلف للتخزين في المجموعة (انظر استخدام قاموس بايثون كمفتاح غير متداخل) للخلفية.

إذا تجاوزت add, remove, __contains__, __str__, update, __iter__, هل سيكون ذلك كافيًا لجعل العمليات الأخرى تعمل بشكل صحيح، أم هل أحتاج إلى تجاوز أي شيء آخر؟

هل كانت مفيدة؟

المحلول

العمل من collectionsفئات مجردة ، كما يقترح @ kaizer.se، هي الحل المناسب في 2.6 (لست متأكدًا من سبب رغبتك في الاتصال بـ super - ما هي الوظيفة التي تحاول تفويضها والتي لا يمكن القيام بها بشكل أفضل عن طريق الاحتواء بدلاً من الميراث؟!) .

صحيح أنك لا تحصل عليه update - من خلال توفير الأساليب المجردة، يمكنك الحصول على __le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__ __sub__, __xor__, and isdisjoint (من collections.Set) زائد clear, pop, remove, __ior__, __iand__, __ixor__, and __isub__ (من collections.MutableSet)، وهو أكثر بكثير مما ستحصل عليه من الفئات الفرعية set (حيث يتعين عليك تجاوز كل طريقة الفائدة).سيكون عليك فقط توفير طرق المجموعة الأخرى التي تريدها.

لاحظ أن الفئات الأساسية المجردة تحب collections.Set هي وحش مختلف تمامًا عن الطبقات الخرسانية، بما في ذلك الإضافات المدمجة مثل set و(في 2.6) جيد قديم sets.Set, ، مهمل ولكنه لا يزال موجودًا (تمت إزالته في Python 3).من المفترض أن ترث الحروف الأبجدية من (ويمكنها بعد ذلك تجميع بعض الأساليب منك بمجرد تنفيذ جميع الأساليب المجردة، كما يجب عليك) و"تسجيل" الفئات بشكل ثانوي بحيث تبدو كما لو أنها ورثت منها حتى عندما لا تفعل ذلك. (ليصنع isinstance أكثر فائدة ومفيدة).

فيما يلي مثال عملي لـ Python 3.1 و2.6 (لا يوجد سبب وجيه لاستخدام 3.0، حيث أن 3.1 له مزايا فقط، وليس له أي عيوب):

import collections

class LowercasingSet(collections.MutableSet):
  def __init__(self, initvalue=()):
    self._theset = set()
    for x in initvalue: self.add(x)
  def add(self, item):
    self._theset.add(item.lower())
  def discard(self, item):
    self._theset.discard(item.lower())
  def __iter__(self):
    return iter(self._theset)
  def __len__(self):
    return len(self._theset)
  def __contains__(self, item):
    try:
      return item.lower() in self._theset
    except AttributeError:
      return False

نصائح أخرى

في بيثون 2.6:

import collections
print collections.MutableSet.__abstractmethods__
# prints:
# frozenset(['discard', 'add', '__iter__', '__len__', '__contains__'])

وcollections.MutableSet فرعية وتجاوز الأساليب في القائمة أعلاه.

وطريقة التحديث نفسه من السهل جدا، بالنظر إلى أن الحد الأدنى أعلاه تنفيذ

def update(self, iterable):
    for x in iterable:
        self.add(x)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top