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
È stato utile?

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

  1. superclassi deve usare eccellente se i loro sottoclassi fanno
  2. 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.
  3. 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>>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top