Herstellung von super () Arbeit in Python urllib2.Request
-
20-09-2019 - |
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
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
- Superklassen muss Super verwenden, wenn ihre Subklassen tun
- 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. - 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>>