Запуск работы super() в Python urllib2.Request
-
20-09-2019 - |
Вопрос
Сегодня днём я потратил несколько часов, пытаясь найти ошибку в моём расширении для urllib2.Request
.Проблема заключалась, как я выяснил, в использовании super(ExtendedRequest, self)
, с urllib2.Request
(я использую 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()
.)
Редактировать: Кстати:AttributeError упомянул:
>>> 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/ Например.
Эта ссылка показывает (среди прочего), что
- Суперклассы должны использовать super, если их подклассы это делают.
- А
__init__
сигнатуры всех подклассов, использующих super, должны совпадать.Вы должны передать все полученные аргументы суперфункции.Твой__init__
должен быть готов позвонить в любой другой класс__init__
метод в иерархии. - Никогда не используйте позиционные аргументы в
__init__
В вашей ситуации нарушен каждый из вышеперечисленных критериев.
Джеймс Найт также говорит:
Единственная ситуация, в которой Super () может быть полезна, - это когда у вас бриллиантовое наследство.И даже тогда это часто не так полезно, как вы могли подумать.
Условия, при которых супер можно правильно использовать, настолько обременительны, что я думаю, что полезность супера довольно ограничена.Отдавайте предпочтение шаблону проектирования «Композиция», а не подклассам.Если можете, избегайте наследования алмазов.Если вы контролируете иерархию объектов сверху (объект) вниз и используете суперпоследовательно, то все в порядке.Но поскольку в этом случае вы не контролируете всю иерархию классов, я бы посоветовал вам отказаться от использования super
.
Я думаю, вы пропустили передачу параметра self в определение в этом в вашем образце.Попробуй это:
class ExtendedRequest(object, urllib2.Request):
def __init__(self):
super(ExtendedRequest, self).__init__(self)
Я протестировал его, и он, кажется, работает нормально:
>>> x = ExtendedRequest()
>>> super(ExtendedRequest, x)
<super: <class 'ExtendedRequest'>, <ExtendedRequest object>>