2011-11-09 4 views
12

Mi sto gonfiando di documentazione, perché ogni volta che incontro un tipo di anatra complesso, ho bisogno di un modo per dire "questo tipo di anatra", ma invece di rimanere intrappolato in un ciclo infinito di "la tua funzione richiede questo input, ma non lo documenta ", e poi lo documenta. Ciò si traduce in gonfio, la documentazione ripetitivi, come il seguente:Come documentare un tipo di anatra?

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. 

E così via, e così via, per Baz, Qux, e altre funzioni. Ho bisogno di un modo più breve di scrivere "arg è un (tipo di oggetto)".

Per alcuni tipi di anatre, è facile come "Un oggetto dict-like": sappiamo quello che ci aspettiamo da un dict, e così, sappiamo cosa passare. A dict, o qualcosa che può imitarlo.

Penso che C++ abbia lo stesso problema con i tipi di modelli. Haskell avrebbe voluto, ma si può usare la definizione di una classe di caratteri per documentarla. (Nota: Haskell classes! = Classi in Java/C++/Python/etc.) (Nota: in realtà non programma in Haskell, quindi perdonami se è un esempio di merda.)

Devo andare al tradizionale OO route, e scrivi semplicemente una classe base e dì "qualcosa come questa classe base" nei documenti? Il codice non imporrebbe derivando dalla classe base (poiché non vi è alcun requisito per l'oggetto da derivare da esso), e la classe base non aggiunge alcun valore se non per documentare le proprietà dell'interfaccia, in sostanza.

D'altro canto, sto programmando Python e cerco di programmare all'interno degli idiomi di una lingua. (Come fare altrimenti fa solitamente male.) Le classi base sono buone per ereditare le funzionalità, ma quando la classe base è completamente astratta, non sembra aggiungere valore in un linguaggio tipizzato da anatra.


EDIT: per le risposte: So cosa tipizzazione anatra è (che dovrebbe essere evidente dal post). Dove posso documentare è la domanda, esp. quando non esiste una classe per allegare documentazione a.

+0

Mi piace il termine "si comporta come" e mantenere i requisiti generali documentati a meno che non vi sia un motivo specifico per esporre ulteriori dettagli. Ad esempio, se sono necessari solo un indicizzatore e un conteggio, direi che "agisce come un elenco". Per altri tipi, è lo stesso: "x si comporta come un animale", dove presumibilmente l'idea che un "cane è un animale" è documentata/assicurata altrove. –

+0

@pst: Sì, ma cos'è un animale e cosa ci aspettiamo dall'animale e dove lo documentiamo? – Thanatos

+3

'classe Animal' e' class Dog' da qualche parte, con la propria documentazione :) Python è molto radicato nel modello di istanza di classe. –

risposta

6

L'idea alla base della digitazione anatra è che si documenta che si sta aspettando un'anatra e tocca ad altri oggetti fingere di essere un'anatra.

Da nessuna parte nei documenti fa alcuna API specifica che accetta un oggetto StringIO. Invece, noi nella maggior parte dei casi ci aspettiamo un oggetto simile a un file.

Inoltre, per la maggior parte, la libreria standard tenta di evitare di denominare la richiesta di metodi specifici di un tipo di anatra. Ciò lascia aperta l'implementazione al cambiamento. L'API random.sample, ad esempio, avrebbe potuto essere definita in termini di iterabili o in termini di sequenze.

Se si desidera essere più specifici di questo, è possibile utilizzare abstract base classes. Diversi sono già inclusi nello collections module (come Iterable, Hashable e Sized) o numbers module (Rational, Integral, ecc.). Non è difficile da modellare dopo quelli per scriverti. Quindi, la documentazione indica semplicemente quali ABC sono richiesti (ad esempio x è un SizedIterable e y è un Integral).

+0

Sono andato con l'ultimo paragrafo: i miei tipi di anatre sono nuovi tipi, quindi con la scrittura di classi base astratte. – Thanatos

1

Il punto di digitazione anatra è che la nozione di "tipo" diventa un'idea astratta intuitiva, piuttosto che qualcosa che è formalmente parte del linguaggio. Ciò rende la digitazione molto più fluida e flessibile rispetto alle lingue in cui il controllo dei tipi fa parte della lingua.

Ciò che è necessaria quando si utilizza la tipizzazione anatra non è che il programma sa quello "tipo" si sta utilizzando, ma che altri programmatori DO. Quindi se hai un'intera famiglia di classi/funzioni/etc che operano su oggetti di un particolare "tipo", e quel tipo non può essere descritto in poche parole, aggiungi una sezione nei commenti o una docstring (o anche un file .txt esterno) che descrive il tuo tipo e lo nomina. Quindi puoi semplicemente riferirti a quel nome ovunque.

1

Altri linguaggi rigorosamente tipizzati, come Java, hanno il concetto di "interfacce": raccolte di metodi che ogni classe che implementa l'interfaccia dovrebbe fornire.

Immagino che si potrebbe prendere in prestito il concetto senza necessariamente portando con sé il bagaglio di tipizzazione forte: basta definire e documentare una classe astratta Foo, e poi dire che il metodo si aspetta "un oggetto o un FooFoo -come". Non è nemmeno necessario che altre classi ereditino effettivamente da Foo se non si desidera; chi legge la documentazione saprà dove andare per scoprire cosa ci si aspetta da un oggetto simile a Foo.