2011-11-09 23 views
12

Tengo una gran cantidad de documentación sobre mí, ya que cada vez que encuentro un tipo de pato complejo, necesito decir "este tipo de pato", pero me atrapan en un ciclo interminable de "su función requiere esto de esta entrada, pero no lo documenta ", y luego lo documenta. Esto se traduce en la documentación hinchado, repetitivo, tales como los siguientes:¿Cómo documentar un tipo de pato?

def Foo(arg): 
    """ 
    Args: 
     arg: An object that supports X functionality, and Y functionality, 
     and can be passed to Z other functionality. 
    """ 
    # Insert code here. 

def Bar(arg): 
    """ 
    Args: 
     arg: An object that supports X functionality, and Y functionality, 
     and can be passed to Z other functionality. 
    """ 
    # Insert code here. 

Y así sucesivamente, y así sucesivamente, para Baz, Qux, y otras funciones. Necesito una forma más breve de escribir "arg es un (tipo de objeto)".

Para algunos tipos de pato, es tan fácil como "un objeto parecido a un dict": sabemos lo que esperamos de un dict, y entonces, sabemos qué pasar. A dict, o algo que pueda imitarlo.

Creo que C++ tiene el mismo problema con los tipos de plantilla. Haskell lo tendría, pero uno puede usar la definición de una clase de tipo para documentarlo. (Nota: Haskell classes! = Clases en Java/C++/Python/etc.) (Nota: realmente no programo en Haskell, así que discúlpeme si es un ejemplo horrible)

¿Debo ir a la tradicional? OO route, y solo escribe una clase base, y dices, "algo como esta clase base" en los documentos? El código no exigiría derivar de la clase base (ya que no hay ningún requisito para que el objeto se derive de ella), y la clase base no agrega ningún valor excepto para documentar las propiedades de la interfaz, esencialmente.

Por otro lado, estoy programando Python, y trato de programar dentro de las expresiones idiomáticas de un idioma. (De lo contrario, usualmente duele). Las clases base son buenas para heredar la funcionalidad, pero cuando la clase base es completamente abstracta, no parece agregar valor en un lenguaje de pato.


EDITAR: Para las respuestas: Yo sé lo que es la tipificación de pato (que debería ser evidente a partir de la entrada). ¿Dónde lo documenta? Es la pregunta, esp. cuando no existe una clase para adjuntar documentación a.

+0

Me gusta el término "actúa como" y mantengo los requisitos documentados en general a menos que haya una razón específica para exponer más detalles. Por ejemplo, si solo se necesita un indizador y una cuenta, aún diría que "actúa como una lista". Para otros tipos, es lo mismo: "x actúa como un animal", donde presumiblemente la idea de que un "perro es un animal" está documentada/asegurada en otra parte. –

+0

@pst: Sí, pero ¿qué es un animal, y qué esperamos del animal, y dónde lo documentamos? – Thanatos

+3

'clase Animal' y' clase Dog' en alguna parte, con su propia documentación :) Python está muy enraizado en el modelo de instancia de clase. –

Respuesta

6

La idea detrás de la tipificación de pato es que usted documenta que está esperando un pato y le corresponde a otros objetos fingir que es un pato.

En ninguna parte del documento, ninguna API especifica que acepta un objeto StringIO. En cambio, nosotros en la mayoría de los lugares que esperamos un objeto similar a un archivo.

También, en su mayor parte, la biblioteca estándar que trata de evitar nombrar los métodos específicos demanda de un tipo de pato. Eso deja la implementación abierta para el cambio. La API random.sample, por ejemplo, podría haberse definido en términos de iterables o en términos de secuencias.

Si quiere ser más específico que esto, puede usar abstract base classes. Varios ya están incluidos en el collections module (como Iterable, Hashable y Sized) o numbers module (Rational, Integral, etc.). No es difícil modelar después de aquellos para escribirlo. Entonces, la documentación simplemente menciona qué ABC se requieren (es decir, x es un SizedIterable y y es un Integral).

+0

Fui con el último párrafo: mis tipos de patos son tipos nuevos, por lo que seguiré escribiendo clases base abstractas. – Thanatos

1

El punto de la tipificación del pato es que la noción de "tipo" se convierte en una idea abstracta e intuitiva, en lugar de algo que forma parte formal del lenguaje. Esto hace que la escritura sea mucho más fluida y flexible que en los idiomas en los que la verificación de tipos es parte del lenguaje.

Lo que se requiere cuando se usa la tipificación de pato no es que el programa sabe qué "tipo" que está utilizando, pero que otros programadores hacen. Entonces, si tiene toda una familia de clases/funciones/etc. que operan en objetos de un "tipo" en particular, y ese tipo no puede describirse en pocas palabras, simplemente agregue una sección en comentarios o una docstring (o incluso un archivo externo .txt) que describe su tipo y lo nombra. Entonces puedes referirte a ese nombre en todas partes.

1

Los lenguajes más estrictamente tipados, como Java, tienen el concepto de "interfaces": colecciones de métodos que toda clase que implementa la interfaz debe proporcionar.

supongo que se podría tomar prestado el concepto sin llevar necesariamente a lo largo del bagaje de tipos de datos estrictos: acaba de definir y documentar una clase abstracta Foo, y luego dicen que su método espera "un objeto o una FooFoo -como". Ni siquiera tiene que hacer que ninguna otra clase herede de Foo si no lo desea; las personas que lean la documentación sabrán a dónde ir para averiguar qué se espera de un objeto similar a Foo.

Cuestiones relacionadas