PEP 257 en ruso. (Acuerdo de cadenas de documentos)

Hola Habr Hay momentos en los que desea sumergirse en el idioma tanto como sea posible y comprender todas sus sutilezas. En el caso de Python, una de las mejores formas de hacerlo es leer la documentación y las PEP en el sitio web oficial. No hice esto en ese momento, porque no podía entender muchos de los aspectos "técnicos", y no había variantes de la traducción al ruso. Ahora decidí traducir PEP-257 yo mismo, que cuenta sobre la documentación correcta del código, porque con seguridad esto ayudará a los principiantes a comprender mejor el verdadero enfoque de "Python" para escribir código. Traduje los ejemplos de código al ruso, pero solo para transmitir mejor el significado. En programación real, intente escribir líneas de documentación en inglés. También digo de inmediato que como sinónimo del término "docstring" usé las palabras: "documentación" y "líneas de documentación". Bueno, pasemos a la traducción en sí.

Energía257
Título:Acuerdo de cadenas de documentos
AutoresDavid Goodger <goodger en python.org>, Guido van Rossum <guido en python.org>
Discusión:doc-sig en python.org
Estado:Activo
Un tipo:Informativo
Creado:29 de mayo de 2001
Publicación:13 de junio de 2001

anotación


Este PEP documenta la semántica y las convenciones asociadas con el uso de cadenas de documentos de Python.

Justificación


El propósito de este PEP es estandarizar la estructura de alto nivel de las cadenas de documentos: describir exactamente qué deben contener y explicar (no discutiremos la sintaxis de marcado real). PEP no contiene pautas estrictas, pero recomendaciones:
“Las convenciones convencionales proporcionan claridad, consistencia, facilidad de mantenimiento y fomentan buenos hábitos de programación. Pero no te obligan a actuar contra tu voluntad. ¡Esto es Python!

Tim Peters en comp.lang.python, 2001-06-16

Si evita los acuerdos generalmente aceptados, se verá en el peor de los casos. Pero hay algunas aplicaciones (por ejemplo, sistemas de documentación como Docutils) que le permitirán lograr un mejor resultado si conoce los acuerdos y los sigue.

Especificación


¿Qué es una cadena de documentos?


Una cadena de documentación es un literal de cadena que es la primera instrucción en una definición de módulo, función, clase o método. Dicha cadena estará disponible cuando se maneje el atributo especial __doc__ de este objeto.

Todas las bibliotecas, así como las funciones y clases exportadas por ellas, deben tener docstring. Los métodos públicos (incluido el constructor __ init__) también deben tener documentación. El paquete en sí puede documentarse dentro del archivo __init__.py ubicado en su directorio correspondiente.

Los literales de cadena que se encuentran en otras partes del código también pueden desempeñar el papel de documentación. No son reconocidos por el compilador de bytecode de Python y no están disponibles como atributos de objeto en tiempo de ejecución (es decir, carecen de información en __ doc__). Pero hay dos tipos adicionales de líneas de documentación que se recuperan utilizando otras herramientas de software:

  1. Los literales de cadena que ocurren inmediatamente después de una asignación simple en el módulo, clase o nivel __init__ se denominan "cadenas de documentación de atributos". (atributo docstrings)
  2. Los literales de cadena que ocurren inmediatamente después de otra línea de documentación se denominan "líneas de documentación adicionales". (cadenas de documentos adicionales)

Consulte PEP 258, "Especificación del proyecto Docutils", para obtener más detalles sobre atributos y cadenas de documentos adicionales.

[aprox. ed. Explicación de PEP 258]
def f(x):
    """  docstring   __doc__ ."""
    """
     "additional docstrings",   , 
        Docutils.
    """
    return x**2

f.a = 1
""" "attribute docstrings"   : f.a"""

Para mantener la coherencia, use siempre "" "comillas dobles" "" alrededor de la línea de documentación. Si usa caracteres de barra diagonal inversa ("\"), use la cadena "" "sin comillas" "" en su documentación. Para la cadena de documentos que contiene caracteres Unicode, use "" "Cadena Unicode en comillas dobles" "". [aprox. las cadenas unicode han perdido su significado en python 3.x]

Hay dos formas de docstring: una línea y varias líneas.

Líneas de documentación de una sola línea.


Las cadenas de una sola línea se usan para casos obvios y realmente deberían estar en la misma línea. Por ejemplo:

def kos_root():
    """    root KOS"""
    global _kos_root
    if _kos_root: return _kos_root
    ...

Observaciones:

  • . .
  • , . docstring .
  • , .
  • — «», . (« », « »), . , : « ...».

    « » «Return pathname» «Returns pathname». PEP-257 , .
  • «», / ( ). :

    def function(a, b):
        """function(a, b) -> list"""
    

    , C ( ), . . - :

    def function(a, b):
        def function(a, b):
        """ X   ."""
    

    ( -, « X» !)

    , : « », «description» . , , .



La documentación de varias líneas consiste en una línea de resumen que tiene la misma estructura que una cadena de documentos de una sola línea, seguida de una línea vacía y luego una descripción más compleja. La "línea de resumen" se puede utilizar mediante documentación automática; por lo tanto, es muy importante colocarlo en una línea y luego hacer un pase en una línea. La línea de resumen se escribe inmediatamente después de las comillas iniciales, pero se permite hacer una transferencia y comenzar desde la siguiente línea. [aprox. después de esta oración, estaba feliz, porque había personas que intentaron persistentemente demostrarme que era imposible realizar una transferencia en cualquier caso :-)] Al mismo tiempo, toda la cadena de documentación debería tener la misma sangría que las comillas iniciales de la primera línea (ver ejemplo abajo).

