使super()在Python中工作';s urllib2.请求

使super()在Python中工作';s urllib2.请求,python,request,urllib2,super,new-style-class,Python,Request,Urllib2,Super,New Style Class,今天下午,我花了几个小时试图在我的自定义扩展名urllib2.Request中找到一个bug。问题是,正如我发现的那样,super(ExtendedRequest,self)的使用,因为urllib2.Request仍然是一个旧式的类(我使用的是Python 2.5),不可能使用super() 创建具有这两个特性的新类的最明显的方法 class ExtendedRequest(object, urllib2.Request): def __init__(): super(

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

创建具有这两个特性的新类的最明显的方法

class ExtendedRequest(object, urllib2.Request):
    def __init__():
        super(ExtendedRequest, self).__init__(...)
不起作用。调用它时,剩下的是
AttributeError:type
urlib2.Request。现在,在开始复制之前,请从/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
>类扩展请求(对象,urllib2.Request):
...   定义初始化(自):
...     super(扩展请求,self)。\uuuu init\uuuuuhttp://stackoverflow.com')
...
>>>ABC=扩展请求()
>>>d=urllib2.urlopen(ABC)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
urlopen中的文件“/usr/lib/python2.5/urllib2.py”,第124行
return\u opener.open(url、数据)
文件“/usr/lib/python2.5/urllib2.py”,第373行,打开
协议=请求获取类型()
文件“/usr/lib/python2.5/urllib2.py”,第241行,get_类型
如果self.type为无:
文件“/usr/lib/python2.5/urllib2.py”,第218行,在__
提升属性错误,属性错误
AttributeError:类型

由于层次结构很简单,这应该可以很好地工作

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

我认为您没有在示例中将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>>
>x=ExtendedRequest()
>>>超级(扩展请求,x)

使用super可能并不总是最佳做法。使用超级计算机有很多困难。阅读詹姆斯·奈特的书中的例子

这一联系(除其他问题外)表明

  • 如果子类使用super,则超类必须使用super
  • 使用super的所有子类的
    \uuuuu init\uuuu
    签名应该匹配。必须将收到的所有参数传递给超级函数。您的
    \uuuuu init\uuuu
    必须准备好调用层次结构中任何其他类的
    \uuuuuuu init\uuu
    方法。
  • 切勿在
    中使用位置参数
    

    在您的情况下,违反了上述每一条标准

    詹姆斯·奈特还说

    super()的唯一情况 当你 拥有钻石遗产。甚至 然后,它通常没有那么有用 你可能会想


    正确使用super的条件非常苛刻,因此我认为super的实用性相当有限。与子类化相比,更喜欢组合设计模式。尽可能避免钻石继承。如果您从上(对象)到下控制对象层次结构,并超级一致地使用,那么您就可以了。但是,由于在这种情况下您不能控制整个类层次结构,我建议您放弃使用
    super

    谢谢您的回答,但我知道这一点。事实上,我现在正在做这件事。但是,我想在某些方面利用super()的强大功能,比如多重继承。整个层次结构必须是新的样式,才能使
    super
    正常工作是的,很遗憾urllib2没有使用newstyle类。我想知道他们为什么这么做是的,但是当你试图调用
    对象上的任何方法时,它会引发AttributeError。与此同时,我浏览了右栏中的一些相关问题,也找到了James Knight的文章。尽管我仍然认为
    super()
    是一个强大的工具,但我开始意识到它的缺点。感谢您详细指出!