Pregunta

Tengo algo de código en una clase reutilizable que modifica algunos tipos. He aquí una versión simplificada.

class Foo:
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1

# Add another method outside of the class definition.
# Pylint doesn't care about this, and rates this file 10/10.

Foo.__dict__["current_count"] = lambda self: self.count

En el código real "CURRENT_COUNT" es una variable, no una cadena fija, por lo que no he escrito:

Foo.current_count = lambda self: self.count # Cannot do in my scenario.

Ahora, cuando mis clientes vienen a utilizar la nueva función, Pylint salta hacia arriba y hacia abajo con horror.

import server_api

def main():
    foo_count = server_api.Foo()
    foo_count.increment()


    print foo_count.current_count()
    # Pylint complains here:
    #     E1101:  8:main: Instance of 'Foo' has no 'current_count' member
    # I don't want to have to tell pylint to disable that message in every client.

main()

Cada clase que utiliza esta nueva función se castigó, y me veo obligado a desactivar el mensaje en cada referencia. Yo preferiría poner un poco de código en el API para contar Pylint para relajarse cuando hay referencias desconocidas en esta clase.

Por desgracia, la documentación pylint es ... ummm ... no de una calidad favorable a mi entendimiento, y no he podido encontrar ninguna sugerencia allí.

Así que hervirla: puedo saber pylint en mi código API para desactivar la regla E1101 en relación con esta clase, cada vez que un cliente se refiere a ella? ¿Hay alguna otra solución?

¿Fue útil?

Solución

Aquí está mi solución inspirada en el ejemplo de la ActiveState libros de cocina receta , proporcionado en < a href = "https://stackoverflow.com/users/396593/yoni-h"> Yoni H 's respuesta .

Para la clase Foo, I añadió este método __getattr__ inútil.

def __getattr__(self, name):
    # This is only called when the normal mechanism fails, so in practice should never be called.
    # It is only provided to satisfy pylint that it is okay not to raise E1101 errors in the client code.
    raise AttributeError("%r instance has no attribute %r" % (self, name))

Esto debería ser casi indistinguible de la versión anterior. No se debe llamar en el curso normal de los acontecimientos, pero es suficiente para persuadir pylint a permanecer en silencio acerca de este error.

p.s. Se le permite a quejarse de que este código no es muy bonito. Comparto esa opinión. Pero creo que sus beneficios para el cliente son mayores que su olor código.

Otros consejos

Después de uno de sus comentarios, ya que vamos a dar un tipo enumerado, ¿por qué no echar un vistazo en esta cuestión de forma , o este ActiveState libros de cocina receta ?

Fuera de la preferencia personal, me quedaría con la adición de los tipos enumerados en la clase, al igual que una de las respuestas en SO pregunta (copiado descaradamente de contexto):

class Animal:
   def __init__(self, name):
       self.name = name

   def __str__(self):
       return self.name

   def __repr__(self):
       return "<Animal: %s>" % self

Animal.DOG = Animal("dog")
Animal.CAT = Animal("cat")

De manera pragmática hablando, ¿por qué el supuesto de que pylint (o cualquier pelusa) deben estar en silencio? Dado un sesgo entre los falsos positivos y falsos negativos, lints deberían preferir la primera. Me parece que debido a Pylint expresa sus resultados como una puntuación que la gente asume que debe ser maximizada, pero no hay premio para "ganar".

Por otro lado, la construcción se quejaba de duda es feo. Yo entiendo que la server_api se simplifica para nuestra conveniencia, pero lo que realmente necesita para perder el tiempo con el espacio de nombres del módulo? A partir de su código de cliente, parece que el nombre del método current_count está codificado, por qué no en el servidor?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top