2011-08-25 13 views
17

Ho letto docs pitone sulle classi base astratte:pitone @abstractmethod decoratore

Da here:

abc.abstractmethod(function) Un decoratore che indica metodi astratti.

L'utilizzo di questo decoratore richiede che il metaclass della classe sia ABCMeta o . Una classe che ha un metaclasse derivato da ABCMeta non può essere istanziata a meno che tutti i suoi metodi astratti e le proprietà non vengano sovrascritte.

E here

è possibile applicare il @abstractmethod decoratore a metodi come draw() che deve essere implementata; Python genererà quindi un'eccezione per le classi che non definiscono il metodo. Si noti che l'eccezione è solo generata quando si tenta effettivamente di creare un'istanza di una sottoclasse priva del metodo.

Ho usato questo codice per verificare che fuori:

import abc 

class AbstractClass(object): 
    __metaclass__ = abc.ABCMeta 

    @abc.abstractmethod 
    def abstractMethod(self): 
    return 

class ConcreteClass(AbstractClass): 
    def __init__(self): 
    self.me = "me" 

c = ConcreteClass() 
c.abstractMethod() 

Il codice va bene, quindi non capisco. Se scriv c.abstractMethod ottengo:

<bound method ConcreteClass.abstractMethod of <__main__.ConcreteClass object at 0x7f694da1c3d0>> 

Quello che mi manca qui? ConcreteClassdeve implementare i metodi astratti, ma non ottengo eccezione.

+2

Quale Python? Segnala l'errore bene per me. Inoltre, puoi sempre sollevare NotImplementedError invece di usare 'abc'. –

+0

Inserisco un commento sulla risposta mouad, il collegamento da 'python' è stato impostato come predefinito in' python3'. Ti ricorderò di sollevare l'eccezione, poiché scrivere codice portatile con le modifiche su Python sembra molto lontano dalla mia conoscenza di Python. – Sebastian

risposta

25

Stai usando python3 per eseguire quel codice? Se sì, dovresti sapere che dichiarando metaclasse in python 3 have changes dovresti farlo in questo modo:

import abc 

class AbstractClass(metaclass=abc.ABCMeta): 

    @abc.abstractmethod 
    def abstractMethod(self): 
     return 
+0

Grazie, sembra un enorme cambiamento tra le versioni (la mia distribuzione stava puntando 'python' per default come' python3'). Come scrivere per compatibilità con le versioni precedenti? Immagino che questa potrebbe essere un'altra domanda ... – Sebastian

+1

@Sebastian: 'python3' è stato progettato con una minore compatibilità con il suo precedente python2 (http://www.python.org/dev/peps/pep-3000/#compatibility-and -transition) ma per risolvere le incompatibilità a rovescio tra le due versioni dovresti usare lo script 2to3.py (http://docs.python.org/library/2to3.html). – mouad

+0

bello, ho provato. Posso continuare ad usare la sintassi '__metaclass__' e usare quello script per convertire la sintassi' python3'. Ha fatto solo quello che hai detto nell'esempio. Grazie. – Sebastian