1

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

创建具有这两个功能的新类的最明显方法,

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

不起作用。调用它,我留下了AttributeError: typeraise by urllib2.Request.__getattr__()。现在,在我开始并从 /usr/lib/python 复制整个urllib2.Request类之前,将其重写为

class Request(object):

有谁知道,我怎样才能以更优雅的方式实现这一目标?(是有一个基于工作支持的新型类。)urllib2.Requestsuper()

编辑:顺便说一句:提到的 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
4

3 回答 3

1

Using super may not always be the best-practice. There are many difficulties with using super. Read James Knight's http://fuhm.org/super-harmful/ for examples.

That link shows (among other issues) that

  1. Superclasses must use super if their subclasses do
  2. The __init__ signatures of all subclasses that use super should match. You must pass all arguments you receive on to the super function. Your __init__ must be prepared to call any other class's __init__ method in the hierarchy.
  3. Never use positional arguments in __init__

In your situation, each of the above critera is violated.

James Knight also says,

The only situation in which super() can actually be helpful is when you have diamond inheritance. And even then, it is often not as helpful as you might have thought.

The conditions under which super can be used correctly are sufficiently onerous, that I think super's usefulness is rather limited. Prefer the Composition design pattern over subclassing. Avoid diamond inheritance if you can. If you control the object hierarchy from top (object) to bottom, and use super consistently, then you are okay. But since you don't control the entire class hierarchy in this case, I'd suggest you abandon using super.

于 2010-02-15T20:46:37.823 回答
1

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

class ExtendedRequest(urllib2.Request):
    def __init__(self,...):
        urllib2.Request.__init__(self,...)
于 2010-02-15T15:46:41.647 回答
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>>
于 2010-02-15T15:50:07.690 回答