Sto facendo un gioco di scacchi e volevo creare un'interfaccia/un protocollo standard. Python non ha quelli nella lingua, quindi cosa dovrei usare? Leggo un po 'di fabbrica, ma non sono sicuro di come potrebbero aiutare. Grazie in anticipo!Cosa usare in sostituzione di un'interfaccia/protocollo in python
risposta
In breve, probabilmente non ti devi preoccupare affatto. Poichè Python usa duck typing - vedi anche lo Wikipedia article per una definizione più ampia - se un oggetto ha i giusti metodi, funzionerà semplicemente, altrimenti verranno sollevate delle eccezioni.
si potrebbe avere una classe Piece
base con alcuni metodi gettando NotImplementedError
per indicare hanno bisogno di essere re-implementato:
class Piece(object):
def move(<args>):
raise NotImplementedError(optional_error_message)
class Queen(Piece):
def move(<args>):
# Specific implementation for the Queen's movements
# Calling Queen().move(<args>) will work as intended but
class Knight(Piece):
pass
# Knight().move() will raise a NotImplementedError
In alternativa, si potrebbe validare in modo esplicito un oggetto si riceve per assicurarsi che ha tutto i metodi corretti o che si tratti di una sottoclasse di Piece
utilizzando o isubclass. Nota che il controllo del tipo potrebbe non essere considerato "Pythonic" da alcuni e utilizzando l'approccio NotImplementedError
o il modulo abc
- come menzionato in this very good answer - potrebbe essere preferibile.
La tua fabbrica deve solo produrre istanze di oggetti con i giusti metodi su di loro.
Ho scritto un gioco di scacchi in Python (con tkinter), e il modo in cui l'ho fatto era avere una classe Piece, Queen/Knight/etc. classi che ereditano dalla classe Piece, una classe Player, una classe Square e una classe programma principale per il ciclo principale di tkinter. Ogni pezzo ha un colore e una posizione, e un metodo per aiutare a generare serie di mosse per i pezzi che si muovono in linea retta fino a quando non vengono bloccati. Le sottoclassi di Piece specifici contengono ciascuna un metodo per determinare il loro set di mosse. Un oggetto Quadrato contiene un Pezzo e la posizione del quadrato sul tabellone.
La classe di programma principale ha un __init__
che imposta la scheda, posiziona i pezzi, carica icone pezzo ed effetti sonori e inizializza le opzioni. Un metodo draw_board
ridisegna la scheda, reimpostando tutti i pezzi e riconfigurando i tasti di scelta rapida. Poi ci sono vari altri metodi per caricare nuove icone, avviare una nuova partita, impostare il volume, salvare, annullare, castellare e così via.
Non ho ancora finito con la versione 10, ma è possibile ottenere il codice sorgente e le risorse per la versione 9 here.
È anche possibile controllare l'open source Shane's Chess Information Database. Non l'ho mai usato, ma sembra molto carino.
In genere non utilizzo le interfacce in Python, ma se devi farlo puoi usare zope.interface
. È quindi possibile verificare se le classi o gli oggetti implementano determinate interfacce. Inoltre, può anche generare errori se le classi non implementano tutti i metodi o attributi. Twisted e altri framework utilizzano questa libreria.
Anche se Python, essendo dinamico, può utilizzare la digitazione anatra, è ancora possibile implementare ciò che Java e C# chiamano "interfacce". Questo viene fatto dichiarando una classe base astratta. https://docs.python.org/2/library/abc.html o https://docs.python.org/3.4/library/abc.html
Quando si definisce l'ABC, mettere tutti i metodi di interfaccia simile in esso e hanno nel loro corpo sia pass
o raise NotImplementedError
. Le classi figlio ereditano dal tuo ABC e sovrascrivono questi metodi proprio come qualsiasi altra classe secondaria sovrascrive i metodi della classe genitore. (Dato che Python ha ereditarietà multiple, possono ereditare dal tuo ABC più qualsiasi altra classe che ti piace.)
Quale sarebbe il punto delle interfacce in Python, in quanto non potrebbe costringerti ad implementare tutti i metodi? –
Le interfacce sono importanti per le lingue che sono tipizzate staticamente e si desidera imporre che le classi ereditanti implementino le interfacce. Per linguaggi dinamici come python, una classe o un client di una classe possono cercare funzioni. Se la classe ne ha una, può eseguirla, che l'abbia ereditata o meno. –