سؤال

بعد ظهر هذا اليوم ، قضيت عدة ساعات في محاولة للعثور على خطأ في امتداد مخصص إلى urllib2.Request. كانت المشكلة ، كما اكتشفت ، استخدام super(ExtendedRequest, self), ، حيث urllib2.Request IS (أنا على Python 2.5) لا يزال فئة نمط قديمة ، حيث استخدام super() غير ممكن.

الطريقة الأكثر وضوحا لإنشاء فئة جديدة مع كلتا الميزتين ،

class ExtendedRequest(object, urllib2.Request):
    def __init__():
        super(ExtendedRequest, self).__init__(...)

لا يعمل. أسميها ، لقد تركت مع AttributeError: type أرتفع بواسطة urllib2.Request.__getattr__(). الآن ، قبل أن أبدأ ونسخ اللصق الكل urllib2.Request الفصل من/usr/lib/python فقط لإعادة كتابته

class Request(object):

هل كان أي شخص فكرة ، كيف يمكنني تحقيق ذلك بطريقة أكثر أناقة؟ (مع هذه أن يكون لديك أسلوب جديد الفصل على أساس urllib2.Request مع دعم العمل ل super().)

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

>>> class ExtendedRequest(object, urllib2.Request):
...   def __init__(self):
...     super(ExtendedRequest, self).__init__('http://stackoverflow.com')
...
>>> ABC = ExtendedRequest ()
>>> d = urllib2.urlopen(ABC)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/urllib2.py", line 124, in urlopen
    return _opener.open(url, data)
  File "/usr/lib/python2.5/urllib2.py", line 373, in open
    protocol = req.get_type()
  File "/usr/lib/python2.5/urllib2.py", line 241, in get_type
    if self.type is None:
  File "/usr/lib/python2.5/urllib2.py", line 218, in __getattr__
    raise AttributeError, attr
AttributeError: type
هل كانت مفيدة؟

المحلول

هذا يجب أن يعمل بشكل جيد لأن التسلسل الهرمي بسيط

class ExtendedRequest(urllib2.Request):
    def __init__(self,...):
        urllib2.Request.__init__(self,...)

نصائح أخرى

قد لا يكون استخدام Super دائمًا أفضل ممارسة. هناك العديد من الصعوبات في استخدام Super. اقرأ جيمس نايت http://fuhm.org/super-harmful/ للحصول على أمثلة.

يظهر هذا الرابط (من بين قضايا أخرى) ذلك

  1. يجب أن تستخدم الفئات الفائقة سوبر إذا كانت فئاتهم الفرعية
  2. ال __init__ يجب أن تتطابق توقيعات جميع الفئات الفرعية التي تستخدم سوبر. يجب عليك تمرير جميع الوسائط التي تتلقاها إلى الوظيفة الفائقة. لك __init__ يجب أن تكون مستعدًا لاستدعاء أي فئة أخرى __init__ الطريقة في التسلسل الهرمي.
  3. لا تستخدم الحجج الموضعية في __init__

في وضعك ، يتم انتهاك كل من Critera أعلاه.

يقول جيمس نايت أيضًا ،

الموقف الوحيد الذي يمكن أن يكون فيه Super () مفيدًا في الواقع هو عندما يكون لديك ميراث الماس. وحتى ذلك الحين ، غالبًا ما لا يكون مفيدًا كما كنت تعتقد.

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

أعتقد أنك فاتتك تمرير المعلمة الذاتية إلى تعريف فيه في العينة. جرب هذه:

class ExtendedRequest(object, urllib2.Request):
    def __init__(self):
        super(ExtendedRequest, self).__init__(self)

لقد اختبرته ويبدو أنه يعمل أوكي:

>>> x = ExtendedRequest()
>>> super(ExtendedRequest, x)
<super: <class 'ExtendedRequest'>, <ExtendedRequest object>>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top