public interface IInterface
{
void show();
}
public class MyClass : IInterface
{
#region IInterface Members
public void show()
{
Console.WriteLine("Hello World!");
}
#endregion
}
Comment implémenter l'équivalent Python de ce code C #?
class IInterface(object):
def __init__(self):
pass
def show(self):
raise Exception("NotImplementedException")
class MyClass(IInterface):
def __init__(self):
IInterface.__init__(self)
def show(self):
print 'Hello World!'
Est-ce une bonne idée?? Veuillez donner des exemples dans vos réponses.
raise NotImplementedError
est ce queshow
devrait être le corps - cela n'a aucun sens d'élever un complètement génériqueException
quand Python en définit un intégré parfaitement spécifique! -)Réponses:
Comme mentionné par d'autres ici:
Les interfaces ne sont pas nécessaires en Python. C'est parce que Python a un héritage multiple approprié, ainsi que du typage duck, ce qui signifie que les endroits où vous devez avoir des interfaces en Java, vous n'avez pas à les avoir en Python.
Cela dit, il existe encore plusieurs utilisations des interfaces. Certains d'entre eux sont couverts par les classes de base abstraites Pythons, introduites dans Python 2.6. Ils sont utiles si vous souhaitez créer des classes de base qui ne peuvent pas être instanciées, mais fournissent une interface spécifique ou une partie d'une implémentation.
Une autre utilisation est si vous voulez en quelque sorte spécifier qu'un objet implémente une interface spécifique, et vous pouvez utiliser ABC pour cela aussi en les sous-classant. Une autre façon est zope.interface, un module qui fait partie de l'architecture de composants Zope, un framework de composants vraiment génial. Ici, vous ne sous-classez pas les interfaces, mais marquez plutôt les classes (ou même les instances) comme implémentant une interface. Cela peut également être utilisé pour rechercher des composants à partir d'un registre de composants. Super cool!
la source
L'utilisation du module abc pour les classes de base abstraites semble faire l'affaire.
la source
if not server.version() == '1.0': raise ...
:? Je ne comprends pas vraiment cette ligne. Une explication serait la bienvenue.L'interface prend en charge Python 2.7 et Python 3.4+.
Pour installer l' interface, vous devez
Exemple de code:
la source
L'implémentation d'interfaces avec des classes de base abstraites est beaucoup plus simple dans Python 3 moderne et elles servent de contrat d'interface pour les extensions de plug-in.
Créez l'interface / la classe de base abstraite:
Créez une sous-classe normale et remplacez toutes les méthodes abstraites:
Vous pouvez éventuellement avoir une implémentation commune dans les méthodes abstraites comme dans
create_sale_invoice()
, en l'appelantsuper()
explicitement dans la sous-classe comme ci-dessus.L'instanciation d'une sous-classe qui n'implémente pas toutes les méthodes abstraites échoue:
Vous pouvez également avoir des propriétés abstraites, des méthodes statiques et de classe en combinant les annotations correspondantes avec
@abstractmethod
.Les classes de base abstraites sont idéales pour implémenter des systèmes basés sur des plugins. Toutes les sous-classes importées d'une classe sont accessibles via
__subclasses__()
, donc si vous chargez toutes les classes à partir d'un répertoire de plugin avecimportlib.import_module()
et si elles sous-classent la classe de base, vous avez un accès direct à elles via__subclasses__()
et vous pouvez être sûr que le contrat d'interface est appliqué pour tous eux lors de l'instanciation.Voici l'implémentation du chargement du plugin pour l'
AccountingSystem
exemple ci-dessus:Ensuite, vous pouvez accéder à l'objet plug-in du système comptable via la
AccountingSystem
classe:(Inspiré par ce post PyMOTW-3 .)
la source
Il existe des implémentations tierces d'interfaces pour Python (le plus populaire est celui de Zope , également utilisé dans Twisted ), mais le plus souvent les codeurs Python préfèrent utiliser le concept plus riche connu sous le nom de "Abstract Base Class" (ABC), qui combine une interface avec la possibilité d'y avoir aussi quelques aspects de mise en œuvre. Les ABC sont particulièrement bien pris en charge dans Python 2.6 et versions ultérieures, voir le PEP , mais même dans les versions antérieures de Python, ils sont normalement considérés comme "la voie à suivre" - définissez simplement une classe dont certaines méthodes soulèvent
NotImplementedError
pour que les sous-classes soient en notant qu'ils feraient mieux de remplacer ces méthodes! -)la source
Quelque chose comme ça (peut ne pas fonctionner car je n'ai pas de Python):
la source
__init__(self)
le constructeur?abc.ABC
c'est bien mieux que de déclencherNotImplementedError
- l'instanciation d'uneabc.ABC
sous-classe qui n'implémente pas toutes les méthodes abstraites échoue tôt, vous êtes donc protégé contre les erreurs. Voir ma réponse ci-dessous pour savoir à quoi ressemble l'erreur.Je crois comprendre que les interfaces ne sont pas nécessaires dans les langages dynamiques comme Python. En Java (ou C ++ avec sa classe de base abstraite), les interfaces sont des moyens pour s'assurer que, par exemple, vous passez le bon paramètre, capable d'exécuter un ensemble de tâches.
Par exemple, si vous avez observer et observable, observable est intéressé par l'abonnement d'objets prenant en charge l'interface IObserver, qui à son tour a
notify
action. Ceci est vérifié au moment de la compilation.En Python, il n'y a rien de tel
compile time
et les recherches de méthodes sont effectuées au moment de l'exécution. De plus, on peut remplacer la recherche avec les méthodes magiques __getattr __ () ou __getattribute __ (). En d'autres termes, vous pouvez passer, en tant qu'observateur, tout objet qui peut retourner appelable en accédantnotify
attribut.Cela m'amène à la conclusion que les interfaces en Python existent - c'est juste que leur application est reportée au moment où elles sont réellement utilisées
la source