使用super()在Python的urllib2.Request中工作

时间:2010-02-15 15:43:11

标签: python request urllib2 super new-style-class

今天下午我花了几个小时试图在urllib2.Request的自定义扩展程序中找到错误。问题是,正如我发现的那样,使用super(ExtendedRequest, self),因为urllib2.Request(我在Python 2.5上)仍然是一个旧样式类,其中super()的使用不是可能的。

使用这两个功能创建新类的最明显方法

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

不起作用。打电话给我,AttributeError: typeurllib2.Request.__getattr__()提出。现在,在我开始并复制'粘贴/ usr / lib / python中的整个urllib2.Request类之前,只需将其重写为

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

3 个答案:

答案 0 :(得分:1)

这应该可以正常工作,因为层次结构很简单

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

答案 1 :(得分:1)

使用super可能并不总是最好的做法。使用超级有很多困难。阅读James Knight的http://fuhm.org/super-harmful/作为例子。

该链接显示(以及其他问题)

  1. 超类必须使用super,如果它们的子类有
  2. 使用super的所有子类的__init__个签名应该匹配。您必须将收到的所有参数传递给super函数。您的__init__必须准备好调用层次结构中任何其他类的__init__方法。
  3. 永远不要在__init__中使用位置参数

在您的情况下,违反了上述每个标准。

詹姆斯奈特也说,

  

super()的唯一情况   实际上可以帮到你的时候   有钻石继承。乃至   然后,它往往没有那么有用   你可能已经想到了。

超级正确使用的条件非常繁重,我认为超级的实用性相当有限。首选组合设计模式而不是子类化。如果可以的话,避免钻石继承。如果您控制从顶部(对象)到底部的对象层次结构,并使用超级一致,那么您没关系。但是,由于在这种情况下您不控制整个类层次结构,我建议您放弃使用super

答案 2 :(得分:0)

我认为您错过了将self参数传递给示例中 init 的定义。 试试这个:

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

我测试过它似乎工作得很好:

>>> x = ExtendedRequest()
>>> super(ExtendedRequest, x)
<super: <class 'ExtendedRequest'>, <ExtendedRequest object>>