¿Cuáles son algunos de los mejores consejos para ahorrar tiempo para que Python escriba un código más conciso o “Pythonic”?

Advertencia: “ahorro de tiempo” es un término vago, especialmente para una base de código grande y / o en crecimiento compartida por muchos desarrolladores, debe tener cuidado de que el tiempo ahorrado por una persona al escribir código (p. Ej., Con una sola línea inteligente) no comprometa enormemente el tiempo que otras personas dedican a leerlo, a mantenerlo oa trabajar de otra manera. Esta respuesta aborda la pregunta en términos de ganancias de productividad más amplias en todo el equipo de software, a diferencia de los consejos y trucos para piratear el código Python lo más rápido posible.

  • Para Python idiomático, siéntase cómodo con las listas de comprensión, generadores, decoradores y gestores de contexto.
    – Las listas de comprensión son a menudo la forma más idiomática de crear y transformar listas.
    – Los generadores se utilizan con mayor frecuencia para definir los iteradores de manera limpia, generalmente con menos sobrecarga de memoria que las soluciones alternativas.
    – Los decoradores son excelentes para el código de configuración / limpieza común, como la autenticación, el almacenamiento en caché o el tiempo. Algunos decoradores @classmethod como @classmethod y @property son muy útiles cuando se trabaja con clases. Ver también: ¿Cuáles son los usos comunes de los decoradores de Python?
    – Los administradores de contexto también son útiles para el código de configuración / limpieza, por ejemplo al abrir y cerrar archivos o etiquetas (Quora los usa para asegurarse de que las etiquetas en HTML generadas desde WebNode siempre estén cerradas). Otro caso de uso interesante es establecer algún estado para la duración de un bloque de código, como indicadores para omitir el caché o para canalizar instrucciones en red.
  • Familiarícese con todos los métodos de las estructuras de datos más comunes: listas, conjuntos, diccionarios. Python tiene una gran cantidad de funcionalidades incorporadas útiles para trabajar con estas estructuras de datos, como el corte de listas o las operaciones de conjuntos matemáticos con azúcar sintáctica para un fácil uso en conjuntos.
  • Ejecutar fragmentos de código en un shell iPython. Aproveche al máximo el hecho de que Python tiene una gran shell interactiva: pruebe sus fragmentos de código rápidamente y juegue con la sintaxis o la lógica hasta que funcionen, inspeccione sus objetos y funciones, haga llamadas a las funciones de tiempo, etc. Asegúrese de usar iPython y no El shell estándar de Python, ya que iPython es mucho más poderoso y tiene características agradables como la tabulación y el %history .
  • Use una guía como PyFlakes, PyLint o PyChecker (comparación aquí: http://stackoverflow.com/questio…). Mejor aún, conecte su indicador a su editor para que lo revise a medida que avanza, de manera similar al análisis de código y al error o advertencia automática que resalta los IDE de Java.
  • Familiarícese con las bibliotecas estándar de Python , como urllib2 , time and datetime , random , itertools , functools , re , collections , etc. Consulte también: http://stackoverflow.com/questio.
  • Use sentencias de print y pdb para depurar. print es particularmente efectiva para usar en Python, ya que no necesita compilar su código nuevamente para comenzar a imprimir resultados de depuración útiles. En cuanto a pdb, simplemente descargue esto donde sea necesario para comenzar a investigar su programa en ejecución: import pdb; pdb.set_trace() import pdb; pdb.set_trace() ; y recorra / entre, continúe o imprima los valores que desee. Véase también: http://docs.python.org/library/p…
  • Adopte convenciones de nomenclatura sólidas para que su código se autodocumente . Por ejemplo, si tiene ID de usuario y objetos de usuario en su base de código, siempre use * _user_id para referirse al primero y * _user para referirse al último, por lo que siempre está claro si está trabajando con un int / long. ID o un objeto que es el objeto de usuario completo. (Este es un ejemplo que es particularmente destacado debido a la falta de anotaciones de tipo estático de Python). Y a menos que esté utilizando _ para i18n, use _ para indicar los valores que se deben desechar.

  • Use PyCharm, solo tiene numerosas funciones que le ahorran tiempo: refactorizar el código en variables, métodos, cambio de nombre en masa, cambio de parámetros en los métodos, análisis estático profundo a nivel de proyecto, pruebas y depuración integradas.
  • En Pinterest ejecutamos pyflakes y pep8 como parte de nuestras pruebas. Esto evita que nuestro código se vuelva extraño.
  • El paquete autopep8 tiene una marca -i que te permitirá corregir muchos errores pep8.
  • Considere la posibilidad de pylint o algo más configurable para un control más profundo.
  • Empaque cualquier y todas las bibliotecas como cosas, e instálelas a través de pip en lugar de mantenerlas en un solo repositorio.
  • Use los archivos virtualenv y pth para vincular a las bibliotecas “desprotegidas” si existen sobre las bibliotecas instaladas en pip. Esto te permitirá editar tus bibliotecas en su lugar.
  • Puedes desactivar la creación de Pyc, esto no siempre es beneficioso. [1]
  • Contribuya a proyectos de código abierto que tienen personas que escriben código que le resulten fáciles de leer y útiles. Puedes aprender mucho de ellos.
  • Comprenda algo del azúcar sintáctica de Python: listas de comprensión, generadores y comprensión de generador son muy útiles.
  • Aprenda qué métodos producen iteradores y cuándo usarlos (p. Ej., Diccionarios, xrange).
  • Obtener una idea de lo que proporciona la biblioteca estándar. colecciones, por ejemplo, es un placer.
  • Haga que las personas más familiarizadas con los diferentes aspectos del código de idioma revisen su código. Recibo mucho kilometraje al trabajar con personas que saben mucho de python, y me gusta cuando revisan mi código.

[1]: http://stackoverflow.com/questio

  • Comprenda las comprensiones de listas ( http://docs.python.org/tutorial/… ): muchos bucles `for` se pueden escribir de forma más clara y sucinta con esta construcción de lenguaje. O, más en general,
  • Comprenda los generadores ( http://docs.python.org/reference… ) ya que las comprensiones de listas son esencialmente generadores realizados en una lista. Las expresiones generadoras se pueden usar en muchos contextos donde la forma ingenua sería construir una lista en un bloque de código adicional. Una vez que entienda los generadores, aprenda sobre la biblioteca de itertools ( http://docs.python.org/library/i… ).
  • Entender las capacidades de la estructura de datos. Mis estructuras de datos subutilizadas favoritas son conjuntos ( http://docs.python.org/tutorial/… ) y Contadores ( http://docs.python.org/library/c… ), pero hay muchos más. Tratar de conceptualizar su problema en un dominio matemático a menudo hará que la solución sea fácil de escribir debido a la famosa estética de “psudo-código que se ejecuta” de Python. Esa estética frecuentemente proviene del soporte de la estructura de datos para operaciones comunes.
  • Aprender otro idioma. Clojure y Haskell (como ejemplos) te obligarán a escribir código más breve en muchos casos, y esa experiencia puede traducirse en un mejor código de Python. Solo asegúrate de que cuando vuelvas a Python, sigas las costumbres sociales de Python.

Aquí hay un ejemplo que trata de unirlos: encuentra el número de palabras diferentes entre dos partes de texto, a_str y b_str.

  a_words, b_words = [set (w.lower () para w en re.split ('\ W +', s)) para s en (a_str, b_str)]
 len (a_words ^ b_words)

Una expresión generadora se utiliza en la construcción de dos conjuntos. Se utiliza una lista de comprensión para ejecutar una transformación en las dos entradas. Las estructuras de datos repetibles pueden ser “desempaquetadas” o “desestructuradas” en múltiples variables. La noción matemática de diferencia de conjunto se usa para encontrar el conjunto de palabras diferentes.

Con mucho, la mejor manera de escribir Python al mismo tiempo es NO escribir Python.

Python, posiblemente más que cualquier otro lenguaje, tiene una amplia gama de bibliotecas, rutinas y módulos escritos por genios mucho más allá del conocimiento de los mortales. Están bien documentados y depurados y seleccionados por programadores muy serios. Y vienen en prácticamente todos los propósitos.

Cópialos, úsalos, enciérralos en tus programas.

Aquí hay una lista de muchos de ellos (de la excelente documentación de Python), y senderos a otros. ¡Úsalos sabiamente, y ahorrarán a un programador de Python serio años de trabajo!

Módulos útiles – Python Wiki

Para generar un montón de datos que son similares pero no iguales, recientemente encontré el acceso directo de este principiante en Codeacademy usando el desempaquetado de argumentos [1]:

  clase de perro:
     def __init __ (auto, nombre, edad, raza, color):
         self.name = name
         self.gender = género
         self.breed = raza
         self.color = color

 # crear los valores por defecto
 attrs = {"age": 7, "gender": "m", "breed": "mutt", "color": "motley"}

 #create chico perros
 Spuds = Dog ("Spuds", ** attrs)
 spike = Dog ("spike", ** attrs)

 #modificar sexo y obtener el resto de los datos predeterminados de forma gratuita
 attrs ["género"] = "f"

 #create chicas perros
 laika = Perro ("laika", ** attrs)
 lassy = Perro ("lassy", ** attrs) 

** attrs se desempaqueta en la lista que init está esperando.

Súper fácil de poner este concepto en un par de bucles y generar un montón de archivos de datos para probar varios mecanismos que necesitan datos en masa válidos (y no válidos, según sea necesario).

Sospecho que hay formas más eficientes de hacer esto y espero leer sobre ellos en los comentarios.

[1] Técnicas de Parámetros y Argumentos Sección 5

Algunas buenas sugerencias aquí, y agregaré algunas más que nadie más mencionó.

enumerar()

A veces desea que los elementos en una lista y un contador. Los siguientes son todos más o menos equivalentes.

  # Iterando con un contador
 para i en xrange (len (thelist)):
     v = la lista [i]
     ...

 # Manteniendo un contador    
 i = 0
 para v en la lista:
     ...
     i + = 1

 # Utilizando enumerar
 para i, v en enumerar (la lista):
    ...

sentencia por defecto

El módulo de “colecciones” de Pythons tiene un montón de herramientas muy útiles. Vale la pena explorar el paquete. Uno de mis favoritos y más usado es el defaultdict. Digamos que tenemos una lista de valores y queremos contar las ocurrencias de los elementos en la lista. (Concedido, ahora hay un “Contador” en las colecciones, pero tengan paciencia conmigo.) Esto funcionará:

  # Manera ingenua
 contador = {}
 para el artículo en la lista:
     Si el artículo en el contador:
         contador [item] + = 1
     más:
         contador [item] = 0

 # Usando get ()
 contador = {}
 para el artículo en la lista:
     contador [artículo] = contador.get (artículo, 0) + 1

 # Usando defaultdict
 contador = defaultdict (int)
 para el artículo en la lista:
     contador [item] + = 1

Como puede ver, también es útil conocer el método get () de dict … y defaultdict puede funcionar con muchos tipos. ¿Quieres un dictado de listas? Utilice “defaultdict (lista)”.

Incrustación de IPython

Se ha mencionado el uso de pdb, pero por lo general me gusta irrumpir en un lugar en particular con un shell IPython e ir a depurar desde allí. Recuerda estas dos líneas mágicas:

  importar IPython
 IPython.embed ()

¡Eso es! Solo tira eso donde quieras usar pdb.

Conocer sus tipos de datos.

¿Buscando un artículo en una lista? Su tiempo de ejecución es O (n).
Buscando una clave en un dict? El tiempo de ejecución es O (1).

¿Qué sucede si tiene una lista grande en la que va a hacer muchas búsquedas en un bucle y no le importan los duplicados en la lista?

  # Esto puede ser lento
 user_ids = get_user_ids_meeting_condition ()
 para t en transacciones:
     id_usuario = t ['id_usuario']
     Si user_id no está en user_ids:
          continuar
     ...

 # Acelerando las cosas con un set.
 user_ids = set (get_user_ids_meeting_condition ())
 para t en transacciones:
     id_usuario = t ['id_usuario']
     Si user_id no está en user_ids:
          continuar
     ...

El mismo código, pero ahora user_ids es un conjunto y las búsquedas son O (1) en lugar de O (n). ¿Moraleja de la historia? ¡No te olvides del set!

  • Documente su código con comentarios.

Esto debería explicarse por sí mismo, pero ayudará dramáticamente. Hay una línea muy fina entre hacerlo bien y tener demasiados comentarios. Lo que me gusta hacer es que, para cada módulo tengo una cadena de documentación en la parte superior y para cada función / método que no es extremadamente autoexplicativo (por ejemplo, una propiedad que devuelve una variable subyacente), tendré una breve descripción y describiré los argumentos y valor de retorno. Esto parece inútil a veces, pero hará que su código sea mucho más mantenible y legible para un tercero y para usted.

  • Usa el mismo estilo en todo

La forma en que pienso de esto es que si escribiera un libro, trataría de mantener el mismo estilo todo el tiempo. Si elijo usar la coma de Oxford, continuaré usándola. Si pongo dos espacios después de un periodo seguiré haciendo eso. Encuentro lo mismo con python especialmente porque los espacios en blanco son importantes y tienden a faltar paréntesis y corchetes para envolver las declaraciones. Entonces trato de seguir 80 caracteres por línea y cuando tengo saltos de línea, trato de seguir las mismas convenciones, especialmente cuando se pasan muchos argumentos a las funciones. De esta manera hace que sea mucho más fácil de leer cuando vuelvo a leerlo.

  • Usa algún tipo de IDE

Ya sea que se trate de complementos para VIM o PyCharm de pleno derecho, usar algo donde saltar a diferentes módulos es simple. Yo uso texto sublime 2 y es bastante excelente.

Supongo que ahorrar tiempo no significa ahorrar tiempo ahora, sino ahorrar tiempo después, evitando dificultades al depurar o refactorizar el código.

En este contexto, los consejos para ahorrar tiempo podrían ser:

– Nunca use importación * o importaciones relativas

– Evite duplicar nombres de directorio ascendente / descendiente en su árbol.

– Evitar locales () y globales ()

– Trate de no tener dependencias circulares, importe solo sobre los módulos. Las excepciones deben tener comentario explicativo.

– Dentro del mismo proyecto, importe en la fuente: no importe x de b si el código real está en a.

– No utilice valores param predeterminados cuando no se utiliza.

– Use los métodos y funciones _private por defecto para el método que no usa fuera del módulo o la clase.

– Considere cada construcción “if” concreta como un posible olor de código, candidato para un valor de configuración (“si no x: return” está bien, “si x es manzana: hacer cosas de Apple” no está bien, debería ser “do_fruit_stuff () ”

– Escuche con atención la mayor parte de lo que pylint le dirá, modifique su configuración si es necesario.

– No pase variables en caso de que puedan ser utilizadas en el futuro. Python es muy dúctil, agregar algo más tarde es casi siempre más fácil que eliminar más tarde algo que podría no ser inútil.

– Nunca escribas código verificable sin las pruebas.

Si usa PyCharm, aprenda la función de sugerencias de tipo de PyCharm y practíquelo. Encontrarás que su función de autocompletar será mucho más útil y ahorrará tiempo:

Tipo Hinting en PyCharm

Si está ejecutando el código Python a través de una consola (por ejemplo, pruebas unitarias), puede encontrar útil la siguiente receta: inicia automáticamente el depurador en una excepción [1]. Coloque el código en la ruta LIB / python2.X / sitecustomize.py para que esto funcione.

  importar bdb
 sistemas de importación

 Def info (tipo, valor, tb):
   si hasattr (sys, 'ps1') \
       o no sys.stdin.isatty () \
       o no sys.stdout.isatty () \
       o no sys.stderr.isatty () \
       o issubclass (type, bdb.BdbQuit) \
       o issubclass (type, SyntaxError):
     # estamos en modo interactivo o no tenemos un tty-like
     # dispositivo, por lo que llamamos el gancho por defecto
     sys .__ excepthook __ (tipo, valor, tb)
   más:
     trazabilidad de importación, pdb
     # NO estamos en modo interactivo, imprima la excepción ...
     traceback.print_exception (tipo, valor, tb)
     impresión
     # ... luego inicie el depurador en modo post-mortem.
     pdb.pm ()

 sys.excepthook = info

[1] La versión proporcionada aquí está un poco modificada según los comentarios de la receta; Está disponible como una esencia.

Haría lo contrario, no escribir código conciso, escribir código largo.

He estado allí, he escrito decenas de miles de líneas de Python, y ojalá hubiera sabido sobre cosas como mypy (Opcional Tipografía estática para Python), haría que su código de Python sea más largo y más legible. Si solo estás escribiendo unos pocos cientos de líneas o lo que sea, tal vez escríbalo brevemente si quieres, pero si quieres volver y entenderlo en unos pocos años, no uses los trucos, no trates de entenderlo. en tan pocas líneas como sea posible.

No le ahorrará una cantidad apreciable de tiempo para utilizar trucos concisos para acortar su código, ya que escribir no es el cuello de botella a menos que sea un teclista terrible, leer el código antiguo y comprenderlo sin duda es un cuello de botella.

Depuración rápida y sencilla:
importar pdb
pdb.set_trace ()

Rastreo de código en vivo:
$ python -m trace –trace myModule.py

Aquí hay algunos consejos que son más consejos relacionados con la experiencia en lugar de codificar paradigmas:

1. Utilice el editor VIM. VIM no es como los otros editores. Está lleno de atajos de teclado que ciertamente tienen una curva de aprendizaje, pero que te recompensa después de un tiempo.
2. Usa iPython como una cáscara interactiva. Es mejor que el shell básico de Python.
3. Haz un diseño antes de escribir un guión.
4. Utilice comentarios y cadenas de documentos para documentar sus scripts. Eso le ahorrará el tiempo y la comprensión del dolor de cabeza cuando vuelva a su código en una etapa posterior.

  1. Use conda en lugar de virtualenv si está tratando con numpy / scipy / pandas para evitar largos tiempos de compilación y requisitos de fortran.
  2. Usa la biblioteca de peticiones.
  3. Use los cuadernos PyCharm y Jupyter

Función dinámica de creación de llamadas mediante capacidades de introspección incorporadas o mediante el uso de llamadas exec ().

Lo anterior es un ahorro de tiempo de errores para aquellos que desean obtener cadenas externas y luego construirlas en callables. Aunque es una pesadilla de depuración, si no se hace bien.

Usa PyDev en Eclipse. No es perfecto, pero tener una interfaz incorporada y un depurador visual decente es una gran victoria que supera todas las desventajas de Eclipse.

http://pydev.org/

Aprecio la respuesta de Dave Dash
ed
% pdb
%cronométralo
%perfil

Hay unos cuantos comandos.

Aproveche su código con SQL