Frage

An diesem Nachmittag verbrachte ich mehrere Stunden versucht, einen Fehler in meiner benutzerdefinierten Erweiterung urllib2.Request zu finden. Das Problem war, wie ich herausgefunden hat, die Verwendung von super(ExtendedRequest, self), da urllib2.Request ist (ich bin auf Python 2.5) noch im alten Stil Klasse, wo die Verwendung von super() nicht möglich.

Die naheliegendste Möglichkeit, eine neue Klasse mit beiden Funktionen zum Erstellen,

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

funktioniert nicht. Nenne es, ich bin mit AttributeError: type von urllib2.Request.__getattr__() angehoben links. Nun, bevor ich anfangen und copy'n die ganze urllib2.Request Klasse einfügen von / usr / lib / python nur zu umschreiben es als

class Request(object):

hat jemand eine Idee, wie ich das in einer elegantere Art und Weise erreichen könnte? (Mit das ist einen haben, new-style Klasse basierend auf urllib2.Request mit Arbeitsunterstützung für super().)

Edit: Übrigens: die Attribute erwähnt:

>>> 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
War es hilfreich?

Lösung

Das sollte funktionieren, da die Hierarchie einfach

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

Andere Tipps

Super verwendet, kann nicht immer die beste Praxis. Es gibt viele Schwierigkeiten mit Super verwenden. Lesen James Knight http://fuhm.org/super-harmful/ Beispiele.

Dieser Zusammenhang zeigt (unter anderem Fragen), die

  1. Superklassen muss Super verwenden, wenn ihre Subklassen tun
  2. Die __init__ Unterschriften aller Subklassen, dass die Verwendung Super sollten übereinstimmen. Sie müssen alle Argumente übergeben Sie auf der Super-Funktion erhalten. Ihre __init__ muss jede andere Klasse __init__ Methode in der Hierarchie nennen hergestellt werden.
  3. Verwenden Sie niemals Positionsargumente in __init__

In Ihrer Situation, jede der oben genannten critera verletzt wird.

James Ritter auch sagt,

  

Die einzige Situation, in der super ()   tatsächlich kann hilfreich sein, wenn Sie   haben Diamant Vererbung. Und sogar   dann ist es oft nicht so hilfreich wie   Sie vielleicht gedacht haben.

Die Bedingungen, unter denen Super korrekt verwendet werden können, sind streng genug, dass ich denke, Super Nützlichkeit ist eher begrenzt. Ziehe die Zusammensetzung Entwurfsmuster über Subklassen. Vermeiden Sie Diamant Vererbung, wenn Sie können. Wenn Sie die Objekthierarchie von oben (Objekt) nach unten zu steuern, und verwenden Sie Super konsequent, dann bist du in Ordnung. Aber da Sie keine Kontrolle über die gesamte Klassenhierarchie in diesem Fall würde ich vorschlagen, Sie verlassen super verwenden.

Ich glaube, du verpasst die Selbst Parameter Definition von passieren init in Ihrer Probe. Versuchen Sie dieses:

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

Ich habe es getestet und es scheint zu funktionieren okey:

>>> x = ExtendedRequest()
>>> super(ExtendedRequest, x)
<super: <class 'ExtendedRequest'>, <ExtendedRequest object>>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top