Rendere il lavoro super () in Python urllib2.Request
-
20-09-2019 - |
Domanda
Oggi pomeriggio ho trascorso diverse ore cercando di trovare un bug nel mio un'estensione personalizzata per urllib2.Request
. Il problema era, come ho scoperto, l'utilizzo di super(ExtendedRequest, self)
, dal momento che urllib2.Request
è (sono in Python 2.5) ancora un vecchio stile di classe, dove l'uso di super()
non è possibile.
Il modo più ovvio per creare una nuova classe con entrambe le caratteristiche,
class ExtendedRequest(object, urllib2.Request):
def __init__():
super(ExtendedRequest, self).__init__(...)
non funziona. Chiamarlo, io sono rimasto con AttributeError: type
sollevata da urllib2.Request.__getattr__()
. Ora, prima di iniziare e copy'n incollare l'intera classe urllib2.Request
da / usr / lib / python solo per riscriverlo come
class Request(object):
qualcuno ha un'idea, come avrei potuto raggiungere questo obiettivo in un modo più elegante? (Con questo è quello di avere una new-style di classe sulla base di urllib2.Request
con il supporto di lavoro per super()
.)
Modifica A proposito: l'AttributeError citato:
>>> 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
Soluzione
Questo dovrebbe funzionare bene dal momento che la gerarchia è semplice
class ExtendedRequest(urllib2.Request):
def __init__(self,...):
urllib2.Request.__init__(self,...)
Altri suggerimenti
con Super non può essere sempre il best-practice. Ci sono molte difficoltà con l'utilizzo di Super. Leggi http://fuhm.org/super-harmful/ per gli esempi.
che puntano spettacoli (tra l'altro) che
- superclassi deve usare eccellente se i loro sottoclassi fanno
- Le firme
__init__
di tutte le sottoclassi che utilizzano Super devono corrispondere. Si deve passare tutti gli argomenti che si ricevono al super funzione. Il tuo__init__
deve essere pronto a chiamare il metodo__init__
di qualsiasi altra classe nella gerarchia. - Non usare mai argomenti posizionali in
__init__
Nella tua situazione, ciascuno dei critera sopra è violata.
James Cavaliere dice anche,
L'unica situazione in cui super () può effettivamente essere utile è quando si hanno ereditarietà diamante. E persino poi, spesso non è così utile come si potrebbe avere pensato.
Le condizioni alle quali Super può essere utilizzato in modo corretto sono sufficientemente oneroso, che penso che l'utilità Super è piuttosto limitata. Preferisco il modello di progettazione Composizione su sottoclassi. Evitare l'eredità di diamante, se potete. Se controlli la gerarchia di oggetti dall'alto (oggetto) al basso, e utilizzare Super coerente, allora sei a posto. Ma dal momento che non si controlla l'intera gerarchia di classe, in questo caso, io suggerisco di abbandonare utilizzando super
.
Credo che vi siete persi per passare il parametro sé la definizione di init nel campione. Provate questo:
class ExtendedRequest(object, urllib2.Request):
def __init__(self):
super(ExtendedRequest, self).__init__(self)
L'ho provato e sembra funzionare okey:
>>> x = ExtendedRequest()
>>> super(ExtendedRequest, x)
<super: <class 'ExtendedRequest'>, <ExtendedRequest object>>