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
28
demandé sur Antonio Araujo 2017-06-01 22:48:32

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.

29
répondu Uriel 2017-06-01 19:54:50

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.

13
répondu Jérôme 2018-03-27 08:11:30

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 NotImplmentedErrorforce 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é).

5
répondu TemporalWolf 2018-05-06 17:22:00

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
0
répondu Simeon Aleksov 2017-06-01 20:00:40