Estou executando o pylint em algum código e recebendo o erro "Muito poucos métodos públicos (0/2)". O que esta mensagem significa? Os documentos do pylint não são úteis:
Usado quando a classe tem poucos métodos públicos, portanto, certifique-se de que realmente vale a pena.
Respostas:
O erro basicamente diz que as classes não servem apenas para armazenar dados, pois você basicamente trata a classe como um dicionário. As classes devem ter pelo menos alguns métodos para operar nos dados que contêm.
Se sua classe é assim:
Considere usar um dicionário ou um
namedtuple
. Embora se uma classe parecer a melhor escolha, use-a. pylint nem sempre sabe o que é melhor.Observe que
namedtuple
é imutável e os valores atribuídos na instanciação não podem ser modificados posteriormente.fonte
dict
ounamedtuple
. Use uma classe quando quiser adicionar alguma lógica ao seu objeto (por exemplo, você deseja que as coisas aconteçam quando ele é criado, você precisa que algumas coisas especiais aconteçam quando for adicionado, você deseja realizar algumas operações nele, controlar como é exibido, etc.)namedtuple
é uma merda - além de ter uma sintaxe feia, você não pode documentá-la ou fornecer valores padrão facilmente.namedtuple
, me arrependi da decisão. É inconsistente permitir acesso nomeado e atributos de acesso indexados.Se você está estendendo uma aula, então minha sugestão é desabilitar sistematicamente este aviso e seguir em frente, por exemplo, no caso de tarefas de aipo:
Mesmo se você estiver apenas estendendo uma única função, você definitivamente precisa de uma classe para fazer essa técnica funcionar, e estender é definitivamente melhor do que hackear as classes de terceiros!
fonte
min-public-methods=0
na[BASIC]
seção do arquivo de configuração. Isso permite que você coloque em uma linha separada de todas as suasdisable=
coisas (in[MESSAGE CONTROL]
), o que torna mais fácil adicionar comentários detalhados sobre por que você habilitou e desabilitou coisas junto com a mudança de configuração.Este é outro caso de
pylint
regras cegas de."As classes não têm como objetivo armazenar dados" - esta é uma afirmação falsa. Os dicionários não são bons para tudo. Um membro de dados de uma classe é algo significativo, um item de dicionário é algo opcional. Prova: você pode fazer
dictionary.get('key', DEFAULT_VALUE)
para prevenir umKeyError
, mas não é simples__getattr__
com o padrão.EDITAR - maneiras recomendadas de usar estruturas
Eu preciso atualizar minha resposta. Agora - se você precisar de um
struct
, você tem duas ótimas opções:a) Basta usar
attrs
Esta é uma biblioteca para isso:
https://www.attrs.org/en/stable/
O que você ganha extra: não escrever construtores, valores padrão, validação,
__repr__
objetos somente leitura (para substituirnamedtuples
, mesmo no Python 2) e muito mais.b) Use
dataclasses
(Py 3.7+)Após o comentário de hwjp, também recomendo
dataclasses
:https://docs.python.org/3/library/dataclasses.html
Isso é quase tão bom quanto
attrs
, e é um mecanismo de biblioteca padrão ("baterias incluídas"), sem dependências extras, exceto Python 3.7+.Resto da resposta anterior
NamedTuple
não é ótimo - especialmente antes do python 3typing.NamedTuple
: https://docs.python.org/3/library/typing.html#typing.NamedTuple - você definitivamente deve verificar oNamedTuple
padrão "classe derivada de ". Python 2 -namedtuples
criado a partir de descrições de string - é feio, ruim e "programar dentro de literais de string" é estúpido.Concordo com as duas respostas atuais ("considere usar outra coisa, mas o pylint nem sempre está certo" - a aceita e "use o comentário de supressão do pylint"), mas tenho minha própria sugestão.
Deixe-me apontar isso mais uma vez: algumas classes destinam-se apenas a armazenar dados.
Agora, a opção de considerar também - use
property
-ies.Acima você tem propriedades somente leitura, o que é OK para Value Object (por exemplo, como aquelas em Domain Driven Design), mas você também pode fornecer setters - desta forma, sua classe será capaz de assumir a responsabilidade pelos campos que você possui - por exemplo para fazer alguma validação etc. (se você tiver setters, você pode atribuir usando-os no construtor, ou seja, em
self.foo = foo
vez de diretoself._foo = foo
, mas cuidado, os setters podem assumir que outros campos já foram inicializados, e então você precisa de validação personalizada no construtor) .fonte
attrs
biblioteca, que era na verdade o projeto para a criação dodataclasses
módulo.namedtuples
tem uma sintaxe estranha para herança ... exigindo que cada classe usando uma saiba que é uma tupla nomeada e use em__new__
vez de__init__
.dataclasses
não tem essa limitaçãoÉ difícil quando seu chefe espera o princípio da responsabilidade única, mas Pylint diz não. Portanto, adicione um segundo método à sua classe para que ela viole o princípio de responsabilidade única. Até onde você deve assumir o princípio da responsabilidade única está nos olhos de quem vê.
Minha correção,
Eu adicionei um método extra à minha classe, então agora ele faz 2 coisas.
Só estou me perguntando se preciso dividir minha classe em 2 arquivos separados agora, e talvez módulos também.
problema resolvido, mas não com meus colegas que passam o dia todo discutindo a especificação, ao invés de continuar com ela, como se fosse vida ou morte.
fonte