self.__class__
è un riferimento al tipo dell'istanza corrente.
Per le istanze di abstract1
, che sarebbe il abstract1
classe sé, che è quello che non si vuole con una classe astratta. classi astratte sono solo scopo di essere sottoclasse, non creare istanze direttamente:
>>> abstract1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
NotImplementedError: Interfaces can't be instantiated
Per un esempio di un sottoclasse di abstract1
, self.__class__
sarebbe un riferimento alla sottoclasse specifica:
>>> class Foo(abstract1): pass
...
>>> f = Foo()
>>> f.__class__
<class '__main__.Foo'>
>>> f.__class__ is Foo
True
Lanciare un'eccezione qui è come usare un'istruzione assert
altrove nel codice, che ti protegge da errori stupidi.
noti che il pythonic modo per verificare il tipo di un'istanza è utilizzare il type()
function invece, insieme ad un prova identità con la is
esercente:
class abstract1(object):
def __init__(self):
if type(self) is abstract1:
raise NotImplementedError("Interfaces can't be instantiated")
C'è poco senso utilizzando un test di uguaglianza qui come per le classi personalizzate, lo __eq__
è praticamente implementato comunque come test di identità.
Python include anche una libreria standard per definire le classi di base astratte, chiamate abc
. Ti consente di contrassegnare metodi e proprietà come astratti e rifiuterà di creare istanze di qualsiasi sottoclasse che non abbia ancora ridefinito quei nomi.
fonte
2013-12-19 17:52:50
Penso che questo richieda più contesto. Dove hai "trovato" questo codice? È fondamentalmente rotto. – Iguananaut
@Iguananaut: Perché è rotto? Funziona bene * se usato come previsto; come una classe base astratta. –
Sono abbastanza sicuro prima era qualcosa di diverso? Non lo so - sono d'accordo, quello che c'è ora non è rotto. – Iguananaut