今天下午我花了几个小时试图在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__()
提出。现在,在我开始并复制'粘贴/ 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
答案 0 :(得分:1)
这应该可以正常工作,因为层次结构很简单
class ExtendedRequest(urllib2.Request):
def __init__(self,...):
urllib2.Request.__init__(self,...)
答案 1 :(得分:1)
使用super可能并不总是最好的做法。使用超级有很多困难。阅读James Knight的http://fuhm.org/super-harmful/作为例子。
该链接显示(以及其他问题)
__init__
个签名应该匹配。您必须将收到的所有参数传递给super函数。您的__init__
必须准备好调用层次结构中任何其他类的__init__
方法。
__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>>