É convencional gerar um NotImplementedError para métodos cuja implementação está pendente, mas não planejada para ser abstrata?

34

Eu gosto de criar um NotImplementedErrormétodo para qualquer método que eu queira implementar, mas onde ainda não cheguei a fazê-lo. Talvez eu já tenha uma implementação parcial, mas acrescente-a raise NotImplementedError()porque ainda não gosto. Por outro lado, também gosto de seguir as convenções, pois isso facilitará a manutenção de meu código por outras pessoas, e as convenções podem existir por um bom motivo.

No entanto, a documentação do Pythons para NotImplementedError afirma:

Esta exceção é derivada de RuntimeError. Nas classes base definidas pelo usuário, os métodos abstratos devem gerar essa exceção quando exigirem que as classes derivadas substituam o método.

Esse é um caso de uso formal muito mais específico do que o que eu descrevo. É um estilo convencional bom NotImplementedErrorsugerir simplesmente que essa parte da API é um trabalho em andamento? Caso contrário, existe uma maneira padronizada diferente de indicar isso?

gerrit
fonte
O que você quer dizer com "apropriado"?
Robert Harvey
1
@RobertHarvey Suponho que quero dizer convencional, seguindo o uso comum. Eu reformulei minha pergunta agora.
precisa saber é
1
Usamos C # aqui principalmente, mas esse tipo de exceção é idiomático aqui, e eu esperaria em outro lugar. Quebrar cedo e sair alto é uma boa diretriz para identificar problemas potenciais rapidamente (leia-se: barato).
Telastyn
Geralmente, se estou criando uma classe, apenas coloco comentários TODO em métodos não implementados até que eu comece a implementar a funcionalidade. Se a classe fosse lançada para produção antes que isso acontecesse, eu consideraria lançar exceções.
5
Pelo que vale, é isso que o Microsoft Visual Studio faz por padrão quando você usa o IDE para "implementar uma interface". Na Robert Harvey diz, o resultado é bem compreendido.
catfood

Respostas:

34

Vale ressaltar que, embora a documentação do Python forneça um caso de uso (e provavelmente o canônico) para essa exceção, ela não exclui especificamente seu uso em outros cenários.

Eu consideraria apropriado gerar uma exceção NotImplementedError se você ainda não substituiu um método em uma classe base (para satisfazer a "interface").

Uma verificação superficial no Google sugere que as pessoas entenderão o que você quer dizer se você usar a exceção dessa maneira. Não há efeitos colaterais ou conseqüências não intencionais que eu saiba; o método simplesmente lançará uma exceção se for chamado, e lançará uma exceção que será bem compreendida por todos.


A documentação do Python 3 reflete esse uso exato:

Nas classes base definidas pelo usuário, os métodos abstratos devem gerar essa exceção quando exigir que as classes derivadas substituam o método ou enquanto a classe estiver sendo desenvolvida para indicar que a implementação real ainda precisa ser adicionada . [Enfase adicionada]

Robert Harvey
fonte
+1, mas também acrescentaria que, para esse tipo de convenção, um pouco de documentação pode percorrer um longo caminho. Como uma nota de uma linha em um wiki para desenvolvedores, read-readpo ou diretrizes de estilo - algo assim - explicando para que você usa essa exceção.
Ben Lee
8

Isso será entendido, se você faz ou não, deve depender das convenções locais (equipe ou empresa). Observe que faz menos sentido no contexto do TDD, pois o TEST deve ser o que determina que o método não está implementado.

A versão curta é: use se você e sua equipe considerarem apropriado.

jmoreno
fonte
5
FWIW, Lançar a exceção deve ser uma boa maneira de fazer com que o teste falhe, se por algum motivo você precisar forçar esse comportamento. (Seria útil como parte de um topo intellisense método definição, por exemplo.)
DougM
1

Parece que NotImplementedErrorgeralmente está sendo gerado para o desenvolvimento de recursos do Python, como o seguinte:

@classmethod
def fromkeys(cls, iterable, v=None):
    # There is no equivalent method for counters because setting v=1
    # means that no element can have a count greater than one.
    raise NotImplementedError(
        'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')

Documetation

fromkeys (iterável)

Este método de classe não é implementado para objetos de contador.

Fonte

Collections.Counter.fromkeys

Emma
fonte