Aggiornamento di una variabile statica durante l'estensione di una classe Python
-
21-12-2019 - |
Domanda
Sto scrivendo un'estensione per una libreria e vorrei registrare la mia nuova funzione con un dizionario di puntatori a funzione nella classe base.La mia comprensione è che il dizionario, poiché si trova nell'ambito più alto all'interno di una classe, è statico e dovrebbe essere aggiornabile.Tuttavia, quando ci provo update()
il dizionario con la nuova funzione nella classe estesa mi dice che è indefinita.Il seguente esempio minimo riproduce l'errore:
def somefunction1(v):
return v
def somefunction2(v):
return v
class SomeClass(object):
dictionary = {'a':somefunction1}
class SomeExtensionClass(SomeClass):
dictionary.update({'b':somefunction2})
Eseguendolo restituisce il seguente errore
9
10 class SomeExtensionClass(SomeClass):
---> 11 dictionary.update({'b':somefunction2})
NameError: name 'dictionary' is not defined
Dal momento che non posso (ragionevolmente) modificare l'originale SomeClass
C'è un modo per aggirare questo?
Modificare:Il risultato desiderato è quello SomeExtensionClass
avrà dictionary={'a':somefunction1, 'b':somefunction2}
Soluzione
Se vuoi modificare SomeClass.dictionary
, chiamalo semplicemente come SomeClass.dictionary
:
SomeClass.dictionary.update(whatever)
Ricerca variabile all'interno di a class
l'istruzione non esamina gli attributi delle superclassi.
Se vuoi un nuovo dizionario, così SomeExtensionClass.dictionary
è diverso da SomeClass.dictionary
, ti consigliamo di copiare l'originale e aggiornare la copia:
class SomeExtensionClass(SomeClass):
dictionary = SomeClass.dictionary.copy()
dictionary.update(whatever)
Altri suggerimenti
Esistono due modi ragionevoli per fornire a SomeExtensionClass un dizionario aggiornato:
- Aggiorna il dizionario originale facendo riferimento a
SomeClass.dictionary
. - Definire un secondo
dictionary
variabile per la classe derivata.
Puoi fare il secondo in questo modo:
class SomeExtensionClass(SomeClass):
dictionary = dict(SomeClass.dictionary, b=somefunction2)
Quale dovresti scegliere dipende da chi usa il dizionario e per cosa.Se un metodo SomeClass utilizza la variabile in questo modo:
def foo(self):
a = self.dictionary['a']()
Il metodo utilizzerà il dizionario SomeExtensionClass per gli oggetti SomeExtensionClass.Se OTOH lo fa:
def foo(self):
a = SomeClass.dictionary['a']()
Utilizzerà sempre il dizionario definito in SomeClass.