Deje una línea en blanco después de toda la documentación (una línea o varias líneas) que se utilizan en la clase; en términos generales, los métodos de clase deben estar separados entre sí por una línea vacía, por lo tanto, la línea de documentación de la clase también debe estar separada de esta manera del primer método.

La documentación del script (programa independiente) es un mensaje "sobre el uso apropiado" y probablemente se imprimirá cuando se llame al script con argumentos no válidos o faltantes (o con la opción "-h" para obtener "ayuda"). Dicha línea de documentación debe describir la funcionalidad y la sintaxis de los parámetros del script, así como las variables de entorno y los archivos utilizados. Este mensaje puede resultar bastante complicado (el manual tiene varias pantallas completas), pero al mismo tiempo debería ser conveniente para los nuevos usuarios para que puedan usar el comando correctamente. Además, el manual debe dar una descripción clara de todos los parámetros y argumentos para usuarios más experimentados.

La documentación del módulo generalmente debe contener una lista de clases, excepciones y funciones (y cualquier otro objeto importante) que se exportan utilizando la biblioteca, así como una explicación de una línea para cada una de ellas. (Este resumen, como regla, proporciona menos detalles que la línea de resumen en la cadena de documentos del objeto mismo). La documentación del paquete (es decir, la cadena de documentación del módulo en __init__.py) también debe describir y enumerar los módulos y subpaquetes exportados por el principal.

La documentación de la función o método debe describir su comportamiento, argumentos, valores de retorno, efectos secundarios, excepciones y restricciones sobre cuándo pueden llamarse (si corresponde). También debe especificar argumentos opcionales. Debe aclararse si los argumentos clave son parte de la interfaz.

La documentación de la clase debe resumir su comportamiento y enumerar los métodos públicos, así como las variables de instancia. Si la clase tendrá subclases con una interfaz adicional, entonces esta interfaz debe especificarse por separado (pero todo está también en esta documentación). El constructor de la clase debe tener su propia línea de documentación separada para el método __init__. Los métodos independientes (individuales) deben tener su propia documentación.

Si una clase es descendiente y su comportamiento se hereda principalmente de la clase principal, es necesario mencionar esto en su documentación y describir posibles diferencias. Utilice el verbo "anular" para indicar que se ha cambiado un método y que, como resultado, no se llamará al método de superclase. Utilice el verbo "extiende" si el método de la subclase llama al método de la superclase (además de su propio comportamiento).

No use la convención de Emacs para mencionar argumentos de función o métodos en mayúsculas. Python distingue entre mayúsculas y minúsculas, y los nombres de argumentos a veces se pueden usar al pasarlos por teclas, por lo que la documentación debe contener nombres de variables reales. Es mejor enumerar cada argumento en una línea separada. Por ejemplo:

def complex(real=0.0, imag=0.0):
    """  .

     :
    real --   (  0.0)
    imag --   (  0.0)
    """
    if imag == 0.0 and real == 0.0:
        return complex_zero
    ...


Si toda la cadena de documentación no cabe en la línea, puede colocar las comillas de cierre en una línea separada. Por lo tanto, será posible usar el comando Emacs: fill-párrafo

Procesamiento de cadena de documentos


Las herramientas de procesamiento de línea de documentación deben eliminar la misma cantidad de sangría igual a la sangría mínima de todas las líneas no vacías, comenzando por la segunda. Cualquier sangría en la primera línea de la documentación no es significativa y se eliminará. Se conserva la sangría relativa de las líneas posteriores en la línea del documento. Las líneas vacías deben eliminarse desde el principio y el final de la línea del documento.

Como el código es mucho más preciso que las palabras, la implementación del algoritmo se proporciona aquí:

def trim(docstring):
    if not docstring:
        return ''
    #     (  Python)
    #      :
    lines = docstring.expandtabs().splitlines()
    #    (   ):
    indent = sys.maxsize
    for line in lines[1:]:
        stripped = line.lstrip()
        if stripped:
            indent = min(indent, len(line) - len(stripped))
    #   (   ):
    trimmed = [lines[0].strip()]
    if indent < sys.maxsize:
        for line in lines[1:]:
            trimmed.append(line[indent:].rstrip())
    #       :
    while trimmed and not trimmed[-1]:
        trimmed.pop()
    while trimmed and not trimmed[0]:
        trimmed.pop(0)
    #    :
    return '\n'.join(trimmed)

Nota del traductor
, python3 sys.maxint sys.maxsize, .


La documentación en el siguiente ejemplo contiene dos líneas nuevas y, por lo tanto, tiene una longitud de tres. La primera y la última línea están vacías:

def foo ():
    """
       .
    """

Ilustramos:

>>> print repr(foo.__doc__)
'\n        .\n    '
>>> foo.__doc__.splitlines()
['', '        .', '    ']
>>> trim(foo.__doc__)
'    .'

Por lo tanto, después del procesamiento, las siguientes líneas de documentación serán equivalentes:

def foo():
    """ 
     .
    """

def bar():
    """
     
     .
    """

Nota del traductor
inspect, , : inspect.cleandoc(function.__doc__)


All Articles