Guía de Estilo Del Código Python
Guía de Estilo Del Código Python
Por Guido van Rossum, Barry Warsaw Traduccin al castellano por Ral Gonzlez Duque el da 10 de Agosto de 2007
Introduccin
En este documento se listan distintas convenciones utilizadas en el cdigo Python comprendido en la librera estndar de la distribucin principal de Python. Por favor refierase al PEP que describe las guas de estilo del cdigo C para la implementacin en C de Python[1]. Este documento es una adaptacin del ensayo original de Guido Gua de Estilo de Python[2], con algunos aadidos de la gua de estilo de Barry[5]. En los puntos en los que exista conflicto, se aplican las reglas de estilo de Guido para los propsitos de este PEP. Este PEP puede estar an incompleto (de hecho, es posible que nunca llegue a completarse ).
Tabuladores o espacios?
Nunca mezcles tabuladores y espacios. La forma ms popular de indentar en Python es utilizar slo espacios. La segunda forma ms popular es usar slo tabuladores. El cdigo indentado con una mezcla de tabuladores y espacios debera reformatearse y usar espacios exclusivamente. Cuando se invoca el intrprete de lnea de comandos de Python con la opcin -t, este muestra avisos sobre cdigo que mezcla tabuladores y espacios. Cuando se utiliza -tt estos avisos se convierten en errores. Estas opciones son altamente recomendables! Para nuevos proyectos, se recomienda firmemente el uso de espacios en lugar de tabuladores. La mayora de los editores tienen caractersticas que hacen esto bastante sencillo.
class Rectangle(Blob): def __init__(self, width, height, color='black', emphasis=None, highlight=0): if width == 0 and height == 0 and \ color == 'red' and emphasis == 'strong' or \ highlight > 100: raise ValueError("sorry, you lose") if width == 0 and height == 0 and (color == 'red' or emphasis is None): raise ValueError("I don't think so") Blob.__init__(self, width, height, color, emphasis, highlight)
Lneas en blanco
Separa las funciones no anidadas y las definiciones de clases con dos lneas en blanco. Las definiciones de mtodos dentro de una misma clase se separan con una lnea en blanco. Se pueden usar lneas en blanco extra (de forma reservada) para separar grupos de funciones relacionadas. Las lneas en blanco se pueden omitir entre un grupo de funciones con una sola lnea (por ejemplo, con un conjunto de funciones sin implementacin). Usa lneas en blanco en las funciones, de forma limitada, para indicar secciones lgicas. Python acepta el caracter control-L (o lo que es lo mismo ^L) como un espacio en blanco; muchas herramientas utilizan este caracter como separador de pginas, por lo que puedes usarlos para separar pginas de secciones relacionadas en tu archivo.
Imports
import sys, os
aunque tambin es correcto hacer esto:
Deberas aadir una lnea en blanco despus de cada grupo de imports. Si es necesario especificar los nombres pblicos definidos por el mdulo con __all__ esto debera hacerse despus de los imports.
Es muy desaconsejable el uso de imports relativos para importar cdigo de un paquete. Utiliza siempre la ruta absoluta del paquete para todos los imports. Incluso ahora que el PEP 328 [7] est totalmente implementado en Python 2.5, el usar imports relativos se desaconseja seriamente; los imports absolutos son ms portables y normalmente ms legibles. Cuando importes una clase de un mdulo, normalmente es correcto hacer esto
if x == 4: print x, y; x, y = y, x
No:
if x == 4 : print x , y ; x , y = y , x
Inmediatamente antes de abrir un parntesis para una lista de argumentos de una llamada a una funcin: S:
spam(1)
No:
spam (1)
Inmediatamente antes de abrir un parntesis usado como ndice o para particionar (slicing):
S:
dict['key'] = list[index]
No:
x = 1 y = 2 long_variable = 3
No:
x = 1 y = 2 long_variable = 3
Otras Recomendaciones
Rodea siempre los siguientes operadores binarios con un espacio en cada lado: asignacin (=), asignacin aumentada (+=, -= etc.), comparacin (==, <, >, !=, <>, <=, >=, in, not in, is, is not), booleanos (and, or, not). Usa espacios alrededor de los operadores aritmticos: S:
i = i + 1 submitted += 1 x = x * 2 - 1 hypot2 = x * x + y * y c = (a + b) * (a - b)
No:
No:
if foo == 'blah': do_blah_thing() for x in lst: total += x while t < 10: t = delay()
Definitivamente no:
if foo == 'blah': do_blah_thing() else: do_non_blah_thing() try: something() finally: cleanup() do_one(); do_two(); do_three(long, argument, list, like, this) if foo == 'blah': one(); two(); three()
Comentarios
Los comentarios que contradicen el cdigo son peores que no tener ningn comentario. Manten siempre como prioridad el mantener los comentarios actualizados cuando cambies el cdigo! Los comentarios deberan ser frases completas. Si un comentario es una frase o sentencia, la primera palabra debera estar en maysculas, a menos que sea un identificador que comience con una letra en minsculas (nunca alteres el identificador sustituyendo maysculas o minsculas!). Si un comentario es corto, se puede omitir el punto al final. Los comentarios de bloque generalmente consisten en uno o ms prrafos construidos con frases completas, y cada frase debera terminar con un punto.
Deberas usar dos espacios despus de un punto de final de lnea. Cuando escribas en ingls, aplica las reglas de Strunk y White (N.T: Los autores de "The Elements of Style", un conocido libro de estilo de escritura en ingls). Para los programadores en Python que no sean de pases de habla inglesa: por favor escribe tus comentarios en ingls, a menos que ests un 120% seguro de que el cdigo nunca ser ledo por gente que no hable tu idioma.
Comentarios de bloque
Los comentarios de bloque generalmente se aplican al cdigo que se encuentra a continuacin, y se indentan al mismo nivel que dicho cdigo. Cada lnea de un comentario de bloque comienza con un # y un nico espacio (a menos que haya texto indentado dentro del comentario). Los prrafos dentro de un comentario de bloque se separan por una lnea conteniendo un nico #.
Comentarios en lnea
Utiliza comentarios en lnea de forma moderada. Un comentario en lnea es un comentario que se encuentra en la misma lnea que una sentencia. Los comentarios en lnea deberan separarse por al menos dos espacios de la sentencia que comentan. Deberan comenzar con un # y un espacio. Los comentarios en lnea son innecesarios y de hecho slo sirven para distraer si indican cosas obvias. No hagas cosas como esta:
x = x + 1
# Incrementa x
x = x + 1
Cadenas de Documentacin
Las convenciones para escribir buenas cadenas de documentacin (tambin llamados "docstrings") se inmortalizaron en elPEP 257 [3].
Escribe docstrings para todos los mdulos, functiones, clases, y mtodos pblicos. Los docstrings no son necesarios para mtodos no pblicos, pero deberas tener un comentario que describa lo que hace el mtodo. Este comentario debera aparecer antes de la lnea "def". El PEP 257 describe las convenciones para buenas cadenas de documentacin. Es importante notar, que el """ que finaliza un docstring de varias lneas debera situarse en una lnea separada, y preferiblemente precederse por una lnea en blanco, por ejemplo:
"""Return a foobang Optional plotz says to frobnicate the bizbaz first. """
Para cadenas de documentacin de una lnea, es adecuado mantener el """ de cierre en la misma lnea.
Convenciones de nombres
Las convenciones de nombres de la librera de Python son un pequeo desastre, as que nunca conseguiremos que sea completamente consistente -- an as, aqu tenis los estndares de nombrado recomendados en la actualidad. Los nuevos mdulos y paquetes (incluyendo los frameworks de terceras personas) deberan acomodarse a estos estndares, pero donde exista una librera con un estilo distinto, se prefiere la consistencia interna.
b (una sola letra en minsculas) B (una sola letra en maysculas) minusculas minusculas_con_guiones_bajos MAYUSCULAS MAYUSCULAS_CON_GUIONES_BAJOS PalabrasEnMayusculas (CapWords o CamelCase -- llamado as por el parecido de las maysculas con las jorobas de los camellos[4]). Algunas veces tambin se llaman StudlyCaps. Nota: Cuando se usan abreviaturas en CapWords, mantn en maysculas todas las letras de la abreviatura. Por lo tanto HTTPServerError es mejor que HttpServerError.
capitalizacionMezclada (se diferencia de PalabrasEnMayusculas porque la primera letra est en minsculas!) Mayusculas_Con_Guiones_Bajos (feo!)
Tambin existe un estilo en el cul se utiliza un prefijo nico corto para agrupar nombres relacionados de forma conjunta. Esto no se suele utilizar mucho en Python, pero se menciona con el objeto de que el texto sea lo ms completo posible. Por ejemplo, la funcin os.stat() devuelve una tupla cuyos elementos tradicionalmente han tenido nombres como st_mode, st_size, st_mtime y similares. (Esto se hace para enfatizar la correspondencia con los campos de la estructura de la llamada a sistema POSIX, lo cual es de utilidad para los programadores que estn familiarizados con ella.) La librera X11 utiliza una X inicial para todas sus funciones pblicas. En Python, este estilo generalmente se considera innecesario porque los atributos y mtodos se preceden por el objeto al que pertenencen, y los nombres de funciones se preceden del nombre del mdulo.
Adems se reconocen las siguientes formas especiales usando guiones bajos al inicio o final del nombre (generalmente estos se pueden combinar con cualquier convencin de capitalizacin):
_guion_bajo_al_inicio: indicador dbil de "uso interno". Por ejemplo " from M import *" no importa objetos cuyos nombres comiencen con un guin bajo. guion_bajo_al_final_: usado por convencin para evitar conflictos con palabras clave de Python, por ejemplo
Tkinter.Toplevel(master, class_='ClassName')
__doble_guion_bajo_al_inicio: cuando se use para nombrar un atributo de clase, invoca la caracterstica de "planchado de nombres" (dentro de la clase FooBar, __boo se convierte en _FooBar__boo; ver abajo). __doble_guion_bajo_al_inicio_y_fin__: objectos "mgicos" o atributos que viven en espacios de nombres controlados por el usuario. Por ejemplo __init__, __import__ o __file__. Nunca inventes nombres como estos; utilizalos slo como estn documentados.
Nombres de Clases
Casi sin excepciones, los nombres de clases usan la convencin CapWords. Las clases de uso interno tienen adems un guin bajo al principio del nombre.
Nombres de Excepciones
Dado que las excepciones deberan ser clases, se aplica la convencin relativa al nombrado de clases. De todas formas, deberas usar el sufijo "Error" en los nombres de las excepciones (si la excepcin es realmente un error).
(Esperamos que estas variables estn destinadas a ser usadas slo dentro de un mdulo.) Las convenciones son prcticamente las mismas que para las funciones. Los mdulos diseados para ser utilizados usando "from M import *" deberan usar el mecanismo __all__ para prevenir que se exporten variables globales, o bien usar la convencin antigua de aadir un guin bajo como prefijo a dichas variables globales (puede que quieras hacer esto para indicar que estas variables son "variables no pblicas del mdulo").
Nombres de Funciones
Los nombres de funciones deberan estar en letras minsculas, con palabras separadas mediante guiones bajos segn sea necesario para mejorar la legibilidad. Slo se acepta capitalizacionMezclada en contextos en los que ya se trate del estilo principal (por ejemplo threading.py), para mantener la compatibilidad hacia atrs.
No utilizamos el trmino "privado" aqu, dado que ningn atributo es realmente privado en Python (sin un trabajo aadido generalmente innecesario). Otra categora de atributos son aquellos que son parte de la "API de las subclases" (a menudo llamado "protected" en otros lenguajes). Algunas clases se disean para que se herede de ellas, bien para extender o bien para modificar aspectos del comportamiento de la clase. Cuando se disea una clase de esta forma, es necesario tomar algunas decisiones explcitas sobre qu atributos van a ser pblicos, cules son parte de la API de la subclase, y cules estn pensados para ser utilizados exclusivamente dentro de la clase actual. Teniendo esto en cuenta, aqu estn las lneas a seguir:
Los atributos pblicos no deberan tener guiones bajos al inicio del nombre. Si el nombre de tu atributo pblico colisiona con el de una palabra reservada, aade un nico guin bajo al final del nombre del atributo. Esto es preferible a abreviar o cambiar la grafa de la palabra. Nota 1: Ver la recomendacin anterior para mtodos de clase.
Para campos pblicos simples, es mejor exponer slo el nombre del atributo, sin complicaciones de mtodos para accederlos y modificarlos (accessors y mutators). Ten en cuenta que Python proporciona una forma sencilla de modificarlo, en caso de que dentro de un tiempo lo necesites. En ese caso, utiliza propiedades para ocultar la implementacin funcional con una sintaxis simple de acceso a atributos de datos. Nota 1: Las propiedades slo funcionan en las nuevas clases. Nota 2: Intenta mantener el comportamiento funcional libre de efectos colaterales, aunque funcionalidad colateral como el cacheo generalmente es aceptable. Nota 3: Evita usar propiedades para realizar operaciones que requieran de grandes clculos; el utilizar la notacin de atributos hace que la persona que accede al atributo piense que el acceso es (relativamente) barato en tiempo computacional.
El cdigo debera escribirse de forma que no pusiera en desventaja otras implementaciones de Python (PyPy, Jython, IronPython, Pyrex, Psyco, y similares). Por ejemplo, no te apoyes en la eficiencia de la implementacin de la concatenacin de cadenas con a+=b o a=a+b en CPython. Estas rdenes se ejecutan ms lentamente en Jython. En partes de la librera en las que el rendimiento sea importante, se debera utilizar en su lugar la forma ''.join(). Esto asegura que el tiempo necesario para la concatenacin es del mismo orden en diferentes implementaciones.
Las comparaciones con singletons como None siempre deberan llevarse a cabo con 'is' o 'is not', nunca con operadores de igualdad. Tambin es importante tener cuidado con escribir "if x" cuando lo que realmente queramos decir es "if x is not None" -- por ejemplo, cuando comprobemos si a una variable o argumento que tiene como valor por defecto None se le ha dado otro valor. El otro valor podra tener un tipo (como un contenedor) que podra ser falso en un contexto booleano!
Utiliza excepciones basadas en clases. Las excepciones en forma de cadenas estn prohibidas en el cdigo nuevo, dado que esta caracterstica del lenguaje se eliminar en Python 2.6.
Los mdulos o paquetes deberan definir sus propias clases excepcin especficas para el dominio del problema, las cuales deberan heredar de la clase Exception. Incluye siempre una cadena de documentacin para la clase. Por ejemplo:
Cuando lances una excepcin, utiliza "raise ValueError('mensaje')" en lugar de la forma antigua "raise ValueError, 'mensaje'". Se prefiere la forma con parntesis porque cuando los argumentos de la excepcin son largos o incluyen formateo de cadenas, no necesitas usar caracteres para indicar que contina en la siguiente lnea gracias a los parntesis. La forma antigua se eliminar en Python 3000.
Cuando captures excepciones, menciona excepciones especficas cuando sea posible en lugar de utilizar una clausula 'except:' genrica. Por ejemplo, utiliza:
try: value = collection[key] except KeyError: return key_not_found(key) else: return handle_value(value)
No:
try:
# Demasiado amplio! return handle_value(collection[key]) except KeyError: # Tambin capturar la excepcin KeyError lanzada por handle_value() return key_not_found(key)
Utiliza mtodos de cadenas en lugar del mdulo string. Los mtodos de las cadenas son siempre mucho ms rpidos y comparten la misma API con las cadenas unicode. Ignora esta regla si es necesaria compatibilidad hacia atrs con versiones de Python anteriores a la 2.0.
Utiliza ''.startswith() y ''.endswith() en lugar del particionado de cadenas para comprobar prefijos y sufijos. startswith() y endswith() son ms limpios y menos propensos a errores. Por ejemplo: S:
if foo.startswith('bar'):
No:
if foo[:3] == 'bar':
La excepcin a esta norma se da si es necesario que el cdigo funcione con Python 1.5.2 (esperemos que no lo necesites!).
Las comparaciones del tipo de objeto siempre deberan utilizar isinstance() en lugar de comparar tipos directamente. S:
if isinstance(obj, int):
No:
if type(obj) is type(1):
Cuando comprobemos si un objeto es una cadena, hay que tener en cuenta que puede que se trate de una cadena unicode! En Python 2.3, str y unicode tienen una clase padre comn, basestring, por lo que puedes usar:
if isinstance(obj, basestring):
En Python 2.2, el mdulo types define el tipo StringTypes para este propsito en concreto, por ejemplo:
if greeting:
No:
if greeting == True:
Peor:
if greeting is True:
Referencias