Estoy ejecutando pylint en algún código y recibo el error "Muy pocos métodos públicos (0/2)". ¿Qué significa este mensaje? Los documentos de pylint no son útiles:
Se usa cuando la clase tiene muy pocos métodos públicos, así que asegúrese de que realmente valga la pena.
Respuestas:
El error básicamente dice que las clases no tienen la intención de simplemente almacenar datos, como que está básicamente el tratamiento de la clase como un diccionario. Las clases deben tener al menos algunos métodos para operar con los datos que poseen.
Si su clase se ve así:
Considere usar un diccionario o en su
namedtuple
lugar. Aunque si una clase te parece la mejor opción, úsala. pylint no siempre sabe qué es lo mejor.Tenga en cuenta que
namedtuple
es inmutable y los valores asignados en la instanciación no se pueden modificar más adelante.fuente
dict
onamedtuple
. Usa una clase cuando quieras agregar algo de lógica a tu objeto (por ejemplo, quieres que sucedan cosas cuando se crea, necesitas que sucedan algunas cosas especiales cuando se agregue, quieres realizar algunas operaciones en él, controlar cómo está mostrado, etc.)namedtuple
apesta: además de tener una sintaxis desagradable, no puede documentarla o proporcionar valores predeterminados fácilmente.namedtuple
me arrepiento de la decisión. Es inconsistente permitir tanto el acceso con nombre como los atributos de acceso indexado.Si está ampliando una clase, mi sugerencia es deshabilitar sistemáticamente esta advertencia y continuar, por ejemplo, en el caso de las tareas de Apio:
Incluso si solo está extendiendo una única función, definitivamente necesita una clase para hacer que esta técnica funcione, ¡y extender es definitivamente mejor que piratear las clases de terceros!
fuente
min-public-methods=0
en la[BASIC]
sección del archivo de configuración. Esto le permite colocarlo en una línea separada de todas susdisable=
cosas (en[MESSAGE CONTROL]
), lo que me parece que facilita la adición de comentarios detallados sobre por qué habilitó y deshabilitó cosas junto con el cambio de configuración.Este es otro caso de
pylint
las reglas ciegas."Las clases no están destinadas a almacenar datos": esta es una declaración falsa. Los diccionarios no sirven para todo. Un miembro de datos de una clase es algo significativo, un elemento de diccionario es algo opcional. Prueba: puedes hacer
dictionary.get('key', DEFAULT_VALUE)
para prevenir unaKeyError
, pero no hay nada simple__getattr__
con defecto.EDITAR - formas recomendadas de usar estructuras
Necesito actualizar mi respuesta. Ahora mismo, si necesita un
struct
, tiene dos excelentes opciones:a) Solo usa
attrs
Esta es una biblioteca para eso:
https://www.attrs.org/en/stable/
Lo que obtiene extra: no escribir constructores, valores predeterminados, validación,
__repr__
objetos de solo lectura (para reemplazarnamedtuples
, incluso en Python 2) y más.b) Utilizar
dataclasses
(Py 3.7+)Siguiendo el comentario de hwjp, también recomiendo
dataclasses
:https://docs.python.org/3/library/dataclasses.html
Esto es casi tan bueno
attrs
y es un mecanismo de biblioteca estándar ("baterías incluidas"), sin dependencias adicionales, excepto Python 3.7+.Resto de respuesta anterior
NamedTuple
no es genial, especialmente antes de Python 3typing.NamedTuple
: https://docs.python.org/3/library/typing.html#typing.NamedTuple - definitivamente deberías revisar elNamedTuple
patrón de "clase derivada de ". Python 2 -namedtuples
creado a partir de descripciones de cadenas - es feo, malo y "programar dentro de cadenas literales" estúpido.Estoy de acuerdo con las dos respuestas actuales ("considere usar otra cosa, pero pylint no siempre es correcto" - la aceptada y "use pylint para suprimir el comentario"), pero tengo mi propia sugerencia.
Permítanme señalar esto una vez más: algunas clases están diseñadas solo para almacenar datos.
Ahora la opción a considerar también - use
property
-ies.Arriba tiene propiedades de solo lectura, que están bien para Objeto de valor (por ejemplo, como las del Diseño controlado por dominio), pero también puede proporcionar establecedores; de esta manera, su clase podrá asumir la responsabilidad de los campos que tiene, por ejemplo para hacer alguna validación, etc. (si tiene establecedores, puede asignarlos usándolos en el constructor, es decir, en
self.foo = foo
lugar de directosself._foo = foo
, pero con cuidado, los establecedores pueden asumir que otros campos ya están inicializados, y luego necesita una validación personalizada en el constructor) .fuente
attrs
biblioteca, que en realidad era el modelo para crear eldataclasses
módulo.namedtuples
tienen una sintaxis extraña para la herencia ... requiriendo que cada clase que use una sepa que es una tupla con nombre y use en__new__
lugar de__init__
.dataclasses
no tengo esta limitaciónEs difícil cuando su jefe espera el principio de responsabilidad única, pero pylint dice que no. Así que agregue un segundo método a su clase para que su clase viole el principio de responsabilidad única. Hasta dónde se supone que debe llevar el principio de responsabilidad única está en el ojo del espectador.
Mi solución
Agregué un método adicional a mi clase, por lo que ahora hace 2 cosas.
Me pregunto si necesito dividir mi clase en 2 archivos separados ahora, y tal vez también en módulos.
problema resuelto, pero no con mis colegas que pasan todo el día discutiendo las especificaciones, en lugar de seguir adelante, como si fuera de vida o muerte.
fuente