Prendiamo il seguente esempio minimale:“Impossibile un'istanza di classe astratta ... con metodi astratti” a classe che non dovrebbe avere alcun metodo astratto
import abc
class FooClass(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def FooMethod(self):
raise NotImplementedError()
def main():
derived_type = type('Derived', (FooClass,), {})
def BarOverride(self):
print 'Hello, world!'
derived_type.FooMethod = BarOverride
instance = derived_type()
esecuzione main()
si ottiene:
TypeError: Can't instantiate abstract class Derived with abstract methods FooMethod
(L'eccezione si verifica sulla riga instance = derived_type()
.)
Ma FooMethod
non deve essere astratto: l'ho sovrascritto con BarOverride
. Quindi, perché questo fa sorgere eccezioni?
Disclaimer: Sì, potrei usare la sintassi esplicita class
e realizzare esattamente la stessa cosa. (E ancora meglio, posso farlo funzionare!) Ma questo è un caso di test minimale, e l'esempio più ampio è la creazione dinamica di classi. :-) E sono curioso di sapere perché questo non funziona.
Edit: E per evitare che l'altra ovvia non-risposta: io non voglio passare BarOverride
nel terzo argomento di type
: Nell'esempio vera, BarOverride
ha bisogno di avere derived_type
legato ad esso. È più semplice farlo se riesco a definire BarOverride
dopo la creazione di derived_type
. (Se non riesco a fare questo, allora perché?)
L'astrattezza di una classe è determinata durante la costruzione di classe . Perché non inserisci semplicemente 'FooMethod' nel dizionario mentre crei la classe? –
@SvenMarnach: 'BarOverride', nell'esempio reale, deve avere la classe derivata vincolata ad esso. Creare la funzione in seguito è il modo più semplice per farlo. – Thanatos
Non capisco quel punto. Cosa intendi per "necessità di avere la classe derivata vincolata ad esso"? –