Quand utiliser "raise NotImplementedError"? [fermé]
est-ce to pour se souvenir de vous et de votre équipe pour mettre en œuvre la classe correctement? Je ne suis pas entièrement d'obtenir l'utilisation d'une classe abstraite comme ceci:
class RectangularRoom(object):
def __init__(self, width, height):
raise NotImplementedError
def cleanTileAtPosition(self, pos):
raise NotImplementedError
def isTileCleaned(self, m, n):
raise NotImplementedError
4 réponses
comme le dit la documentation [docs],
dans les classes de base définies par l'utilisateur, les méthodes abstraites devraient soulever cette exception lorsqu'elles nécessitent des classes dérivées pour outrepasser la méthode, ou alors que la classe est en cours de développement pour indiquer que l'implémentation réelle doit encore être ajoutée.
notez que bien que le principal cas d'utilisation indiqué cette erreur est l'indication de méthodes abstraites qui doivent être mises en œuvre sur classes héritées, vous pouvez l'utiliser comme vous le souhaitez, comme indication d'un TODO
marqueur.
Uriel dit, il est destiné à une méthode dans une classe abstraite qui devrait être implémentée dans la classe enfant, mais peut être utilisé pour indiquer un TODO aussi bien.
Il y a une alternative pour le premier cas d'utilisation: Les Classes De Base Abstraites. Ceux - là aident à créer des classes abstraites.
voici un exemple de Python 3:
class C(abc.ABC):
@abstractmethod
def my_abstract_method(self, ...):
...
Lors de l'instanciation C
, vous obtiendrez une erreur car my_abstract_method
est abstrait. Vous avez besoin de mettre en œuvre dans une classe enfant.
TypeError: Can't instantiate abstract class C with abstract methods my_abstract_method
sous-classe C
et de mettre en œuvre my_abstract_method
.
class D(C):
def my_abstract_method(self, ...):
...
Maintenant, vous pouvez instancier D
.
C.my_abstract_method
ne doit pas être vide. Il peut être appelé à partir de D
en utilisant super()
.
un avantage de ceci sur NotImplementedError
c'est que vous obtenez une explicite Exception
au moment de l'instanciation, pas au moment de l'appel de méthode.
Examiner si, au contraire, c'était:
class RectangularRoom(object):
def __init__(self, width, height):
pass
def cleanTileAtPosition(self, pos):
pass
def isTileCleaned(self, m, n):
pass
et vous sous-classe et d'oublier de dire comment isTileCleaned()
ou, peut-être plus probable, faute de frappe isTileCLeaned()
. Puis dans votre code, vous aurez un None
quand vous l'appelez.
- obtiendrez-vous la fonction overridden que vous vouliez? Certainement pas.
None
valid sortie? Qui sait.- est - ce un comportement intentionnel? Presque certainement pas.
- vous obtenez une erreur? Il dépend.
raise NotImplmentedError
force vous de le mettre en œuvre, comme il lancer une exception lorsque vous essayez de l'exécuter jusqu'à ce que vous le faites. Cela élimine beaucoup d'erreurs silencieuses. Il est similaire à la pourquoi un nue sauf est presque jamais une bonne idée: parce que les gens font des erreurs et cela fait en sorte qu'ils ne sont pas balayés sous le tapis.
Note: L'utilisation d'une classe de base abstraite, comme d'autres réponses l'ont mentionné, est encore mieux, comme alors le les erreurs sont avant-chargées et le programme ne s'exécute pas tant que vous ne les mettez pas en œuvre (avec NotImplementedError, il ne lancera une exception que s'il est réellement appelé).
vous pourriez vouloir utiliser le @property
décorateur,
>>> class Foo():
... @property
... def todo(self):
... raise NotImplementedError("To be implemented")
...
>>> f = Foo()
>>> f.todo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in todo
NotImplementedError: To be implemented