python - visual - ¿Qué significa el mensaje “Muy pocos métodos públicos” de pylint?
run pylint visual studio code (3)
El error básicamente dice que las clases no están destinadas solo a almacenar datos, ya que básicamente estás tratando a la clase como un diccionario. Las clases deben tener al menos unos pocos métodos para operar con los datos que poseen.
Si tu clase se ve así:
class MyClass(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
Considere usar un diccionario o un namedtuple
en namedtuple
lugar. Aunque si una clase 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.
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 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.
Este es otro caso de reglas ciegas de pylint
.
"Las clases no están destinadas a almacenar datos": esta es una declaración falsa. Los diccionarios no son buenos para todo. Un miembro de datos de una clase es algo significativo, un elemento de diccionario es algo opcional. Prueba: puede hacer dictionary.get(''key'', DEFAULT_VALUE)
para evitar un KeyError
, pero no hay un __getattr__
simple con el valor predeterminado.
NamedTuple
no es muy bueno, especialmente antes de typing.NamedTuple
Python typing.NamedTuple
: https://docs.python.org/3/library/typing.html#typing.NamedTuple : definitivamente debes revisar el patrón de "clase derivada de NamedTuple
". Python 2 - las namedtuples
creadas a partir de descripciones de cadenas - es feo, malo y "la programación dentro de los literales de cadenas" es estúpida.
Estoy de acuerdo con las dos respuestas actuales ("considere usar otra cosa, pero pylint no siempre tiene la razón" - la aceptada, y "use el comentario de supresión de pylint"), pero tengo mi propia sugerencia.
Permítanme señalar esto una vez más: algunas clases están destinadas solo para almacenar datos.
Ahora la opción de considerar también - usar property
es.
class MyClass(object):
def __init__(self, foo, bar):
self._foo = foo
self._bar = bar
@property
def foo(self):
return self._foo
@property
def bar(self):
return self._bar
Más arriba, tiene propiedades de solo lectura, lo cual está bien para Objeto de valor (por ejemplo, como en Diseño impulsado por dominio), pero también puede proporcionar definidores: de esta manera su clase podrá asumir la responsabilidad de los campos que tiene, por ejemplo para hacer alguna validación, etc. (si tiene configuradores, puede asignarlos usándolos en el constructor, es decir, self.foo = foo
lugar de self._foo = foo
, pero con cuidado, los configuradores pueden asumir que otros campos ya están inicializados, y luego necesita validación personalizada en el constructor).
Si está extendiendo una clase, entonces mi sugerencia es desactivar sistemáticamente esta advertencia y seguir adelante, por ejemplo, en el caso de las tareas de apio:
class MyTask(celery.Task): # pylint: disable=too-few-public-methods
"""base for My Celery tasks with common behaviors; extends celery.Task
...
Incluso si solo estás extendiendo una sola función, definitivamente necesitas una clase para hacer que esta técnica funcione, ¡y extender es definitivamente mejor que hackear las clases de terceros!