6

Questo è in riferimento alla risposta per this question a "Utilizzare il modulo abc di python per creare classi astratte". (by @alexvassel e accettato come risposta).In grado di istanziare la classe python, nonostante sia astratta (usando abc)

Ho provato i suggerimenti, ma stranamente, nonostante i suggerimenti per utilizzare il modo abc, non funziona per me. Quindi Vi metto come una domanda qui:

Ecco il mio codice Python:

from abc import ABCMeta, abstractmethod 

class Abstract(object): 
    __metaclass__ = ABCMeta 

    @abstractmethod 
    def foo(self): 
     print("tst") 

a = Abstract() 
a.foo() 

Quando eseguo questo modulo, qui è l'uscita sulla mia console:

pydev debugger: starting (pid: 20388) 
tst 

in contrapposizione a quella risposta accettata

>>> TypeError: Can not instantiate abstract class Abstract with abstract methods foo 

Quindi cosa sto facendo giusto o sbagliato? Perché funziona e non fallisce? Apprezzare qualsiasi opinione di esperti in questo.

+0

ero in grado di rispondere alla tua domanda in modo chiaro? –

risposta

7

In Python 3 utilizza l'argomento metaclass quando si crea la classe base astratta:

from abc import ABCMeta, abstractmethod 

class Abstract(metaclass=ABCMeta): 

    @abstractmethod 
    def foo(self): 
     print("tst") 

a = Abstract() 
a.foo() 
+0

Capisco. Questa è un'ottima informazione da sapere. Funziona dopo aver modificato la definizione come suggerito. Grazie. – jark

4

In Python 2, è necessario assegnare il metaclasse così:

import abc 

class ABC(object): 

    __metaclass__ = abc.ABCMeta 

    @abc.abstractmethod 
    def foo(self): 
     return True 

a = ABC() 

che solleva un TypeError

Traceback (most recent call last): 
    File "<pyshell#59>", line 1, in <module> 
    a = ABC() 
TypeError: Can't instantiate abstract class ABC with abstract methods foo 

Ma in Python 3, assegnando __metaclass__ come attributo non funziona (come tu lo intendi, ma l'interprete non lo considera un errore, solo un normale attributo come qualsiasi altro, motivo per cui il codice precedente non genera un errore). Metaclassi sono ora definiti come un argomento di nome alla classe:

import abc 

class ABC(metaclass=abc.ABCMeta): 

    @abc.abstractmethod 
    def foo(self): 
     return True 

a = ABC() 

solleva la TypeError:

Traceback (most recent call last): 
    File "main.py", line 11, in 
    a = ABC() 
TypeError: Can't instantiate abstract class ABC with abstract methods foo 
+0

Grazie per la spiegazione dettagliata sul motivo per cui non genera un errore con Python 2. Vorrei farlo, senza lavorare silenziosamente come non intendevo :( – jark

+0

@jark Interessante hai scelto il codice di Vittoria, poiché non è valido per Python 3 e in realtà non dimostra quello che stavi cercando –

+0

Aaron Hall, grazie per il tuo feedback Ho accettato la risposta di Victory perché è stato il primo a venire e ho letto e provato e ha funzionato come mi aspettavo Non sono sicuro del motivo per cui stai dicendo che è "Invalido per Python 3"? Se confronto il codice che hai pubblicato nella tua soluzione su ciò che Victory ha pubblicato, entrambi usano esattamente la stessa logica. L'unica differenza è che hai usato "import abc" (ea sua volta usando il metodo abc.abstract ecc.) vs Victory usando "da abc import ABCMeta, abstractmethod" e usando abstractmethod ecc. Nulla di personale contro di te è per Victory, – jark