جعل العمل Super () في Python Urllib2.request
-
20-09-2019 - |
سؤال
بعد ظهر هذا اليوم ، قضيت عدة ساعات في محاولة للعثور على خطأ في امتداد مخصص إلى 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/ للحصول على أمثلة.
يظهر هذا الرابط (من بين قضايا أخرى) ذلك
- يجب أن تستخدم الفئات الفائقة سوبر إذا كانت فئاتهم الفرعية
- ال
__init__
يجب أن تتطابق توقيعات جميع الفئات الفرعية التي تستخدم سوبر. يجب عليك تمرير جميع الوسائط التي تتلقاها إلى الوظيفة الفائقة. لك__init__
يجب أن تكون مستعدًا لاستدعاء أي فئة أخرى__init__
الطريقة في التسلسل الهرمي. - لا تستخدم الحجج الموضعية في
__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>>