Categorías
Python

Cómo sacar el máximo provecho de PyCon

 

Tabla de Contenidos

  • Proyecto LayoutLicensingREADMEContributing Guidelinessetup.py
  • Licensing
  • README
  • Contribuir Directrices
  • setup.py
  • GitHubHandling Tire RequestsVersioning, ramificación, y los lanzamientos
  • Tire el manejo de solicitudes
  • de versiones, ramificación, y liberaciones
  • Documentación
  • Automatizar el código de calidad
  • Colaboración vs Cooperación
  • Resumen
  • Licensing
  • README
  • Contribuir Directrices
  • setup.py Tire Manejo
  • Pide
  • de versiones, ramificación, y los lanzamientos

Este es un puesto de invitado por Patrick Altman, un apasionado pirata informático de código abierto, y vicepresidente de ingeniería en Eldarion.

En este artículo vamos a diseccionar una aplicación de Django repetitivo destinado a desarrollar rápidamente proyectos de código abierto que se adhieren a las convenciones ampliamente compartidos.

La disposición (o patrón) que vamos a estar viendo se basa en django-Raya-pagos. En este diseño se ha probado con éxito por más de 100 proyectos de código abierto diferentes publicados por Eldarion y Pinax.

a medida que avanza a través de este artículo, tenga en cuenta que su proyecto específico puede variar de este patrón; Sin embargo, hay una serie de elementos que son bastante comunes entre los proyectos de Python, y para algunos proyectos de código abierto de titulación en general. Nos centraremos en estos artículos.

Proyecto Disposición

Un diseño de proyecto de buena ayuda a un nuevo usuario navegar por su código fuente. Hay ciertas convenciones que son comúnmente aceptadas, así que son importantes para acatar. Además, un buen diseño de proyecto ayuda con el empaquetado. diseños

Proyecto

diferirán un poco dependiendo de si son paquetes de Python (como una aplicación Django reutilizable) o algo así como un proyecto de Django. Utilizando nuestro proyecto de ejemplo, nos gustaría destacar algunos aspectos del diseño, así como los archivos incluidos en el nivel superior del proyecto.

Debe reservar la raíz de su proyecto para los archivos de metadatos que describen diversos aspectos de su proyecto, como una licencia, CONTRIBUTING.md, README.rst, así como las secuencias de comandos para ejecutar pruebas y embalajes. Además, debe haber una carpeta en este nivel de la raíz que se llama lo que quiere el nombre del paquete de Python que sea. En nuestro ejemplo django-Raya-pagos es pagos. Por último, debe almacenar la documentación como un proyecto basado Sphinx en una carpeta llamada docs.

Licensing

En general, es mejor para licenciar su software en el MIT permisiva o licencias BSD si su objetivo es la adopción más extendida posible. Cuanto mayor es la adopción, la mayor exposición en entornos del mundo real variaron que aumenta la oportunidad para la retroalimentación y la cooperación a través de solicitudes de extracción. Almacenar el contenido de la licencia en un archivo de licencia en la raíz de su proyecto.

README

Cada proyecto debe tener un archivo README.rst en la raíz del proyecto. En este documento se debe presentar brevemente el usuario al proyecto, describir lo que resuelve un problema, y ​​proporcionar una rápida guía de introducción.

Nombre que README.rst y lo puso en la raíz de tu repositorio GitHub y la mostrará en la página principal del proyecto para los usuarios potenciales para ver y hojear a través de obtener una idea rápida de cómo el software puede ayudar a ellos.

Usando reStructuredText en lugar de Markdown en el readme se recomienda para que muestre muy bien en PyPI si publica su paquete.

Contribuir archivo Directrices

Un CONTRIBUTING.md analiza el libro de estilo de código, los procesos y directrices para las personas que deseen contribuir código a través de solicitudes de tiro para su proyecto. Esto es útil en la reducción de la barrera para las personas que deseen contribuir código. contribuyentes de primera vez pueden estar nervioso acerca de hacer algo mal o fuera de convenciones y el más detallado de este documento es más se puede comprobar a sí mismos sin tener que hacer preguntas que pudieran ser demasiado tímido para preguntar.

setup.py

Un buen empaque ayuda a la distribución de su proyecto. Al escribir un script setup.py, puede aprovechar utilidades de paquetes de Python para crear y publicar su proyecto en PyPI.

Este es un script muy simple. Por ejemplo, aquí está el núcleo del guión de django-Raya-pagos:

PACKAGE = "payments"
NAME = "django-stripe-payments"
DESCRIPTION = "a payments Django app for Stripe"
AUTHOR = "Patrick Altman"
AUTHOR_EMAIL = "paltman@eldarion.com"
URL = "https://github.com/eldarion/django-stripe-payments"
VERSION = __import__(PACKAGE).__version__

setup(
    name=NAME,
    version=VERSION,
    description=DESCRIPTION,
    long_description=read("README.rst"),
    author=AUTHOR,
    author_email=AUTHOR_EMAIL,
    license="BSD",
    url=URL,
    packages=find_packages(exclude=["tests.*", "tests"]),
    package_data=find_package_data(PACKAGE, only_in_packages=False),
    classifiers=[
        "Development Status :: 3 - Alpha",
        "Environment :: Web Environment",
        "Intended Audience :: Developers",
        "License :: OSI Approved :: BSD License",
        "Operating System :: OS Independent",
        "Programming Language :: Python",
        "Framework :: Django",
    ],
    install_requires=[
        "django-jsonfield>=0.8",
        "stripe>=1.7.9",
        "django>=1.4",
        "pytz"
    ],
    zip_safe=False
)

Hay varias cosas que suceden aquí. Recuerda que hemos discutido haciendo el archivo reStructuredText README.rst?

Eso se debe a que como se puede ver por la long_description estamos utilizando el contenido de ese archivo para poblar la página de destino en PyPI y ese es el lenguaje de marcas utilizado allí. Los clasificadores son un conjunto de metadatos que ayuda a poner su proyecto en las categorías adecuadas en PyPI.

Por último, el argumento install_requires se asegurará de que cuando el paquete está instalado que estas dependencias enumeradas se instalan o que ya están instalados.

GitHub

Si el proyecto no está en GitHub que están realmente desaparecidas. Seguro que hay otros DVCS basada en Web (sistema distribuido de control de versiones) sitios que ofrecen alojamiento gratuito de código abierto, pero ninguno ha hecho más por la fuente abierta que GitHub.

Manipulación y jalar solicitudes

parte de la construcción de un gran proyecto de código abierto está haciendo más grande que uno mismo. Esto implica no sólo aumentar simplemente la base de usuarios, sino también la base de contribuyentes. GitHub (y git en general) realmente ha transformado cómo se hace esto.

Una clave para el aumento de contribuyentes es responder en la gestión de las solicitudes de extracción. Esto no significa aceptar todas las contribuciones, pero también permanecen abiertas las respuestas de mentalidad y mango con la deferencia que le gustaría recibir si contribuían a otro proyecto.

No sólo cerca de las solicitudes que no desee, pero toma el tiempo para explicar por qué no se acepta, o si es posible explicar cómo se pueden mejorar para que puedan ser exceptuados. Si las mejoras son menores o que de lo contrario se pueden mejorar por sí mismo, seguir adelante y aceptarlo y luego hacer las correcciones que le gustaría. Hay una línea muy fina entre pedir mejoras en comparación con sólo les hace a sí mismo.

El principio rector es crear un ambiente acogedor y agradecido. Recuerde que sus colaboradores están ofreciendo su tiempo y energía para mejorar su proyecto.

versiones, la ramificación, y los lanzamientos

Lea y siga semántica de versiones al crear versiones.

Al hacer grandes lanzamientos siempre documentar cambios incompatibles con claridad hacia atrás. Es más fácil si el documento cambia a medida que los está cometiendo mediante la actualización de un archivo de registro de cambios a medida que trabaja entre versiones. Este archivo podría ser simplemente un fichero de cambios en la raíz de su proyecto, o parte de su documentación en un archivo en algún lugar como docs / changelog.rst. Esto le permitirá crear agradables notas de la versión con muy poco esfuerzo.

mantener estable al maestro. Siempre existe la posibilidad de que la gente va a usar el código maestro en lugar de un comunicado de paquetes. Crear ramas de características para el trabajo y de mezcla cuando se probó y relativamente estable.

Documentación

Ningún proyecto es totalmente completa hasta que hay una cierta cantidad de documentación. Una buena documentación ahorra a los usuarios de tener que leer el código fuente para determinar cómo utilizar el software. Una buena documentación comunica que se preocupa por sus usuarios.

Con Leer la documentación, que puede tener la documentación de renderizado y alojado de forma gratuita de forma automática. Se actualizará automáticamente en cada confirmación de dominar que es super cool.

Para utilizar Leer los documentos, se debe crear un proyecto de documentación basada en la documentación Sphinx carpeta en la raíz de su proyecto. Esto realmente es una cosa bastante simple y consiste en un Makefile y un archivo conf.py y luego una colección de archivos reStructuredText formateado. Esto se puede hacer de forma manual copiando y pegando el archivo Makefile y conf.py de un proyecto anterior y la modificación de los valores, o ejecutando:

$ pip install Sphinx
$ sphinx-quickstart

Código Automatización de Calidad

Hay una serie de herramientas que puede utilizar para ayudar a la calidad torreón bajo control de sus proyectos. Pelusa, pruebas y cobertura de las pruebas de todo debe ser utilizado para ayudar a asegurar la calidad no se mueve durante la vida del proyecto.

de inicio con pelusa con algo como pylint o pyflakes o PEP8. Todos ellos tienen sus ventajas y desventajas, que están más allá del alcance de este artículo para explorar. Punto es: estilo coherente es el primer paso de un proyecto de alta calidad. Además, ayudando con el estilo de estos borra de pueden ayudar a identificar algunos errores simples rápidamente.

Por ejemplo, para django-Raya-pagos, tenemos un guión que combina dos herramientas que ejecutan diferentes pelusa con excepciones personalizadas para nuestro proyecto:

# lint.sh
pylint --rcfile=.pylintrc payments && pep8 --ignore=E501 payments

Tome un vistazo al archivo .pylintrc en los django-Raya-pagos para el reporto ejemplos de algunas de las excepciones. Una cosa acerca de pylint es que es bastante agresivo y puede ser ruidoso con las cosas son que realmente no son problemáticos. Es necesario decidir por sí mismo para ajustar su propio archivo .pylintrc pero recomienda la documentación y el archivo para que sepa más adelante por qué se está excluyendo ciertas reglas.

Configuración de una buena infraestructura de la prueba es importante para demostrar que sus obras de código. Por otra parte, escribiendo algunas de sus pruebas de primera puede ayudar a pensar a través de su API. Incluso si usted escribe pruebas último, el acto de escribir pruebas expondrá puntos débiles en el diseño de su API y / u otros problemas de usabilidad que se pueden abordar antes de que se informa.

Parte de su infraestructura de pruebas debe implicar el uso de coverage.py para mantener un ojo en la cobertura de un módulo. Esta herramienta no le dirá si el código es probado, sólo usted puede hacer eso, sino que le ayudará a identificar el código que no se ejecuta en absoluto para que sepa qué código es definitivamente no se está probando.

Una vez que haya desprendimiento de fibras, scripts de pruebas y de cobertura integrado en su proyecto puede automatización de la configuración para que estas herramientas ejecutar en cada pulsación en una entornos más (por ejemplo, versiones diferentes de Python, diferentes versiones de Django, o ambos en una matriz de prueba) .

La creación de una integración Travis puede ejecutar pruebas de forma automática y borra de. Batas pueden ser añadidos a esta configuración para proporcionar la cobertura de la prueba histórica cuando Travis construye plazo. Ambos tienen características que le permiten incrustar una insignia en su README.md para mostrar estado más reciente construcción y cobertura.

Colaboración vs Cooperación

Durante DjangoCon 2011, David Eaves dio un discurso de apertura que elocuentemente en palabras la idea de que a pesar de la colaboración y la cooperación tienen definiciones similares, hay una sutil diferencia:

“Yo diría que la colaboración, la cooperación a diferencia , obliga a las partes involucradas en un proyecto a resolver los problemas de forma conjunta “.

Aleros va a dedicar un post entero específicamente a la forma en GitHub fue la fuerza motriz para la innovación cómo el código abierto funciona de forma específica, el aspecto de la gestión de la comunidad. En “Cómo GitHub guardadas Open Source” (ver Recursos), Alero afirma:

“Creo proyectos de código abierto funcionan mejor cuando los colaboradores son capaces de participar en la cooperación de bajo costo de transacción y colaboración elevado coste de transacción se reduce al mínimo. El genio de código abierto es que no requiere un grupo de debatir todos los temas y trabajar en forma colectiva los problemas, sino todo lo contrario “.

Él va a hablar sobre el valor de bifurcación y cómo se reduce el alto costo de la colaboración al permitir la cooperación bajo costo entre las personas capaces de asumir proyectos adelante sin permiso. Este se bifurcan empuja la necesidad de coordinación hasta soluciones están listas para ser fusionado en, lo que permite mucho más rápido y dinámico experimentación.

Puede dar forma a su proyecto de manera similar, con el mismo objetivo de aumentar la cooperación bajo costo y reducir al mínimo la colaboración cara a lo largo de la escritura, el mantenimiento y el apoyo a su proyecto siguiendo las convenciones y los patrones detallados en este post.

Resumen

Muchas estaba cubierto aquí con pequeños ejemplos reales. La mejor manera de aprender acerca de estas cosas en detalle es para navegar por los repositorios en GitHub de proyectos que hacen un buen trabajo en estos patrones.

Pinax tiene su propio repetitivo aquí, que puede ser utilizado para generar rápidamente un proyecto basado en las convenciones y los patrones que se encuentran en este post.

Tenga en cuenta, que incluso si vas con nuestra repetitivo o algún otro texto modelo, tendrá que encontrar un estilo en la ejecución de estas cosas que se ajuste a usted y su proyecto. Todas estas cosas son, además de escribir el código real de su proyecto, pero todos ayudan en el crecimiento de una comunidad de colaboradores.

Categorías
Python

Gestores de contexto Python y el «con» Declaración

 

Tabla de Contenidos

  • ¿Qué pasó en PyCon África
  • principal Conferencia
  • Moustapha Cisse: El potencial de impacto positivo a través de AI
  • Meili Triantafyllidi: lecciones aprendidas de 6 años en PyLadies Berlín
  • caramelo Tricia Khohliwe: Web Realidad Virtual y a-Frame
  • Nicolás del Grosso: Revelación de los espaguetis (Consejos para Refactorizando Código)
  • Jessica Upani: Esta cosa es Python realmente de trabajo?
  • Kelvin Oyana: Bridging the Talent brecha entre Comunidades Python e Industria
  • Daniele Procida: más simple del mundo, más barato Plotter
  • Ewa Jodlowska: Keynote
  • Anna Makarudze: Lo que el desarrollador de África puede hacer para aumentar la diversidad en Tech
  • Panel

  • discusión: el papel del desarrollador Python africana en la Comunidad
  • Anthony Shaw: el destacarse en un mundo de 20 millones de desarrolladores
  • Cierre principal: Kojo Idrissa
  • Sprints Día
  • Resumen

PyCon África era una maravilla, inspirar, y técnicamente iluminar conferencia que tuvo lugar en Accra, Ghana, del 6 de agosto al 10 de 2019 en la Universidad de Ghana. Esta conferencia fue la primera conferencia panafricana para los desarrolladores de Python y asistieron 323 Pythonistas de 26 países diferentes. La mayoría de los asistentes viajaron desde países de todo África, y varios oradores procedían de los EE.UU., los Países Bajos, Alemania, Brasil e Italia.

Python se está convirtiendo cada vez más adoptado en todo el mundo. En África, Python está ganando un lugar especial para sí mismo, donde se utiliza ampliamente para el desarrollo web y la ciencia de datos. empresas africanas están buscando desarrolladores con conocimientos de Python en estas áreas, y tener un PyCon en África proporciona una base de apoyo para ayuda a los programadores de África. Bono

gratuito: 5 pensamientos sobre Python Maestría, un curso gratuito para los desarrolladores de Python que muestra la hoja de ruta y la mentalidad que necesita para tomar sus habilidades de Python al siguiente nivel.

¿Qué pasó en PyCon África

En el día antes de que comenzara la conferencia principal, los asistentes tomaron algún tiempo para adaptarse. Los que se acaban de cómo empezar con Python asistió a una sesión Día principiantes dirigido por Joey Darko para ayudar a establecer sus ordenadores para el desarrollo de Python. Me uní a otro grupo de viajeros internacionales en un recorrido de Accra, Ghana. Visitamos muchos lugares turísticos como la Plaza de la Independencia, el centro cultural, y algunos de los mercados locales para tener una idea de la forma de Ghana de la vida.

Al día siguiente se dedicó a talleres, y dos se ejecutan simultáneamente en ambas las sesiones de mañana y tarde. El taller de Django niñas introdujo las mujeres y los principiantes a Django Django desarrollo. Otros talleres se centraron en conceptos como la visualización de datos, pruebas y iteradores.

principal Conferencia

La conferencia principal se inició el 8 de agosto y se inició con una ceremonia de apertura que contó con la danza tradicional de Ghana y las palabras de bienvenida de Marlene Mhangami, el Presidente de África Python. Cada día de la conferencia tenía una apertura y cierre de la charla de apertura.

vamos a echar un vistazo a algunas de las conversaciones que se dieron durante los dos días de la conferencia.

Moustapha Cisse: El potencial de impacto positivo a través de AI

Moustapha Cisse es el jefe del centro de la IA de Google en Accra y él dio el discurso de apertura en el primer día de la conferencia principal. La charla de moustapha era acerca de cómo tecnólogos africanos pueden utilizar la tecnología para resolver los problemas africanos. En su charla, habló de algunos de los trabajos que está involucrado en por Google y en el espacio de AI, como el uso de inteligencia artificial para la predicción de la enfermedad, y las imágenes de satélite para reunir información y estadísticas para la predicción de crecidas permitido por la IA.

Meili Triantafyllidi: lecciones aprendidas de 6 años en Berlín PyLadies

Meili Triantafyllidi es el co-fundador de PyLadies Berlín. Hay una serie de PyLadies y mujeres centrada en los grupos de usuarios de Python alrededor de África. Estos grupos están haciendo un montón de trabajo increíble, pero como todo en la vida, siempre hay margen de mejora.

Meili Triantafyllidi dio una charla oportuna sobre las lecciones que aprendió de seis años de funcionamiento de PyLadies Berlín. En su charla, ella compartió consejos y las mejores prácticas para la fabricación de los eventos más inclusiva, accesible y seguro. Su charla también cubrió la información sobre cómo ejecutar eventos, obtener los altavoces de la derecha, y mejorar las habilidades de hablar en público. reunión

Un PyLadies se llevó a cabo después de la charla de Meili. La reunión estableció un propósito y planes de apoyo a programadores de las mujeres en África, en particular mediante la creación de un canal dedicado PyLadies África en los PyLadies grupo Slack común.

caramelo Tricia Khohliwe: Web Realidad Virtual y A-Frame

caramelo Khohliwe, un altavoz Tech Mozilla, dio una charla sobre WebVR, una tecnología abierta que le permite experimentar la realidad virtual en su navegador independientemente del dispositivo que utilice. El objetivo de la charla de caramelo era A-Frame, un framework de desarrollo web para crear experiencias 3D y WebVR utilizando HTML. A partir de esta charla informativa, he aprendido cómo usar A-Frame para crear y dibujar componentes WebVR. Estoy deseando probarlo en proyectos futuros!

Nicolás Del Grosso: Revelación de los espaguetis (Consejos para Refactorizando Código)

Nick Del Grosso dio una charla sobre la refactorización de código. Explicó cómo el código de proyecto puede causar problemas y nos llevó a través del proceso de refactorización de forma segura. También habló de las estrategias para la identificación de código muerto, elegir buenos nombres de variables, y el uso de herramientas de código ayuda refactor.

Jessica Upani: es esta cosa Python realmente de trabajo?

Jessica Upani de la comunidad de Namibia Python dio una charla instructiva sobre los diferentes grupos de la comunidad Python en Namibia. Se refirió a los desafíos que venció y qué lecciones otras comunidades pitón africana pueden aprender de ellos.

Kelvin Oyana: Bridging the Gap Talento entre las comunidades de Python y la charla de Industria

Kelvin estaba a punto de la línea divisoria entre lo que las empresas esperan de los desarrolladores y lo que los desarrolladores pueden hacer realidad. También ofreció una idea de cómo esto puede reducir la diferencia, tanto por las comunidades y los desarrolladores individuales.

Daniele Procida: más simple del mundo, más barato Plotter

Daniele Procida es un desarrollador del núcleo de Django y uno de los miembros del equipo de organización de PyCon África. En su charla, Daniele presentó un interesante proyecto: un simple plotter construyó utilizando cartón, un software de Raspberry Pi, algunos servomotores, y Python. Su proyecto encarna el espíritu de inventiva e innovación que caracteriza a la empresa africana.

Ewa Jodlowska: Keynote

Ewa Jodlowska, el Director Ejecutivo de la Fundación para el Software Python (PSF), dio una charla magistral sobre el PSF, cómo se trabaja con la comunidad mundial, y sus planes para el futuro. Ewa arrojar más luz sobre los diferentes programas de la PSF se ejecuta para fomentar el crecimiento de la comunidad Python, tales como el programa de patrocinio y el Programa Embajador Python en América del Sur.

Anna Makarudze: Lo que el desarrollador de África puede hacer para aumentar la diversidad en Tech

Anna Makarudze dio el discurso de cierre en el primer día de la conferencia principal. Ella es una Software Engineer en BriteCore (uno de los patrocinadores de diamantes de PyCon África), el vicepresidente de la Django Software Foundation, y el Coordinador de recaudación de fondos para la Fundación de Django niñas. Anna se basó en sus experiencias en estas organizaciones para discutir como conferencias, organizaciones y desarrolladores individuales pueden aumentar las cifras de diversidad en la tecnología.

Mesa redonda: El papel del desarrollador Python africana en el

Comunidad Hubo una discusión de grupo de líderes en los negocios, la tecnología y el desarrollo comunitario. Marlene Manghami moderó el debate sobre el papel de la comunidad Python africano en el espacio global de tecnología. Sus panelistas fueron Salomón Apenya, Daniel Roy Greenfeld, y James Yankah.

Salomón Apenya es un Consultor Senior en Andela, una empresa que distribuye hallazgos y construye equipos de ingeniería en África. Daniel Roy Greenfeld es co-autor de dos bolas de Django y vicepresidente de Ingeniería de Ejecución BriteCore. James Yankah es el director gerente de Brompton Group, un grupo de empresas que ofrecen servicios de reclutamiento, formación, gestión, logística y seguridad.

Anthony Shaw: El destacarse en un mundo de 20 millones de desarrolladores

En el último día de la conferencia, tuve el placer de conocer y escuchar a Anthony Shaw, un compañero de real del pitón autor. Anthony dio una charla dirigida a los nuevos desarrolladores para ayudarles a tener éxito en sus carreras de desarrollo. En la charla, Anthony discutió maneras de salir adelante, crecer su conjunto de habilidades, aprender nuevas tecnologías, y luchar contra la duda y el síndrome de impostor. Concluyó con consejos sobre cómo clavar entrevistas técnicas.

Cierre principal: Kojo Idrissa

El cierre de apertura sobre el último día de la conferencia fue dada por Kojo Idrissa, un organizador para DjangoCon y una Django Eventos Fundación América del Norte (DEFNA) Embajador. Kojo refleja en las lecciones del pasado y cómo la diáspora africana ha tenido un efecto en todos nosotros.

Día Sprints

El día después de la conferencia principal se dedica a carreras cortas! Aquí es donde el grupo de personas para trabajar en varios proyectos de código abierto Python. Yo era parte de un equipo que trabajó en cortador de galletas y otros proyectos relacionados. Presenté un PR que quedó fusionado en el proyecto y también me ayudó a mentora otros miembros del equipo.

recomiendo cualquiera que no ha asistido a una carrera de velocidad antes de hacerlo! Es una gran manera de practicar sus habilidades, contribuyen a un proyecto de código abierto, y conoce a los desarrolladores involucrados en el proyecto.

Resumen

PyCon África fue un gran éxito y nada menos que fantástico! Fue un comienzo bueno para la comunidad africana, ya que reunió, por primera vez, los desarrolladores de Python de las diferentes comunidades del pitón africana. Asimismo, ha permitido saber de representantes de la PSF sobre cómo la comunidad Python está organizado y financiado. Para muchos, esta fue la primera vez que las personas de las diferentes comunidades se reunieron en persona después de años de colaboración en línea.

Para mí, la experiencia valió la pena el sacrificio y el gasto porque llegué a conocer y hablar con gente de todo el mundo y aprender acerca de cómo utilizan Python en su trabajo o estudios. Di una charla relámpago sobre cómo enviar notificaciones en el escritorio de scripts de Python utilizando Python y otras herramientas nativas de Linux.

Otro punto a destacar de asistir a PyCon África fue que pude conocer a muchos de nuestros lectores, y un número de ellos atribuye su éxito a gran parte del contenido que leen aquí en real del pitón . Anthony Shaw y también me regalaron muchos real del pitón pegatinas. Aquí hay una foto que tomamos con Edison, un amigo y lector de real del pitón :

0190809_113244.149c0fd85db5.jpg»>

Uno de los problemas que enfrentan los organizadores de la conferencia estaba haciendo accesible a tantas personas como sea posible. Los viajes dentro de África es caro y difícil para muchos africanos. Por ejemplo, un visado de entrada a Ghana solo cuesta $ 100 a $ 200 dólares estadounidenses. Añadir a que el costo de los viajes y el alojamiento, y el evento estaba fuera del alcance de muchas personas que estaban interesadas en asistir. donaciones

voluntarias de individuos y el patrocinio empresarial de real del pitón , BriteCore, Andela, y varios otros patrocinadores ayudaron a cubrir el costo de los pasajes, alojamiento, viajes y para aquellos que lo necesitaban. Si desea hacer que la gente más africanos que participan en Python, y luego considerar el apoyo a futuros eventos de Python en África y la contratación de los desarrolladores africanos para trabajar de forma remota en sus equipos.

En el momento de escribir estas líneas, los vídeos de la conferencia no se han puesto a disposición, pero hay un video destacado que también incluye entrevistas con algunos de los asistentes. También puede leer el informe oficial de los organizadores de la conferencia. Si usted está pensando en asistir a una PyCon cerca de usted, a continuación, echa un vistazo a cómo obtener el máximo rendimiento de PyCon.

Categorías
Python

Inicio de sesión en Python

 

Tabla de Contenidos

  • Nuestro primer PyCon Junto
  • equipo InterviewsJim AndersonGeir Arne HjelleJames MertzDan Bader
  • Jim Anderson
  • Geir Arne Hjelle
  • James Mertz
  • Dan Bader
  • Resumen
  • Jim Anderson
  • Geir Arne Hjelle
  • James Mertz
  • Dan Bader

Hay muchas PyCons en todo el mundo cada año, pero el mayor de todos ellos es PyCon los Estados Unidos (Estados Unidos). Este año, más de 3.000 Pythonistas descendió en Cleveland, Ohio, para aprender, colaborar, contribuir, y encontrarse con viejos y nuevos amigos por igual. Estoy seguro que muchos de ustedes ya son conscientes de lo PyCon Estados Unidos es, pero si no, entonces sugeriría leer nuestra guía para PyCon para aprender más.

Nuestro primer PyCon Junto

Este año, real del pitón se dio la oportunidad de unirse a otros creadores de contenido en el stand PyCharm creadores de contenido, donde llegamos a pasar unos lectores de reuniones tiempo y miembros de la comunidad real del pitón . Ah, y nos dimos una tonelada de real del pitón pegatinas, y nos encontramos fuera de stock por completo! ¿Recibió el suyo?

El equipo también estaba excitado por nuestros autores Geir Arne Hjelle y Anthony Shaw, que estaban también allí como altavoces. Usted puede coger las grabaciones de sus conversaciones en plugins: añadiendo flexibilidad a las aplicaciones y Wily Python: La escritura más simple y más fácil de mantener Python en el canal de YouTube PyCon.

También tuvieron la suerte de ser capaz de organizar un espacio abierto real del pitón en PyCon para nuestros lectores. Tuvimos una excepcional participación, con 30 personas en asistencia.

Fue una gran oportunidad para nosotros, no sólo para llegar a agitar las manos y gracias por ayudarnos con su estímulo y retroalimentación, sino también para asegurarse de que podemos continuar empujando y producir mejor y un mejor contenido. Para escuchar la retroalimentación de los que asistieron fue una experiencia increíble, y nos va a tomar algunas de las ideas generadas de cara al futuro para ayudarnos a ofrecer una mejor experiencia de la lectura y el aprendizaje para usted.

A pesar de la conversación diaria en los grupos miembros y Slack personal, la mayoría del equipo real del pitón nunca había conocido en persona. Reunión cara a cara colegas y compartir una comida o una cerveza con ellos fue sin duda uno de los aspectos más destacados de toda la conferencia para mí personalmente.

Pero decidí a pedir al resto del equipo acerca de su experiencia, con la esperanza de que podríamos llegar a algunos consejos útiles consejos o acciones concretas para que en caso de que todavía tiene que asistir a su primera PyCon.

Hice las mismas tres preguntas a algunos de los miembros del equipo que asistieron a PyCon y cotejar sus respuestas a continuación. Las preguntas fueron: Entrevistas

equipo

sin más preámbulos, vamos a ver lo que tenían que decir.

Jim Anderson

estoy Jim Anderson, y yo soy un desarrollador de firmware embebido por día, trabajando principalmente en C ++ para las cámaras de seguridad de vídeo producen. Llego a hacer un poco de Python en el trabajo también. En real Python, soy un autor y un revisor técnico, por lo general tiende hacia los artículos que son ya sea de bajo nivel, herramienta relacionada, o temas generales CS.

Esta fue mi primera PyCon. Finalmente decidí ir simplemente debido a la emoción que estaba viendo al respecto en la comunidad real Python. La gente que sabía que habían sido previamente hablado hasta tanto. Tenían razón.

había tantos puntos destacados! Llegar a conocer finalmente a algunos de mis real Python compañeros de trabajo fue muy fresco, por supuesto, como era pasar un rato en la sección de contenido-creadores de la cabina PyCharm. (Gracias, JetBrains!)

yo diría que el mejor recuerdo que tengo, el que realmente solidificó la atmósfera en mi mente, estaba viendo un amigo de PythonistaCafe y PyCon hablar con alguien que estaba trabajando el lugar limpiando . Ella estaba tan tomada por la amabilidad de la conferencia que estaba preguntando por él y encontrar la manera de que pudiera ser una parte de ella el próximo año. Tal vez vamos a llegar a verla en Pittsburgh.

Hubo una charla que había programado para ir y sólo explotó el tiempo y se perdió. Fue la construcción de un páncreas artificial de código abierto, y todavía estoy decepcionado que no lo hacen. Es un gran tema y una gran charla.

Geir Arne Hjelle

Mi nombre es Geir Arne Hjelle, y me creció en un pequeño pueblo en el norte de Noruega. Actualmente, vivo en Oslo en la que trabajo con diferentes proyectos de ciencia de datos y aprendizaje automático. La mayoría de las veces, llego a utilizar Python y la excelente ciencia pila de datos construido encima de numpy.

he estado escribiendo para Python real desde la primavera de 2018, la mayoría de los paquetes y conceptos generales de Python. Mi primer artículo era sobre el paquete pathlib, y actualmente estoy trabajando en uno sobre el funcionamiento de las importaciones. Además, apoyo de otros autores al hacer una revisión de sus artículos, ambas revisiones contorno y revisiones técnicas.

Este año fue mi primera PyCon Estados Unidos. Vivo en Noruega, por lo que asistir a conferencias, principalmente en Europa. Esta caída, que estará en EuroSciPy por quinta vez. Sin embargo, después de unirse al equipo de real Python, yo estaba realmente tentado por la oportunidad de conocer a algunos de mis nuevos amigos y colegas en el medio silvestre.

James y yo consiguieron reunirse el pasado verano, pero por lo demás sabían todo el equipo por sus avatares holgura. Reunión y salir con el resto de la banda real Python, y nerding sobre algunos de los comentarios que hemos hecho el uno al otro son grandes recuerdos que atesorará durante mucho tiempo.

Hay tanto que sucede en PyCon. Fui todo en y me quedé por los tutoriales, la conferencia principal, y partes de las pruebas de velocidad. Me gustó mucho todo.

Los tutoriales eran grandes, incluyendo inmersión profunda de David Beazley en el cálculo lambda. (¡Sí, las matemáticas!) Tuve la suerte de llegar a dar una charla durante la conferencia, que fue muy divertido. Yo estaba muy bien cuidado antes de mi presentación: Creo que esta es la primera vez que he tenido mi propia habitación para las preparaciones, y alguien me caminando hacia la sala de presentación.

Posteriormente, tengo algunas preguntas muy agradables e interesantes. Durante las pruebas de velocidad, tengo que ayudar un poco en la nueva biblioteca importlib.metadata Jason Coombs y Barry Varsovia están armando para Python 3.8. Fue genial ver de primera mano cómo algunos de los desarrolladores principales están trabajando.

Tenía tantas grandes experiencias en Cleveland que es difícil pensar en cosas que no tengo la oportunidad de hacerlo. Si bien, voy a admitir que en este PyCon, estaba bastante centrado en mí mismo (especialmente con ser mi charla durante la última sesión de la conferencia).

La próxima vez, voy a dejar de lado algún tiempo para ser voluntario y asegúrese de que para apoyar el funcionamiento de la conferencia más que yo en esta ocasión. Fue genial ver cómo todo el mundo aportó: Me dieron la bienvenida y nos registramos por Ernest W. Durbin III, que era también el presidente de toda la conferencia.

James Mertz

estoy James Mertz, y soy un Ingeniero de Software Assurance en el Jet Propulsion Laboratory (JPL). Actualmente estoy trabajando en el proyecto Europa Clipper, que es un satélite que será orbitando alrededor de Júpiter y hacer viajes muy cerca cerca de la luna Europa. He estado escribiendo por Python real alrededor de un año ahora con temas que van desde la documentación de Python a cómo sacar el máximo provecho de PyCon.

Este es mi cuarto año en PyCon, por lo que estoy empezando a conocer a mi camino alrededor de la conferencia, aunque cada año es lo suficientemente diferente para mantener traerme de vuelta. Este año fue de lejos el mejor para mí por dos razones: el voluntariado y reunirse con la banda real Python (tanto los autores y los lectores).

En mi guía sobre cómo obtener el máximo rendimiento de PyCon, realmente poner un enfoque en ser voluntario en PyCon. Me di cuenta de que, mientras que yo había hecho algunas cosas en los últimos años, realmente no había practicado lo que predicaba. Decidí aceptar plenamente este y trataba de ayudar en todo lo que podía.

Al final de la conferencia, que tuvo:

  • sido un “gorila” tutorial para inmersión profunda de David Beazley en cálculo lambda
  • Ayudado con registro de entrada en el registro e incluso llegó a comprobar en Michael Kennedy desde Python Bytes y charlas Python para mí
  • Hecho la bolsa de botín relleno de baile en línea DJ-ed por Larry Hastings
  • sido un corredor personal de sesión (la persona que hace que el altavoz está en la habitación a tiempo)
  • Has estado en una silla personal de sesión (la persona quien introduce el altavoz)

a pesar de todo, he hecho algunas conexiones muy sorprendentes y sentí gran poder contribuir un poco a la comunidad que tanto amo.

Hablando de la comunidad, reunirse con la comunidad real Python fue otro momento muy importante. Como autores, realmente no conseguimos muchas oportunidades para reunirse con cada otra cara a cara. Por lo tanto, para cumplir finalmente con algunas de las personas que he llegado a conocer tan bien digitalmente, en el mundo físico, era una experiencia surrealista. Lo que hizo que era mejor que, a pesar de que estábamos todos de diferentes lugares del mundo con diferentes experiencias de la vida, hemos sido capaces de construir rápidamente un espíritu de equipo.

Tal vez incluso mejor que conocer a mis otros miembros del equipo real del pitón , que se reunía, los lectores. Llevamos a cabo nuestra primera real del pitón espacio abierto, donde muchos de los que se detuvo a conversar. Como autor de un editor digital, es difícil a veces para conectar con la gente que usted está escribiendo para, pero para mí, que se ha convertido en más fácil.

experiencia PyCon de este año fue en general bastante equilibrado como llegué a hacer un montón de redes, viendo charlas y tutoriales, e incluso el voluntariado. Lo único que podía pensar que me gustaría poder haber hecho era dar una presentación de algún tipo. Eso es lo que el próximo año es de embargo.

Dan Bader

Hey yo soy Dan Bader, y yo soy el dueño y editor en jefe aquí en real Python. También hago todo el back-end y el desarrollo de front-end para el CMS basado en Django y otras infraestructuras que se ejecuta en realpython.com.

Soy un largo tiempo de Pythonista y super apasionada sobre la enseñanza de Python. Publicar mi propio libro de programación Python fue un sueño de toda la vida y llegar a ejecutar real del pitón junto con un equipo impresionante ahora es la guinda del pastel!

Este año fue mi quinta PyCon, y no será el último, eso es seguro …

mis mejores momentos personales estaban colgando con el equipo tutorial real Python y conocer a muchos de ellos en persona por primera vez. Eso hizo que mi corazón saltar! Fuimos a buscar comida y bebidas un par de noches, y una memoria aleatoria que yo probablemente nunca olvido es averiguar cuánto Logan ama el espectáculo chicas de oro de TV: – D

Durante el día, los buenos chicos de JetBrains dio nosotros algo de espacio en su stand PyCharm, por lo que todos tenemos que llevar nuestra botín real Python y charlar con los lectores, así como la mano pegatinas y pines. Eso fue super divertido!

Otra gran memoria es el espacio abierto real Python organizamos donde varias docenas de lectores y miembros presentaron para decir “hola”. Que acaba de soplar mi mente y fue una de mis experiencias favoritas PyCon hasta ahora!

me sentí bastante quemado cuando llegué por primera vez en PyCon después de trabajar sin parar durante un par de meses en el lanzamiento de nuestras suscripciones función de video, y al ver esta participación masiva sentía increíble. Realmente no sé qué decir al principio! Gracias a todos por parar cerca 🙂

Este año fue también la segunda vez que fuimos anfitriones de un Meetup-espacio abierto para el foro PythonistaCafe , y fue super cool para ver cómo este proyecto poco loco ha provocado tal muy unida y temible comunidad ahora.

Otro punto a destacar fue la grabación en vivo de un episodio del podcast Talk Python junto con Mike Kennedy. Siempre una delicia salir con este chico 🙂

Ojalá hubiera tenido más tiempo para ir a las conversaciones. Me quedé muy impresionado con las conversaciones que Geir Arne y Anthony de la Tutorial Equipo real del pitón dio. Asegúrese de revisar las grabaciones cuando se tiene la oportunidad.

feliz Pythoning, y nos vemos el próximo año!

Resumen

Independientemente de la ubicación, un PyCon es una experiencia gozosa. Si usted es Colegas de la reunión, amigos en línea, o extraños que comparten una pasión que no sea Python, que es la gente que hacen que la experiencia especial. El viejo dicho, “vino de la lengua, pero se quedó para la comunidad” no es más cierto que en PyCon Estados Unidos.

No hay dos Pythonistas son los mismos, y hay algo para todos en la diversidad de los eventos, charlas y tutoriales que tienen lugar. En lo personal, yo estoy deseando PyCon del próximo año ya. Horario lo permite, voy a hacer todo lo posible para unirse a las pruebas de velocidad en 2020. Sin embargo, incluso si no consigo que marque eso de mi lista, ya sé que el año que viene voy a estar emocionado de conocer a usted y muchos otros, a pesar de mi introversión.

si estuviera en PyCon Estados Unidos y llegó a decir “hola”, o se unió a nosotros para los espacios abiertos pitón real o PythonistaCafe , a continuación, dejar un comentario a continuación y háganos saber lo que era su parte favorita de PyCon. ¿Cuál es tu un consejo le daría a alguien que asistirá a cualquier PyCon por primera vez el año que viene? codificación feliz!

Categorías
Python

Acelerar su programa de Python con la Concurrencia

 

Tabla de Contenidos

  • básico SetupWhat que realmente está pasando aquí?
  • Lo que realmente está pasando aquí? de
  • deje correr las cosas en paralelo
  • Una cuestión importante a considerar
  • Embalaje para arriba de
  • Lo que realmente está pasando aquí?

Bienvenido!

los artículos de esta serie:

    Parte

  • 1: Pruebas asíncrono con Django y PyVows (artículo actual)
  • Parte 2: Pruebas unitarias con pyVows y Django
  • Parte 3: Las pruebas de integración con pyVows y Django

repo: TDD-Django

PyVows es un puerto del desarrollo votos populares comportamiento impulsado (o BDD) marco para Node.js. Para este artículo me centraré en el uso de PyVows y selenio para ejecutar las pruebas de interfaz gráfica de usuario contra Django, y en el siguiente artículo de esta serie, voy a hablar de las pruebas unitarias con PyVows.

Antes de empezar, tómese un minuto para leer este artículo que describe las diferencias entre el comportamiento impulsado y desarrollo basado en pruebas. El trabajo de instalación de

básico

Vamos a través de un conjunto de ejemplos. Iniciar un nuevo proyecto de Django (con virtualenvwrapper, django-pyVows y selenio):

$ mkvirtualenv TDD-Django --no-site-packages
$ workon TDD-Django
$ pip install pyVows django django-pyVows selenium lxml cssselect
$ django-admin.py startproject tddapp

Esta configuración es todo lo que necesitamos por ahora. Vamos a crear nuestra primera prueba GUI con pyVows añadiendo uitests.py a tddapp, y luego añadir el siguiente código:

from pyvows import Vows, expect
from django_pyvows.context import DjangoHTTPContext
from selenium import webdriver

@Vows.batch
class TDDDjangoApp(DjangoHTTPContext):

def get_settings(self):
return "tddapp.settings"

def topic(self):
self.start_server()
browser = webdriver.Firefox()
browser.get(self.get_url("/"))
return browser

def should_prompt_the_user_with_a_login_page(self, topic):
expect(topic.title).to_include('Django')

Lo que realmente está pasando aquí?

el inicio de las importaciones de prueba todas las bibliotecas necesarias, como pyvows, django_pyvows y selenio:

from pyvows import Vows, expect
from django_pyvows.context import DjangoHTTPContext
from selenium import webdriver

La siguiente línea crea lo que en pyVows que se conoce como un lote de prueba. Un lote de prueba en pyVows se identifica por el decorador @ Vows.batch y es sinónimo de unittest.TestCase en el módulo de prueba de unidad de la biblioteca estándar de Python.

lotes de prueba

son contextos que describen diferentes componentes y estados que desea probar. En general, un lote de prueba heredará del Vows.Context pero en nuestro caso estamos heredando de DjangoHTTPContext como esa clase proporciona toda la funcionalidad del ayudante al horno en django_pyvows. Además de la herencia de DjangoHTTPContext necesita sobrescribir los get_settings función () y devolver la ruta de acceso al archivo de settings.py que desea utilizar para ejecutar las pruebas:

@Vows.batch
class TDDDjangoApp(DjangoHTTPContext):

def get_settings(self):
return "tddapp.settings"

Cada contexto debe contener un solo tema, que es el el objeto que desee prueba y un número de votos que realizan las pruebas en contra de dicho tema. Para nuestro tema empezamos el servidor Django usando la función auxiliar start_server (), el fuego de selenio y selenio punto a la raíz de nuestra aplicación Django. Entonces, ya que esta es una prueba de interfaz gráfica de usuario, nuestro tema devuelve el WebDriver selenio para que podamos ejecutar nuestras pruebas.

Nota: self.get_url ( «/») traduce la dirección URL relativa a la URL absoluta que necesitamos para acceder al sitio.

A continuación, nuestros primeros cheques voto / prueba para ver si el título de la página incluye ‘Django’:

def topic(self):
self.start_server()
browser = webdriver.Firefox()
browser.get(self.get_url("/"))
return browser

def should_prompt_the_user_with_a_django_page(self, topic):
expect(topic.title).to_include('Django')

Ejecución de la prueba en este punto debe pasar, porque la página por defecto en Django tiene un título de “Bienvenido a Django” . Esto verifica que nuestra configuración básica es correcta y podemos seguir adelante y empezar a programar algo. La salida de la ejecución de la prueba es el siguiente: la atención

$ pyVows -vvv uitests.py

============
Vows Results
============

Tdd django app
✓ should prompt the user with a django page
✓ OK » 1 honored • 0 broken (2.489381s)

And a failed test would look like this:

$ pyVows -vvv uitests.py

============
Vows Results
============

Tdd django app
✗ should prompt the user with a django page
Expected topic(u'Page Not Found') to include 'Login'

...snipping Traceback to save space...

✗ OK » 0 honored • 1 broken (2.489381s)

atención a la denominación de las pruebas en el informe. La línea indentada más exterior es el contexto (TDDDjangoApp), con cada voto / test en ese contexto que aparece y debajo de sangría. Esto hace que la presentación de informes y la búsqueda de defectos muy fácil, ya que se lee como una serie de requisitos. Considere el siguiente informe:

$ pyVows -vvv uitests.py

============
Vows Results
============

Tdd django app
on Chrome
✓ should prompt the user with a django page
on Firefox
✗ should prompt the user with a django page

...snipping Traceback to save space...

✗ OK » 1 honored • 1 broken (3.119354s)

En el ejemplo ficticio anterior, podemos ver que nuestra configuración está funcionando forChrome y no en Firefox. Así, mediante el uso de nombres intuitiva de las pruebas, pyVowsproduces un informe simple pero altamente eficaz para la localización de problemas. de

deje correr las cosas en paralelo

Además se están acercando a la prueba paralela asíncrona en varios navegadores! Vamos a echar un vistazo al código de la prueba que se habría producido ese informe:

@Vows.batch
class TDDDjangoApp(DjangoContext):

class OnFirefox(DjangoHTTPContext):

def get_settings(self):
return "tddapp.settings"

def topic(self):
self.start_server(port=8888)
browser = webdriver.Firefox()
browser.get(self.get_url("/"))
return browser

def should_prompt_the_user_with_a_django_page(self, topic):
expect(topic.title).to_include('string not in the title')

class OnChrome(DjangoHTTPContext):

def get_settings(self):
return "tddapp.settings"

def topic(self):
self.start_server(port=8887)
browser = webdriver.Chrome()
browser.get(self.get_url("/"))
return browser

def should_prompt_the_user_with_a_django_page(self, topic):
expect(topic.title).to_include('Django')

En pyVows, hermanos contextos son ejecutados en contextos paralelos y anidadas se ejecutan de forma secuencial – lo que significa TDDDjangoApp sería ejecutado primero, y luego sus dos contextos anidados OnFirefox y OnChrome serían ejecutados en paralelo (porque son hermanos de la otra). sin embargo, podemos eliminar una gran parte del código duplicado mediante la creación de un conjunto estándar de pruebas y ejecutar esas pruebas contra múltiples contextos. La programación funcional

def onBrowser(webdriver, port):
class BrowserTests(DjangoHTTPContext):

def get_settings(self):
return "tddapp.settings"

def topic(self):
self.start_server(port=port)
browser = webdriver()
browser.get(self.get_url("/"))
return browser

def should_prompt_the_user_with_a_django_page(self, topic):
expect(topic.title).to_include('Django')

return BrowserTests

@Vows.batch
class TDDDjangoApp(DjangoContext):

class OnChrome(onBrowser(webdriver.Chrome, 8887)):
pass

class OnFirefox(onBrowser(webdriver.Firefox, 8888)):
pass

class OnPhantonJS(onBrowser(webdriver.PhantomJS, 8886)):
pass

al rescate! (Bueno, algo así …) Una de las ventajas de Python es que no estará sujeto a un paradigma de programación en particular. Así que podemos usar una variedad de soluciones. En este caso, queremos crear dinámicamente un contexto de prueba para cada navegador y el puerto que queremos ejecutar las pruebas en contra.

Para hacer esto podemos escribir todas nuestras pruebas una vez (en la clase BrowserTests, que se devuelve por la función OnBrowser). Lo bueno de esta técnica es que la función tema () en las declaraciones de clase BrowserTests cualquier WebDriver (también conocido como navegador) que se pasa a la función onBrowser.

Desde aquí nuestro lote de prueba (denotado por @ Vows.batch) es simplemente describiendo lo que será RAN / informó. La salida de los cuales sería el siguiente:

============
Vows Results
============

Tdd django app
On phantom js
✓ should prompt the user with a django page
On chrome
✓ should prompt the user with a django page
On firefox
✓ should prompt the user with a django page
✓ OK » 3 honored • 0 broken (4.068020s)

Con esta configuración cada prueba añadimos a la clase BrowserTests se ejecutará againsteach navegador especificamos. Por ejemplo, si añadimos las siguientes pruebas para la clase theBrowserTests …

def heading_should_tell_the_user_it_worked(self,topic):
heading_text = topic.find_element_by_css_selector("#summary h1").text
expect(heading_text).to_equal("It worked!")

def should_display_debug_message(self,topic):
explain_text = topic.find_element_by_id("explanation").text
expect(explain_text).to_include("DEBUG = True")

… entonces el informe mostraría:

============
Vows Results
============

Tdd django app
On firefox
✓ should prompt the user with a django page
✓ heading should tell the user it worked
✓ should display debug message
On chrome
✓ heading should tell the user it worked
✓ should prompt the user with a django page
✓ should display debug message
On phantom js
✓ should prompt the user with a django page
✓ should display debug message
✓ heading should tell the user it worked
✓ OK » 9 honored • 0 broken (4.238522s)

Una cuestión importante a considerar

Usted puede preguntarse por qué, sin embargo, estamos llamando start_server por cada nuevo contexto. En realidad no tenemos que hacer esto, pero estamos trabajando en torno a una limitación de django_pyvows. Desafortunadamente la función DjangoHTTPContext.start_server () crea un solo hilo, lo que disminuye el rendimiento. Para este conjunto de pruebas, por ejemplo, tiempo de ejecución aumenta desde unos 5 segundos (lo escrito anteriormente) a aproximadamente 21 segundos si sólo crean un servidor CherryPy.

Lo ideal sería que desee crear un solo servidor de prueba en contra y perhapsmake el servidor multi-hilo, de modo que no tenemos que incurrir en el performancepenalty. Así que vamos a ver si podemos hacer que eso ocurra. En primer lugar la actualización del código Let TheTest utilizar pyVows noción de contexto herencia tan sólo tenemos que createthe servidor una vez.

def onBrowser(webdriver):
class BrowserTests(DjangoHTTPContext):

def topic(self):
browser = webdriver()
browser.get(self.get_url("/"))
return browser

def should_prompt_the_user_with_a_login_page(self, topic):
expect(topic.title).to_include('Django')

return BrowserTests

@Vows.batch
class TDDDjangoApp(DjangoHTTPContext):

def get_settings(self):
return "tddapp.settings"

def topic(self):
self.start_server()

class OnChrome(onBrowser(webdriver.Chrome)):
pass

class OnFirefox(onBrowser(webdriver.Firefox)):
pass

class OnPhantonJS(onBrowser(webdriver.PhantomJS)):
pass

Aviso cómo el contexto TDDDjangoApp ahora llama start_server () de su topicfunction y ya no hay necesidad de pasar de un puerto a nuestra función contextcreation onBrowser (). Ahora tenemos una única versión del servidor de instantiate theCherryPy y ejecutar todas las pruebas en contra de eso. Esto tiene la ventaja de utilizar menos resourcesand hace que el código sea más fácil de mantener.

para lidiar con el problema de rendimiento, que puede manejar manualmente los hilos para obtener pruebas que se ejecutan más rápido:

def onBrowser(webdriver):
class BrowserTests(DjangoHTTPContext):

def topic(self):
webdriver.get(self.get_url("/"))
return webdriver

def teardown(self):
webdriver.quit()

def should_prompt_the_user_with_a_login_page(self, topic):
expect(topic.title).to_include('Django')

return BrowserTests

@Vows.batch
class TDDDjangoApp(DjangoHTTPContext):

def get_settings(self):
return "tddapp.settings"

def topic(self):
self.start_server()
#manual add some more threads to the CherryPy server
self.server.thr.server.requests.grow(3)

def teardown(self):
#clean up the threads so we can exit cleanly
self.server.thr.server.requests.stop(timeout=1)

class OnChrome(onBrowser(webdriver.Chrome())):
pass

class OnFirefox(onBrowser(webdriver.Firefox())):
pass

class OnPhantonJS(onBrowser(webdriver.PhantomJS())):
pass

Hemos hecho tres cosas aquí. En primer lugar, en la función de tema () hemos añadido tres morethreads a grupo de subprocesos de CherryPy:

def topic(self):
self.start_server()
#manual add some more threads to the CherryPy server
self.server.thr.server.requests.grow(3)

En segundo lugar, era necesario asegurarse de que los hilos se limpiaron o la prueba de runwill nunca es completa.

def teardown(self):
#clean up the threads so we can exit cleanly
self.server.thr.server.requests.stop(timeout=1)

Por último, aseguró que WebDriver limpia después de sí mismo mediante la adición de una función de desmontaje a nuestra clase BrowserTest:

def teardown(self):
webdriver.quit()

Embalaje para arriba de

nodo no es el único juego en la ciudad que se pueden hacer las cosas de forma asíncrona. Y con el puerto de Vows.js a pyVows y un poco de ingenio podemos obtener pruebas en paralelo con varios navegadores para Django en marcha con muy poco esfuerzo.

Teniendo esto un paso más allá, que podría vincularse a algo así como BrowserMob o SauceLabs a prueba contra un gran número de navegadores y entonces las cosas sería realmente comenzar a ponerse interesante. Además, con sencillo, fácil de entender que informa y una sintaxis muy limpia, sus pruebas de interfaz gráfica de usuario puede llegar a ser (relativamente) indoloro y rápido!

El código utilizado para este artículo se puede encontrar en el repositorio de Github asociado.

me dejó saber lo que piensa en los comentarios a continuación. ¡Salud!

Categorías
Python

Proyecto de Python para principiantes: Bitcoin Precio Notificaciones

 

Tabla de Contenidos

  • Estimado Pythonic Santa Claus … Funciones
  • recursivas en Python
  • mantener estructuras de Estado
  • recursiva de datos en Python
  • Naive La recursividad es ingenuo
  • molestos detalles
  • Fin
  • Referencias

reloj ahora Este tutorial tiene un curso de vídeo relacionado creado por el equipo del real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: Pensando de forma recursiva en Python

“De todas las ideas que he introducido a los niños, la recursividad se destaca como la idea de que es particularmente capaz de provocar una respuesta emocionados”

Seymour Papert, Mindstorms

problemas (en la vida y también en la informática) a menudo pueden parecer grande y aterrador. Pero si seguimos saltando lejos en ellos, más a menudo que no podemos romperlos en trozos más pequeños lo suficientemente trivial para resolver. Esta es la esencia de pensar de forma recursiva, y mi objetivo en este artículo es proporcionar usted, mi querido lector, con las herramientas conceptuales necesarias para abordar los problemas desde este punto de vista recursiva.

Juntos, vamos a aprender a trabajar con la recursividad en nuestros programas de Python por el dominio de conceptos tales como funciones recursivas y estructuras de datos recursivas. También hablaremos de mantener el estado durante la recursividad y evitar el recálculo almacenamiento en caché de resultados. Esto va a ser muy divertido. ¡Adelante y hacia arriba!

Estimado Pythonic Santa Claus …

Soy consciente de que como compañero de Pythonistas estamos todos los adultos que consienten aquí, pero los niños parecen asimilar la belleza de la recursividad mejor. Así que vamos a no ser adultos aquí por un momento y hablar sobre cómo podemos utilizar la recursividad para ayudar a Santa Claus.

alguna vez se preguntó cómo se entregan los regalos de Navidad? Claro que tengo, y creo que Santa Claus tiene una lista de casas que recorre. Él va a una casa, cae fuera de los presentes, se come las galletas y la leche, y se mueve a la siguiente casa en la lista. Dado que este algoritmo para la entrega de regalos se basa en una construcción de bucle explícita, se llama un algoritmo iterativo.

El algoritmo para la presente entrega iterativo implementado en Python:

houses = ["Eric's house", "Kenny's house", "Kyle's house", "Stan's house"]

def deliver_presents_iteratively():
for house in houses:
print("Delivering presents to", house)
>>> deliver_presents_iteratively()
Delivering presents to Eric's house
Delivering presents to Kenny's house
Delivering presents to Kyle's house
Delivering presents to Stan's house

pero me siento para Santa. A su edad, no debería tener que entregar todos los regalos por él mismo. Propongo un algoritmo con el que se puede dividir el trabajo de entrega de regalos entre sus duendes:

  • > 1 Él es un director y puede nombrar dos elfos y dividir su trabajo entre ellos
  • = 1 Es un trabajador y tiene que ofrecer los regalos a la casa asignada a él

Esta es la estructura típica de un algoritmo recursivo. Si el problema actual representa un caso simple, resolverlo. Si no es así, dividirlo en subproblemas y aplicar la misma estrategia a ellos.

El algoritmo recursivo para la entrega presente implementado en Python: Funciones

houses = ["Eric's house", "Kenny's house", "Kyle's house", "Stan's house"]

# Each function call represents an elf doing his work
def deliver_presents_recursively(houses):
# Worker elf doing his work
if len(houses) == 1:
house = houses[0]
print("Delivering presents to", house)

# Manager elf doing his work
else:
mid = len(houses) // 2
first_half = houses[:mid]
second_half = houses[mid:]

# Divides his work among two elves
deliver_presents_recursively(first_half)
deliver_presents_recursively(second_half)
>>> deliver_presents_recursively(houses)
Delivering presents to Eric's house
Delivering presents to Kenny's house
Delivering presents to Kyle's house
Delivering presents to Stan's house

recursivas en Python

Ahora que tenemos un poco de intuición acerca de la recursividad, vamos a introducir la definición formal de una función recursiva. Una función recursiva es una función definida en términos de sí mismo a través de expresiones auto-referenciales.

Esto significa que la función continuará llamando a sí mismo y repetir su comportamiento hasta que se cumpla alguna condición para devolver un resultado. Todas las funciones recursivas comparten una estructura común formada por dos partes: caso base y caso recursivo.

Para demostrar esta estructura, vamos a escribir una función recursiva para calcular n !:

descomponer el problema original en los casos más sencillos de un mismo problema. Este es el caso recursivo:

n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3 x 2 x 1
n! = n x (n−1)!

A medida que el gran problema se descompone en los sucesivamente menos complejos, esos subproblemas deben eventualmente se vuelven tan simples que se pueden resolver sin una mayor subdivisión. Este es el caso base:

n! = n x (n−1)!
n! = n x (n−1) x (n−2)!
n! = n x (n−1) x (n−2) x (n−3)!


n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3!
n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3 x 2!
n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3 x 2 x 1!

Aquí, 1! es nuestro caso base, y es igual a 1. Función

recursiva para calcular n! implementado en Python:

def factorial_recursive(n):
# Base case: 1! = 1
if n == 1:
return 1

# Recursive case: n! = n * (n-1)!
else:
return n * factorial_recursive(n-1)
>>> factorial_recursive(5)
120

Detrás de las escenas, cada llamada recursiva agrega un marco de pila (que contiene su contexto de ejecución) a la pila de llamadas hasta llegar al caso base. A continuación, la pila empieza a relajarse, ya que cada llamada devuelve sus resultados:

Manteniendo el estado

Cuando se trata de las funciones recursivas, tenga en cuenta que cada llamada recursiva tiene su propio contexto de ejecución, por lo que para mantener el estado durante la recursividad tiene ya sea a:

  • Pase el estado a través de cada llamada recursiva para que el estado actual es parte del contexto de ejecución de la llamada actual
  • Mantener el estado en el ámbito global

Una demostración debe hacer las cosas más claras. Vamos a calcular 1 + 2 + 3 + 10 ⋅⋅⋅⋅ utilizando la recursividad. El estado que tenemos que mantener es (número actual estamos añadiendo, suma acumulada hasta ahora) .

Así es como se hace eso por roscado a través de cada llamada recursiva (es decir, pasando el actual estado actualizado para cada llamada recursiva como argumentos):

def sum_recursive(current_number, accumulated_sum):
# Base case
# Return the final state
if current_number == 11:
return accumulated_sum

# Recursive case
# Thread the state through the recursive call
else:
return sum_recursive(current_number + 1, accumulated_sum + current_number)
# Pass the initial state
>>> sum_recursive(1, 0)
55

Así es como se mantiene el estado manteniéndolo en el ámbito global:

# Global mutable state
current_number = 1
accumulated_sum = 0

def sum_recursive():
global current_number
global accumulated_sum
# Base case
if current_number == 11:
return accumulated_sum
# Recursive case
else:
accumulated_sum = accumulated_sum + current_number
current_number = current_number + 1
return sum_recursive()
>>> sum_recursive()
55

prefiero enhebrar el estado a través de cada llamada recursiva porque encuentro estado mutable mundial a ser malo, pero eso es una discusión para otro momento. Estructuras

recursiva de datos en la estructura de datos de Python

A es recursivo si puede ser definido en términos de una versión más pequeña de sí mismo. Una lista es un ejemplo de una estructura de datos recursiva. Permítanme demostrar. Suponga que tiene solamente una lista vacía a su disposición, y la única operación que se puede realizar en la misma es la siguiente:

# Return a new list that is the result of
# adding element to the head (i.e. front) of input_list
def attach_head(element, input_list):
return [element] + input_list

Uso de la lista vacía y la operación attach_head, puede generar cualquier lista. Por ejemplo, vamos a generar [1, 46, -31, «hola»]:

attach_head(1, # Will return [1, 46, -31, "hello"]
attach_head(46, # Will return [46, -31, "hello"]
attach_head(-31, # Will return [-31, "hello"]
attach_head("hello", [])))) # Will return ["hello"]
[1, 46, -31, 'hello']

A partir de una lista vacía, se puede generar cualquier lista mediante la aplicación recursiva de la función attach_head, y por lo tanto la estructura de datos de lista pueden definirse de forma recursiva como:

+---- attach_head(element, smaller list)
list = +
+---- empty list

recursión también puede ser visto como composición de la función auto-referencial. Aplicamos una función a un argumento, a continuación, pasar a ese resultado en como argumento para una segunda aplicación de la misma función, y así sucesivamente. Repetidamente componer attach_head consigo mismo es el mismo que attach_head hace llamar repetidamente.

Lista

no es la estructura de datos única recursiva. Otros ejemplos incluyen la serie, árbol, diccionario, etc. estructuras de datos recursivas

y funciones recursivas van juntos como el pan y la mantequilla. La estructura de la función recursiva a menudo puede ser modelada después de la definición de la estructura de datos recursiva que toma como entrada. Permítanme demostrar esto calculando la suma de todos los elementos de una lista recursiva:

def list_sum_recursive(input_list):
# Base case
if input_list == []:
return 0

# Recursive case
# Decompose the original problem into simpler instances of the same problem
# by making use of the fact that the input is a recursive data structure
# and can be defined in terms of a smaller version of itself
else:
head = input_list[0]
smaller_list = input_list[1:]
return head + list_sum_recursive(smaller_list)
>>> list_sum_recursive([1, 2, 3])
6

recursividad Naive es un número

El Fibonacci Naive fueron originalmente definida por el Fibonacci matemático italiano en el siglo XIII para modelar el crecimiento de las poblaciones de conejo. Fibonacci conjeturó que el número de pares de conejos nacidos en un año dado es igual al número de pares de conejos nacidos en cada uno de los dos años anteriores, a partir de un par de conejos en el primer año.

para contar el número de conejos nacidos en el año enésimo, que de fi ne la relación de recurrencia:

Fn = Fn-1 + Fn-2

Los casos base son: escritura de

F0 = 0 and F1 = 1

Let una función recursiva para calcular el enésimo número de Fibonacci:

def fibonacci_recursive(n):
print("Calculating F", "(", n, ")", sep="", end=", ")

# Base case
if n == 0:
return 0
elif n == 1:
return 1

# Recursive case
else:
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)
>>> fibonacci_recursive(5)
Calculating F(5), Calculating F(4), Calculating F(3), Calculating F(2), Calculating F(1),
Calculating F(0), Calculating F(1), Calculating F(2), Calculating F(1), Calculating F(0),
Calculating F(3), Calculating F(2), Calculating F(1), Calculating F(0), Calculating F(1),

5

Ingenuamente después de la recursivas definición del enésimo número de Fibonacci era bastante ineficiente. Como se puede ver en la salida anterior, estamos recalcular los valores innecesariamente. Vamos a tratar de mejorar fibonacci_recursive almacenamiento en caché de los resultados de cada cálculo de Fibonacci Fk:

from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci_recursive(n):
print("Calculating F", "(", n, ")", sep="", end=", ")

# Base case
if n == 0:
return 0
elif n == 1:
return 1

# Recursive case
else:
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)
>>> fibonacci_recursive(5)
Calculating F(5), Calculating F(4), Calculating F(3), Calculating F(2), Calculating F(1), Calculating F(0),

5

lru_cache es un decorador que almacena en caché los resultados. De esta manera, evitamos recálculo comprobando de forma explícita por el valor antes de intentar calcularlo. Una cosa a tener en cuenta sobre lru_cache es que ya que utiliza un diccionario para resultados de caché, los argumentos posicionales y de palabras clave (que sirven como claves en ese diccionario) a la función debe ser hashable.

molestos detalles

Python no tiene soporte para la eliminación de llamada final. Como resultado, puede causar un desbordamiento de pila si al final el uso de marcos de pila más que la profundidad de la pila de llamadas predeterminado:

>>> import sys
>>> sys.getrecursionlimit()
3000

Tenga en cuenta esta limitación si tiene un programa que requiere la repetición de profundidad.

Además, las estructuras de datos mutables de Python no admiten el intercambio estructural, por lo que tratarlos como estructuras de datos inmutables va a afectar negativamente a su espacio y GC (recolección de basura) la eficiencia, ya que van a terminar innecesariamente copiar una gran cantidad de objetos mutables . Por ejemplo, he utilizado este modelo para descomponer listas y recursivo sobre ellos:

>>> input_list = [1, 2, 3]
>>> head = input_list[0]
>>> tail = input_list[1:]
>>> print("head --", head)
head -- 1
>>> print("tail --", tail)
tail -- [2, 3]

lo hice para simplificar las cosas por el bien de la claridad. Tenga en cuenta que la cola se crea copiando. Recursiva haciendo que más grandes listas pueden afectar negativamente a su espacio y la eficiencia GC.

Fin

Una vez me preguntaron para explicar la recursividad en una entrevista. Tomé una hoja de papel y escribí favor vuelca en ambos lados. El entrevistador no tuvo la broma, pero ahora que ha leído este artículo, esperamos que pueda hacer feliz Pythoning!

Referencias

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del Real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: Pensamiento de forma recursiva en Python

Categorías
Python

Crear una aplicación matraz con Google Login

 

Tabla de Contenidos

  • Estimado Pythonic Santa Claus … Funciones
  • recursivas en Python
  • mantener estructuras de Estado
  • recursiva de datos en Python
  • Naive La recursividad es ingenuo
  • molestos detalles
  • Fin
  • Referencias

reloj ahora Este tutorial tiene un curso de vídeo relacionado creado por el equipo del real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: Pensando de forma recursiva en Python

“De todas las ideas que he introducido a los niños, la recursividad se destaca como la idea de que es particularmente capaz de provocar una respuesta emocionados”

Seymour Papert, Mindstorms

problemas (en la vida y también en la informática) a menudo pueden parecer grande y aterrador. Pero si seguimos saltando lejos en ellos, más a menudo que no podemos romperlos en trozos más pequeños lo suficientemente trivial para resolver. Esta es la esencia de pensar de forma recursiva, y mi objetivo en este artículo es proporcionar usted, mi querido lector, con las herramientas conceptuales necesarias para abordar los problemas desde este punto de vista recursiva.

Juntos, vamos a aprender a trabajar con la recursividad en nuestros programas de Python por el dominio de conceptos tales como funciones recursivas y estructuras de datos recursivas. También hablaremos de mantener el estado durante la recursividad y evitar el recálculo almacenamiento en caché de resultados. Esto va a ser muy divertido. ¡Adelante y hacia arriba!

Estimado Pythonic Santa Claus …

Soy consciente de que como compañero de Pythonistas estamos todos los adultos que consienten aquí, pero los niños parecen asimilar la belleza de la recursividad mejor. Así que vamos a no ser adultos aquí por un momento y hablar sobre cómo podemos utilizar la recursividad para ayudar a Santa Claus.

alguna vez se preguntó cómo se entregan los regalos de Navidad? Claro que tengo, y creo que Santa Claus tiene una lista de casas que recorre. Él va a una casa, cae fuera de los presentes, se come las galletas y la leche, y se mueve a la siguiente casa en la lista. Dado que este algoritmo para la entrega de regalos se basa en una construcción de bucle explícita, se llama un algoritmo iterativo.

El algoritmo para la presente entrega iterativo implementado en Python:

houses = ["Eric's house", "Kenny's house", "Kyle's house", "Stan's house"]

def deliver_presents_iteratively():
for house in houses:
print("Delivering presents to", house)
>>> deliver_presents_iteratively()
Delivering presents to Eric's house
Delivering presents to Kenny's house
Delivering presents to Kyle's house
Delivering presents to Stan's house

pero me siento para Santa. A su edad, no debería tener que entregar todos los regalos por él mismo. Propongo un algoritmo con el que se puede dividir el trabajo de entrega de regalos entre sus duendes:

  • > 1 Él es un director y puede nombrar dos elfos y dividir su trabajo entre ellos
  • = 1 Es un trabajador y tiene que ofrecer los regalos a la casa asignada a él

Esta es la estructura típica de un algoritmo recursivo. Si el problema actual representa un caso simple, resolverlo. Si no es así, dividirlo en subproblemas y aplicar la misma estrategia a ellos.

El algoritmo recursivo para la entrega presente implementado en Python: Funciones

houses = ["Eric's house", "Kenny's house", "Kyle's house", "Stan's house"]

# Each function call represents an elf doing his work
def deliver_presents_recursively(houses):
# Worker elf doing his work
if len(houses) == 1:
house = houses[0]
print("Delivering presents to", house)

# Manager elf doing his work
else:
mid = len(houses) // 2
first_half = houses[:mid]
second_half = houses[mid:]

# Divides his work among two elves
deliver_presents_recursively(first_half)
deliver_presents_recursively(second_half)
>>> deliver_presents_recursively(houses)
Delivering presents to Eric's house
Delivering presents to Kenny's house
Delivering presents to Kyle's house
Delivering presents to Stan's house

recursivas en Python

Ahora que tenemos un poco de intuición acerca de la recursividad, vamos a introducir la definición formal de una función recursiva. Una función recursiva es una función definida en términos de sí mismo a través de expresiones auto-referenciales.

Esto significa que la función continuará llamando a sí mismo y repetir su comportamiento hasta que se cumpla alguna condición para devolver un resultado. Todas las funciones recursivas comparten una estructura común formada por dos partes: caso base y caso recursivo.

Para demostrar esta estructura, vamos a escribir una función recursiva para calcular n !:

descomponer el problema original en los casos más sencillos de un mismo problema. Este es el caso recursivo:

n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3 x 2 x 1
n! = n x (n−1)!

A medida que el gran problema se descompone en los sucesivamente menos complejos, esos subproblemas deben eventualmente se vuelven tan simples que se pueden resolver sin una mayor subdivisión. Este es el caso base:

n! = n x (n−1)!
n! = n x (n−1) x (n−2)!
n! = n x (n−1) x (n−2) x (n−3)!


n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3!
n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3 x 2!
n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3 x 2 x 1!

Aquí, 1! es nuestro caso base, y es igual a 1. Función

recursiva para calcular n! implementado en Python:

def factorial_recursive(n):
# Base case: 1! = 1
if n == 1:
return 1

# Recursive case: n! = n * (n-1)!
else:
return n * factorial_recursive(n-1)
>>> factorial_recursive(5)
120

Detrás de las escenas, cada llamada recursiva agrega un marco de pila (que contiene su contexto de ejecución) a la pila de llamadas hasta llegar al caso base. A continuación, la pila empieza a relajarse, ya que cada llamada devuelve sus resultados:

Manteniendo el estado

Cuando se trata de las funciones recursivas, tenga en cuenta que cada llamada recursiva tiene su propio contexto de ejecución, por lo que para mantener el estado durante la recursividad tiene ya sea a:

  • Pase el estado a través de cada llamada recursiva para que el estado actual es parte del contexto de ejecución de la llamada actual
  • Mantener el estado en el ámbito global

Una demostración debe hacer las cosas más claras. Vamos a calcular 1 + 2 + 3 + 10 ⋅⋅⋅⋅ utilizando la recursividad. El estado que tenemos que mantener es (número actual estamos añadiendo, suma acumulada hasta ahora) .

Así es como se hace eso por roscado a través de cada llamada recursiva (es decir, pasando el actual estado actualizado para cada llamada recursiva como argumentos):

def sum_recursive(current_number, accumulated_sum):
# Base case
# Return the final state
if current_number == 11:
return accumulated_sum

# Recursive case
# Thread the state through the recursive call
else:
return sum_recursive(current_number + 1, accumulated_sum + current_number)
# Pass the initial state
>>> sum_recursive(1, 0)
55

Así es como se mantiene el estado manteniéndolo en el ámbito global:

# Global mutable state
current_number = 1
accumulated_sum = 0

def sum_recursive():
global current_number
global accumulated_sum
# Base case
if current_number == 11:
return accumulated_sum
# Recursive case
else:
accumulated_sum = accumulated_sum + current_number
current_number = current_number + 1
return sum_recursive()
>>> sum_recursive()
55

prefiero enhebrar el estado a través de cada llamada recursiva porque encuentro estado mutable mundial a ser malo, pero eso es una discusión para otro momento. Estructuras

recursiva de datos en la estructura de datos de Python

A es recursivo si puede ser definido en términos de una versión más pequeña de sí mismo. Una lista es un ejemplo de una estructura de datos recursiva. Permítanme demostrar. Suponga que tiene solamente una lista vacía a su disposición, y la única operación que se puede realizar en la misma es la siguiente:

# Return a new list that is the result of
# adding element to the head (i.e. front) of input_list
def attach_head(element, input_list):
return [element] + input_list

Uso de la lista vacía y la operación attach_head, puede generar cualquier lista. Por ejemplo, vamos a generar [1, 46, -31, «hola»]:

attach_head(1, # Will return [1, 46, -31, "hello"]
attach_head(46, # Will return [46, -31, "hello"]
attach_head(-31, # Will return [-31, "hello"]
attach_head("hello", [])))) # Will return ["hello"]
[1, 46, -31, 'hello']

A partir de una lista vacía, se puede generar cualquier lista mediante la aplicación recursiva de la función attach_head, y por lo tanto la estructura de datos de lista pueden definirse de forma recursiva como:

+---- attach_head(element, smaller list)
list = +
+---- empty list

recursión también puede ser visto como composición de la función auto-referencial. Aplicamos una función a un argumento, a continuación, pasar a ese resultado en como argumento para una segunda aplicación de la misma función, y así sucesivamente. Repetidamente componer attach_head consigo mismo es el mismo que attach_head hace llamar repetidamente.

Lista

no es la estructura de datos única recursiva. Otros ejemplos incluyen la serie, árbol, diccionario, etc. estructuras de datos recursivas

y funciones recursivas van juntos como el pan y la mantequilla. La estructura de la función recursiva a menudo puede ser modelada después de la definición de la estructura de datos recursiva que toma como entrada. Permítanme demostrar esto calculando la suma de todos los elementos de una lista recursiva:

def list_sum_recursive(input_list):
# Base case
if input_list == []:
return 0

# Recursive case
# Decompose the original problem into simpler instances of the same problem
# by making use of the fact that the input is a recursive data structure
# and can be defined in terms of a smaller version of itself
else:
head = input_list[0]
smaller_list = input_list[1:]
return head + list_sum_recursive(smaller_list)
>>> list_sum_recursive([1, 2, 3])
6

recursividad Naive es un número

El Fibonacci Naive fueron originalmente definida por el Fibonacci matemático italiano en el siglo XIII para modelar el crecimiento de las poblaciones de conejo. Fibonacci conjeturó que el número de pares de conejos nacidos en un año dado es igual al número de pares de conejos nacidos en cada uno de los dos años anteriores, a partir de un par de conejos en el primer año.

para contar el número de conejos nacidos en el año enésimo, que de fi ne la relación de recurrencia:

Fn = Fn-1 + Fn-2

Los casos base son: escritura de

F0 = 0 and F1 = 1

Let una función recursiva para calcular el enésimo número de Fibonacci:

def fibonacci_recursive(n):
print("Calculating F", "(", n, ")", sep="", end=", ")

# Base case
if n == 0:
return 0
elif n == 1:
return 1

# Recursive case
else:
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)
>>> fibonacci_recursive(5)
Calculating F(5), Calculating F(4), Calculating F(3), Calculating F(2), Calculating F(1),
Calculating F(0), Calculating F(1), Calculating F(2), Calculating F(1), Calculating F(0),
Calculating F(3), Calculating F(2), Calculating F(1), Calculating F(0), Calculating F(1),

5

Ingenuamente después de la recursivas definición del enésimo número de Fibonacci era bastante ineficiente. Como se puede ver en la salida anterior, estamos recalcular los valores innecesariamente. Vamos a tratar de mejorar fibonacci_recursive almacenamiento en caché de los resultados de cada cálculo de Fibonacci Fk:

from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci_recursive(n):
print("Calculating F", "(", n, ")", sep="", end=", ")

# Base case
if n == 0:
return 0
elif n == 1:
return 1

# Recursive case
else:
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)
>>> fibonacci_recursive(5)
Calculating F(5), Calculating F(4), Calculating F(3), Calculating F(2), Calculating F(1), Calculating F(0),

5

lru_cache es un decorador que almacena en caché los resultados. De esta manera, evitamos recálculo comprobando de forma explícita por el valor antes de intentar calcularlo. Una cosa a tener en cuenta sobre lru_cache es que ya que utiliza un diccionario para resultados de caché, los argumentos posicionales y de palabras clave (que sirven como claves en ese diccionario) a la función debe ser hashable.

molestos detalles

Python no tiene soporte para la eliminación de llamada final. Como resultado, puede causar un desbordamiento de pila si al final el uso de marcos de pila más que la profundidad de la pila de llamadas predeterminado:

>>> import sys
>>> sys.getrecursionlimit()
3000

Tenga en cuenta esta limitación si tiene un programa que requiere la repetición de profundidad.

Además, las estructuras de datos mutables de Python no admiten el intercambio estructural, por lo que tratarlos como estructuras de datos inmutables va a afectar negativamente a su espacio y GC (recolección de basura) la eficiencia, ya que van a terminar innecesariamente copiar una gran cantidad de objetos mutables . Por ejemplo, he utilizado este modelo para descomponer listas y recursivo sobre ellos:

>>> input_list = [1, 2, 3]
>>> head = input_list[0]
>>> tail = input_list[1:]
>>> print("head --", head)
head -- 1
>>> print("tail --", tail)
tail -- [2, 3]

lo hice para simplificar las cosas por el bien de la claridad. Tenga en cuenta que la cola se crea copiando. Recursiva haciendo que más grandes listas pueden afectar negativamente a su espacio y la eficiencia GC.

Fin

Una vez me preguntaron para explicar la recursividad en una entrevista. Tomé una hoja de papel y escribí favor vuelca en ambos lados. El entrevistador no tuvo la broma, pero ahora que ha leído este artículo, esperamos que pueda hacer feliz Pythoning!

Referencias

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del Real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: Pensamiento de forma recursiva en Python

Categorías
Python

11 Consejos para principiantes para la programación de aprendizaje de Python

 

Tabla de Contenidos

  • Make It StickTip # 1: Código EverydayTip # 2: Escribir Se OutTip # 3: Ir interactivo Consejo # 4: Tomar BreaksTip # 5: Conviértase en un Bug Bounty Hunter
  • Consejo # 1: Código Todos los días
  • Consejo # 2: escribirlo
  • Consejo # 3: Ir interactivo!
  • Consejo # 4: Tome descansos
  • Tip # 5: Ser un Bug Bounty Hunter
  • Make It CollaborativeTip # 6: rodearse de otros que están LearningTip # 7: TeachTip # 8: Par ProgramTip # 9: Pregunta “bueno” preguntas
  • Consejo # 6: rodearse de otros que están aprendiendo
  • Consejo # 7: Teach
  • Consejo # 8: Par Programa
  • Consejo # 9: Preguntar “buenas” preguntas
  • Hacer SomethingTip # 10: Algo gruesa, AnythingTip # 11: Contribuir a Open Source
  • Consejo # 10: Construir algo, cualquier cosa
  • Consejo # 11: Contribuir a Open Source
  • Go Forth y aprender!
  • Consejo # 1: Todos los días Código
  • Consejo # 2: escribirlo
  • Consejo # 3: Ir Interactivo!
  • Consejo # 4: Tome descansos
  • Consejo # 5: Conviértase en un Bug Bounty Hunter
  • Consejo # 6: rodearse de otros que están aprendiendo
  • Consejo # 7: Teach
  • Consejo # 8: Par Programa
  • Consejo # 9: Preguntar “bueno” Preguntas
  • Tip # 10: Construir algo, cualquier cosa
  • Tip # 11: Contribuir a Open Source

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el real Python equipo. Mira que junto con el tutorial escrito para profundizar su comprensión: 11 Consejos para principiantes de aprendizaje de Python

Estamos muy emocionados de que se haya decidido a embarcarse en el viaje de aprendizaje de Python! Una de las preguntas más comunes que recibimos de nuestros lectores es “¿Cuál es la mejor manera de aprender Python?”

Creo que el primer paso para aprender cualquier lenguaje de programación es asegurarse de que entiende cómo para aprender. Aprendizaje cómo para aprender es sin duda la habilidad más importante involucrado en la programación de computadoras.

Por qué es saber cómo aprender tan importante? La respuesta es sencilla: como lenguas evolucionan, se crean bibliotecas y herramientas se actualizan. Saber aprender será esencial para mantenerse al día con estos cambios y convertirse en un programador de éxito.

En este artículo, vamos a ofrecer varias estrategias de aprendizaje que ayudarán a hacer que su viaje de convertirse en una estrella de rock Python programador! Bono

gratuito: Python Cheat Sheet

Obtener una hoja de Python Cheat (PDF) y aprender los conceptos básicos de Python 3, como trabajar con tipos de datos, diccionarios, listas, y las funciones de Python:

hacer que se pegue

Estos son algunos consejos para ayudarle a hacer los nuevos conceptos que están aprendiendo como programador principiante realmente se adhieren:

Tip # 1: Todos los días Código

la consistencia es muy importante cuando se está aprendiendo un nuevo idioma. Se recomienda hacer un compromiso con código de todos los días. Puede ser difícil de creer, pero la memoria muscular juega un papel importante en la programación. Comprometerse con la codificación de todos los días realmente ayudará a desarrollar esa memoria muscular. Aunque puede parecer intimidante al principio, considere el comenzar de pequeña con 25 minutos todos los días y su forma de trabajo a partir de ahí.

Confirmar la Guía de primeros pasos con Python para obtener información sobre la configuración, así como ejercicios para ayudarle a empezar.

Consejo # 2: escribirlo

A medida que avance en su viaje como un nuevo programador, usted puede preguntarse si usted debe tomar notas. ¡Si deberías! De hecho, las investigaciones sugieren que el tomar notas a mano es más beneficioso para la retención a largo plazo. Esto será especialmente beneficioso para las personas que trabajan hacia el objetivo de convertirse en un desarrollador de tiempo completo, ya que muchas entrevistas implicarán la escritura de código en una pizarra.

Una vez que comience a trabajar en proyectos y programas pequeños, la escritura a mano también puede ayudar a planificar su código antes de pasar a la computadora. Se puede ahorrar mucho tiempo si se escribe qué funciones y clases que se necesitan, así como la forma en que interactúan.

Consejo # 3: Ir Interactivo!

Si usted está aprendiendo acerca de las estructuras básicas de datos de Python (cadenas, listas, diccionarios, etc.) para la primera vez, o se depura una aplicación, el terminal de Python interactiva será uno de sus mejores herramientas de aprendizaje. Lo usamos mucho en este sitio también!

para usar el intérprete interactivo de Python (también a veces llamado un “REPL Python”), primero asegúrese de que Python está instalado en su ordenador. Tenemos un tutorial paso a paso para ayudarle a hacer eso. Para activar el terminal de Python interactiva, basta con abrir el pitón o python3 terminal y ejecutar dependiendo de su instalación. Puede encontrar más instrucciones específicas aquí.

Ahora que ya sabe cómo iniciar la cáscara, aquí hay algunos ejemplos de cómo se puede utilizar la cáscara cuando se está aprendiendo:

Saber qué operaciones se pueden realizar en un elemento mediante el uso de dir ():

>>> my_string = 'I am a string'
>>> dir(my_string)
['__add__', ..., 'upper', 'zfill'] # Truncated for readability

los elementos devueltos de dir () son todos los métodos (es decir, acciones) que se puede aplicar al elemento. Por ejemplo:

>>> my_string.upper()
>>> 'I AM A STRING'

en cuenta que llamamos el método superior (). Se puede ver lo que hace? Esto hace que todas las letras en mayúscula la cadena! Más información sobre estos métodos incorporados en “Manipulación de cadenas” en este tutorial.

Aprender el tipo de un elemento:

>>> type(my_string)
>>> str

uso del sistema integrado de ayuda para obtener la documentación completa: bibliotecas

>>> help(str)

importación y jugar con ellos:

>>> from datetime import datetime
>>> dir(datetime)
['__add__', ..., 'weekday', 'year'] # Truncated for readability
>>> datetime.now()
datetime.datetime(2018, 3, 14, 23, 44, 50, 851904)

Ejecutar comandos shell:

>>> import os
>>> os.system('ls')
python_hw1.py python_hw2.py README.txt

Consejo # 4: Tome descansos

Cuando se está aprendiendo, es importante dar un paso de distancia y absorber los conceptos. La Técnica Pomodoro es ampliamente utilizado y puede ayudar: se trabaja durante 25 minutos, tomar un breve descanso, y luego repetir el proceso. Tomar descansos es fundamental para tener una sesión de estudio eficaz, sobre todo cuando se está tomando en una gran cantidad de nueva información. Saltos

son especialmente importantes cuando se está depurando. Si se golpea un error y no se puede averiguar por lo que está mal, tomar un descanso. Paso lejos de su computadora, vaya a dar un paseo, o charlar con un amigo.

En la programación, el código debe seguir las reglas de un lenguaje y la lógica exactamente, por lo que incluso falta una comilla va a romper todo. ojos frescos hacen una gran diferencia.

Consejo # 5: Ser un Bug Bounty Hunter

Hablando de golpear un error, es inevitable una vez que comience a escribir programas complejos que se ejecutará en fallos en su código. ¡Nos pasa a todos! No deje que los insectos se frustran. En su lugar, adoptar estos momentos con orgullo y pensar en sí mismo como un cazador de recompensas de errores.

Al depurar, es importante tener un enfoque metodológico para que encuentres donde las cosas se están desmoronando. Yendo a través de su código en el orden en el que se ejecuta y asegurándose de que cada parte trabaja es una gran manera de hacer esto.

Una vez que tenga una idea de donde las cosas podrían estar desapareciendo, insertar la siguiente línea de código en su guión pdb de importación; pdb.set_trace () y ejecutarlo. Este es el depurador Python y te deja en el modo interactivo. El depurador también se puede ejecutar desde la línea de comandos con el pitón -m pdb .

Make It Colaboración

Una vez que las cosas empiezan a pegarse, acelerar su aprendizaje a través de la colaboración. He aquí algunas estrategias para ayudarle a sacar el máximo provecho de trabajar con otros.

Consejo # 6: rodearse de otros que están aprendiendo

Aunque la codificación puede parecer una actividad solitaria, que en realidad funciona mejor cuando se trabaja juntos. Es extremadamente importante cuando se está aprendiendo a código en Python que se rodea de otras personas que están aprendiendo también. Esto le permitirá compartir los consejos y trucos que se aprenden a lo largo del camino.

no se preocupe si usted no conoce a nadie. Hay un montón de maneras de conocer a otras personas que sienten pasión por el aprendizaje de Python! Encontrar eventos locales o Meetup o unirse PythonistaCafe, una comunidad de aprendizaje de igual a igual para los entusiastas de Python como tú!

Consejo # 7: Teach

Se dice que la mejor manera de aprender algo es enseñándolo. Esto es cierto cuando se está aprendiendo Python. Hay muchas maneras de hacer esto: pizarras con otros amantes de Python, escribir entradas de blog para explicar los nuevos conceptos aprendidos, la grabación de vídeos en el que explicar algo que ha aprendido, o simplemente hablando a sí mismo en su ordenador. Cada una de estas estrategias solidificar su comprensión, así como exponer las lagunas en su comprensión.

Consejo # 8: Programa de programación Par

Pair es una técnica que consiste en dos desarrolladores que trabajan en una estación de trabajo para completar una tarea. Los dos desarrolladores cambiar entre ser el “conductor” y el “navegador”. El “controlador”, escribe el código, mientras que el “navegador” ayuda a guiar la resolución de problemas y revisa el código como está escrito. Cambiar con frecuencia para obtener el beneficio de ambas partes.

programación Par

tiene muchos beneficios: te da la oportunidad de no sólo tener a alguien revisión de su código, sino también ver cómo alguien podría estar pensando en un problema. Estar expuesto a múltiples ideas y formas de pensar le ayudarán en la resolución de problemas cuando volviste a la codificación por su cuenta.

Consejo # 9: Preguntar “bueno” Preguntas

Las personas siempre dicen que no hay tal cosa como una mala pregunta, pero cuando se trata de la programación, es posible hacer una pregunta mal. Cuando usted está pidiendo ayuda de alguien que tiene poco o ningún contexto en el problema que está tratando de resolver, lo mejor es hacer preguntas BUENAS siguiendo este acrónimo:

  • G: contexto da por lo que está tratando de hacer, claramente que describe el problema.
  • O: Esquema de las cosas que ya han tratado de solucionar el problema.
  • O: Ofrecer el mejor conjetura en cuanto a lo que podría ser el problema. Esto ayuda a la persona que le está ayudando no sólo para saber lo que está pensando, sino también saber que usted ha hecho pensar un poco por su cuenta.
  • D: Demo lo que está sucediendo. Incluir el código, un mensaje de error de seguimiento, y una explicación de los pasos que ejecutó que dieron como resultado el error. De esta manera, la persona que ayuda no tiene que tratar de recrear el problema.

buenas preguntas pueden ahorrar mucho tiempo. Saltarse cualquiera de estos pasos puede dar lugar a conversaciones de vuelta adelante y hacia atrás que pueden causar conflicto. Como un principiante, usted quiere asegurarse de que hace buenas preguntas para que practique la comunicación de su proceso de pensamiento, y para que las personas que le ayudan estarán encantados de seguir ayudando a usted.

hacer que algo

La mayoría, si no todos, los desarrolladores de Python que hablar con le dirá que con el fin de aprender Python, debe aprender sobre la marcha. Hacer ejercicios sólo se puede llevar muy lejos: se aprende más con la construcción.

Consejo # 10: Algo Generar, Cualquier cosa

Para los principiantes, hay muchos pequeños ejercicios que realmente le ayudará a tener confianza con Python, así como desarrollar la memoria muscular del que hablamos anteriormente. Una vez que tenga un sólido conocimiento de las estructuras de datos básicos (cadenas, listas, diccionarios, juegos), la programación orientada a objetos y clases de escritura, es el momento para empezar a construir!

Lo que se construye no es tan importante como la forma en que lo construye. El viaje del edificio es realmente lo que le enseñará más. Sólo se puede aprender mucho de la lectura de artículos y cursos real Python. La mayor parte de su aprendizaje vendrá el uso de Python para construir algo. Los problemas se resolverán le enseñará mucho.

Hay muchas listas por ahí con ideas para proyectos de Python para principiantes. Aquí están algunas ideas para empezar:

    Número

  • juego de adivinanzas
  • aplicación de calculadora simple
  • dados simulador de rollo
  • Bitcoin Precio notificación de servicio

Si le resulta difícil llegar a proyectos de buenas prácticas de Python para trabajar, mira este video. Se establece una estrategia que puede utilizar para generar miles de ideas de proyectos cada vez que se siente atrapado.

Consejo # 11: Contribuir a Open Source

En el modelo de código abierto, software de código fuente está disponible públicamente, y cualquiera puede colaborar. Hay muchas bibliotecas de Python que son proyectos de código abierto y toman contribuciones. Además, muchas empresas publican proyectos de código abierto. Esto significa que puede trabajar con el código escrito y producido por los ingenieros que trabajan en estas empresas.

Contribuir a un proyecto de Python de código abierto es una gran manera de crear experiencias de aprendizaje de gran valor. Digamos que usted decide presentar una solicitud de corrección de errores: se envía una “solicitud de extracción” para su solución a ser parcheado en el código.

A continuación, los responsables del proyecto revisará su trabajo, comentarios y sugerencias. Esto le permitirá aprender las mejores prácticas de programación Python, así como la práctica que se comunican con otros desarrolladores.

Para obtener consejos y tácticas adicionales que le ayudarán a entrar en el mundo de código abierto, ver el vídeo incrustado abajo:

Go Forth y aprender!

Ahora que tiene estas estrategias para el aprendizaje, ya está listo para comenzar su viaje Python! Encuentra del Real Python principiantes Hoja de Ruta para el Aprendizaje aquí! También ofrecemos supuesto Python nivel de principiante, que utiliza ejemplos interesantes para ayudarle a aprender programación y desarrollo web.

feliz Codificación!

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del Real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: 11 Consejos para principiantes de aprendizaje de Python

Categorías
Python

Rethink Frasco – Una lista de tareas simple Desarrollado por Frasco y RethinkDB

 

Tabla de Contenidos

  • Configuración de su Python Web raspador
  • Web Hacer peticiones
  • Wrangling HTML Con BeautifulSoup
  • Usando BeautifulSoup obtener matemático Nombres
  • Conseguir la popularidad Puntuación
  • Poniendo todo junto
  • Conclusión y próximos pasos

¿Qué es la web raspado de todo esto?

Imagine que un día, de repente, te encuentras pensando “Vaya, me pregunto quiénes son los cinco más populares son los matemáticos?”

lo hace un poco de pensamiento, y se obtiene la idea de utilizar Xtools de Wikipedia para medir la popularidad de un matemático igualando popularidad con páginas vistas. Por ejemplo, mira la página sobre Henri Poincaré. Allí, se puede ver que páginas vistas de Poincaré para los últimos 60 días son, a partir de diciembre de 2017, alrededor de 32.000.

A continuación, Google “matemáticos famosos” y encontrar este recurso que enumera 100 nombres. Ahora usted tiene una página donde aparecen los nombres de los matemáticos, así como un sitio web que proporciona información sobre cómo ‘popular’ que es matemático. ¿Ahora que?

Aquí es donde Python y raspado Web vienen en. Raspado web es acerca de la descarga de datos estructurados de la web, la selección de algunos de esos datos, y que pasa a lo largo de lo que haya seleccionado a otro proceso.

En este tutorial, va a escribir un programa Python que descarga la lista de 100 matemáticos y sus Xtools páginas, selecciona los datos acerca de su popularidad, y acabados por decirnos los 5 mejores matemáticos más populares de todos los tiempos! Empecemos.

Importante: Hemos recibido un correo electrónico de un mantenedor Xtools nos informa de que el raspado Xtools es perjudicial y que las API de automatización se debe utilizar en su lugar:

este artículo en su sitio es esencialmente una guía para Xtools raspado […] Este no es necesario, y está causando problemas para nosotros. Tenemos las API que se deben utilizar para la automatización, y además, por páginas vistas en concreto la gente debe estar usando la API oficial de páginas vistas.

El código de ejemplo en el artículo se modificó a ninguna solicitud de maquillaje más largas a la página web Xtools. Las técnicas de raspado web demostradas aquí siguen siendo válidos, pero por favor no los utilizan en las páginas web del proyecto Xtools. Utilizar la API de automatización proporcionada en su lugar.

Configuración de su Python Web raspador

Usted va a utilizar Python y Python 3 ambientes virtuales de todo el tutorial. Siéntase libre de cosas establecido como usted quiera. Así es como yo tiendo a hacerlo:

$ python3 -m venv venv
$ . ./venv/bin/activate

Usted tendrá que instalar sólo estos dos paquetes: solicitudes

  • para realizar su peticiones HTTP
  • BeautifulSoup4 para el manejo de la totalidad de su HTML procesamiento

vamos a instalar estas dependencias con pip :

$ pip install requests BeautifulSoup4

por último, si desea seguir adelante, lanzar su editor de texto favorito y crear un archivo llamado mathematicians.py. Para comenzar, la inclusión de estas declaraciones de importación en la parte superior:

from requests import get
from requests.exceptions import RequestException
from contextlib import closing
from bs4 import BeautifulSoup

Web Hacer Pide

Su primera tarea será la de las páginas web de descarga. El paquete de peticiones viene al rescate. Su objetivo es ser una herramienta fácil de usar para hacer todas las cosas HTTP en Python, y no me decepcionó. En este tutorial, necesitará sólo la función requests.get (), pero que sin duda debe pago y envío de la documentación completa cuando se quiere ir más allá.

En primer lugar, esta es su función: function

def simple_get(url):
"""
Attempts to get the content at `url` by making an HTTP GET request.
If the content-type of response is some kind of HTML/XML, return the
text content, otherwise return None.
"""
try:
with closing(get(url, stream=True)) as resp:
if is_good_response(resp):
return resp.content
else:
return None

except RequestException as e:
log_error('Error during requests to {0} : {1}'.format(url, str(e)))
return None

def is_good_response(resp):
"""
Returns True if the response seems to be HTML, False otherwise.
"""
content_type = resp.headers['Content-Type'].lower()
return (resp.status_code == 200
and content_type is not None
and content_type.find('html') > -1)

def log_error(e):
"""
It is always a good idea to log errors.
This function just prints them, but you can
make it do anything.
"""
print(e)

El simple_get () acepta un solo argumento url. Luego hace una petición GET a la URL. Si nada sale mal, se termina con el contenido HTML prima para la página solicitada. Si hubiera algún problema con su solicitud (como la URL es malo, o el servidor remoto está abajo), entonces su función devuelve Ninguno.

Usted puede haber notado el uso de la función de cierre () en su definición de simple_get (). Las asegura la función de cierre () que todos los recursos de red se liberan cuando salen del ámbito en el que con el bloque. El uso de cierre () de esa manera es una buena práctica y ayuda a prevenir errores fatales y los tiempos de espera de la red.

Puede probar simple_get () así:

>>> from mathematicians import simple_get
>>> raw_html = simple_get('https://realpython.com/blog/')
>>> len(raw_html)
33878

>>> no_html = simple_get('https://realpython.com/blog
ope-not-gonna-find-it')
>>> no_html is None
True

Wrangling HTML Con BeautifulSoup

Una vez que tenga el HTML puro delante de usted, usted puede comenzar a seleccionar y extracto. Para este propósito, que va a utilizar BeautifulSoup. El constructor BeautifulSoup analiza cadenas HTML primas y produce un objeto que los espejos estructura del documento HTML. El objeto incluye una serie de métodos para seleccionar, ver y manipular nodos DOM y contenido de texto.

Consideremos el siguiente ejemplo rápido y artificial de un documento HTML:




Contrived Example<itle><br /> </head><br /> <body></p> <p id="eggman"> I am the egg man </p> <p id="walrus"> I am the walrus </p> <p></body><br /> </html><br /> </code> </p> <p> Si lo anterior HTML se guarda en el archivo de contrived.html, entonces se puede utilizar BeautifulSoup así: </p> <p> <code>>>> from bs4 import BeautifulSoup<br /> >>> raw_html = open('contrived.html').read()<br /> >>> html = BeautifulSoup(raw_html, 'html.parser')<br /> >>> for p in html.select('p'):<br /> ... if p['id'] == 'walrus':<br /> ... print(p.text)</p> <p>'I am the walrus'<br /> </code> </p> <p> descomponer el ejemplo, primero analizar el HTML puro pasándolo al constructor BeautifulSoup. BeautifulSoup acepta múltiples programas de análisis de back-end, pero el back-end estándar es ‘html.parser’, que usted proporciona aquí como el segundo argumento. (Si usted se olvida de que el suministro ‘html.parser’, entonces el código seguirá funcionando, pero usted verá una impresión advertencia a la pantalla.) </p> <p> El seleccione () en el objeto HTML le permite utilizar los selectores CSS para localizar los elementos del documento. En el caso anterior, html.select ( ‘p’) devuelve una lista de elementos de párrafo. Cada p tiene atributos HTML que se puede acceder como un dict. En la línea si p [ ‘id == ‘morsa’, por ejemplo, se comprueba si el atributo id es igual a la cadena ‘morsa’, que corresponde a </p> <p id = "morsa"> en el código HTML. </p> <h2> Usando BeautifulSoup obtener matemático Nombres </h2> <p> Ahora que ha dado el método de selección () en BeautifulSoup un corto recorrido de prueba, ¿cómo determinar lo que puede suministrar para seleccionar ()? La forma más rápida es a salir de Python y en las herramientas de desarrollo de su navegador web. Puede utilizar el navegador para examinar el documento en detalle. Suelo buscar atributos id o elemento de clase o cualquier otra información que identifica de manera única la información que desea extraer. </p> <p> Para hacer las cosas concretas, a su vez, a la lista de los matemáticos que vimos antes. Si pasas un minuto o dos mirando en la fuente de esta página, se puede ver que el nombre de cada uno matemático aparece dentro del contenido de texto de una etiqueta </p> <li>. Para hacer las cosas aún más simple, etiquetas <li> en esta página parecen contener nada más que los nombres de los matemáticos. </p> <p> He aquí un vistazo rápido con Python: </p> <p> <code>>>> raw_html = simple_get('http://www.fabpedigree.com/james/mathmen.htm')<br /> >>> html = BeautifulSoup(raw_html, 'html.parser')<br /> >>> for i, li in enumerate(html.select('li')):<br /> print(i, li.text)</p> <p>0 Isaac Newton<br /> Archimedes<br /> Carl F. Gauss<br /> Leonhard Euler<br /> Bernhard Riemann</p> <p>1 Archimedes<br /> Carl F. Gauss<br /> Leonhard Euler<br /> Bernhard Riemann</p> <p>2 Carl F. Gauss<br /> Leonhard Euler<br /> Bernhard Riemann</p> <p> 3 Leonhard Euler<br /> Bernhard Riemann</p> <p>4 Bernhard Riemann</p> <p># 5 ... and many more...<br /> </code> </p> <p> El anterior experimento muestra que algunos de los elementos </p> <li> contienen varios nombres separados por caracteres de nueva línea, mientras que otras contienen solo un nombre. Con esta información en mente, usted puede escribir su función para extraer una única lista de nombres: </p> <p> <code>def get_names():<br /> """<br /> Downloads the page where the list of mathematicians is found<br /> and returns a list of strings, one per mathematician<br /> """<br /> url = 'http://www.fabpedigree.com/james/mathmen.htm'<br /> response = simple_get(url)</p> <p> if response is not None:<br /> html = BeautifulSoup(response, 'html.parser')<br /> names = set()<br /> for li in html.select('li'):<br /> for name in li.text.split('\n'):<br /> if len(name) > 0:<br /> names.add(name.strip())<br /> return list(names)</p> <p> # Raise an exception if we failed to get any data from the url<br /> raise Exception('Error retrieving contents at {}'.format(url))<br /> </code> </p> <p> Los get_names () descarga de la página de función y itera sobre los elementos </p> <li>, escogiendo cada nombre que se da. A continuación, añadir cada nombre para un conjunto de Python, lo que asegura que no termina con nombres duplicados. Por último, a convertir el conjunto a una lista y lo devuelve. </p> <h2> Conseguir la popularidad Puntuación </h2> <p> Niza, usted está a punto de terminar! Ahora que tiene una lista de nombres, es necesario seleccionar las páginas vistas para cada uno. La función se escribe es similar a la función que realizan para obtener la lista de nombres, sólo que ahora proporciona un nombre y seleccionar un valor entero de la página. </p> <p> vez más, usted debe consultar primero a cabo una página de ejemplo, en las herramientas de desarrollo de su navegador. Parece como si el texto aparece dentro de un elemento <a>, y el atributo href del elemento que siempre contiene la cadena ‘última-60’ como una subcadena. Esa es toda la información que necesita para escribir su función: </p> <p> <code>def get_hits_on_name(name):<br /> """<br /> Accepts a `name` of a mathematician and returns the number<br /> of hits that mathematician's Wikipedia page received in the<br /> last 60 days, as an `int`<br /> """<br /> # url_root is a template string that is used to build a URL.<br /> url_root = 'URL_REMOVED_SEE_NOTICE_AT_START_OF_ARTICLE'<br /> response = simple_get(url_root.format(name))</p> <p> if response is not None:<br /> html = BeautifulSoup(response, 'html.parser')</p> <p> hit_link = [a for a in html.select('a')<br /> if a['href'].find('latest-60') > -1]</p> <p> if len(hit_link) > 0:<br /> # Strip commas<br /> link_text = hit_link[0].text.replace(',', '')<br /> try:<br /> # Convert to integer<br /> return int(link_text)<br /> except:<br /> log_error("couldn't parse {} as an `int`".format(link_text))</p> <p> log_error('No pageviews found for {}'.format(name))<br /> return None<br /> </code> </p> <h2> Poniendo todo junto </h2> <p> Usted ha llegado a un punto en el que finalmente puede averiguar qué matemático es más querido por el público! El plan es simple: </p> <ul> <li> Obtener una lista de nombres </li> <li> iterar sobre la lista para obtener una “puntuación de popularidad” para cada nombre </li> <li> acabado clasificando los nombres de popularidad </li> </ul> <p> simple, ¿verdad? Bueno, hay una cosa que no se ha mencionado todavía: errores. </p> <p> Trabajo con datos del mundo real es desordenado, y tratando de forzar datos desordenados en una forma uniforme, invariablemente como resultado el salto error ocasional en meterse con su buena visión limpia de cómo deberían ser las cosas. Lo ideal sería que le gustaría hacer un seguimiento de errores cuando se producen con el fin de obtener un mejor sentido de la calidad de sus datos. </p> <p> para sus propósitos presentes, se hará un seguimiento de los casos en los que no se podía encontrar una puntuación de popularidad para el nombre de un matemático dado. Al final de la secuencia de comandos, se va a imprimir un mensaje que indica el número de matemáticos que se quedaron fuera de la clasificación. </p> <p> Aquí está el código: </p> <p> <code>if __name__ == '__main__':<br /> print('Getting the list of names....')<br /> names = get_names()<br /> print('... done.\n')</p> <p> results = []</p> <p> print('Getting stats for each name....')</p> <p> for name in names:<br /> try:<br /> hits = get_hits_on_name(name)<br /> if hits is None:<br /> hits = -1<br /> results.append((hits, name))<br /> except:<br /> results.append((-1, name))<br /> log_error('error encountered while processing '<br /> '{}, skipping'.format(name))</p> <p> print('... done.\n')</p> <p> results.sort()<br /> results.reverse()</p> <p> if len(results) > 5:<br /> top_marks = results[:5]<br /> else:<br /> top_marks = results</p> <p> print('\nThe most popular mathematicians are:\n')<br /> for (mark, mathematician) in top_marks:<br /> print('{} with {} pageviews'.format(mathematician, mark))</p> <p> no_results = len([res for res in results if res[0] == -1])<br /> print('\nBut we did not find results for '<br /> '{} mathematicians on the list'.format(no_results))<br /> </code> </p> <p> Eso es todo! </p> <p> Cuando se ejecuta la secuencia de comandos, debería ver en el siguiente informe: </p> <p> <code>The most popular mathematicians are:</p> <p>Albert Einstein with 1089615 pageviews<br /> Isaac Newton with 581612 pageviews<br /> Srinivasa Ramanujan with 407141 pageviews<br /> Aristotle with 399480 pageviews<br /> Galileo Galilei with 375321 pageviews</p> <p>But we did not find results for 19 mathematicians on our list<br /> </code> </p> <h2> Conclusión y próximos pasos raspado </h2> <p> web es un campo grande, y que acaba de terminar un breve recorrido de ese campo, el uso de Python en la conducción. Se puede llegar muy lejos usando sólo las solicitudes y BeautifulSoup, pero a medida que ha seguido a lo largo, es posible que tenga llegado con algunas preguntas: </p> <ul> <li> ¿Qué pasa si las cargas de contenido de página como resultado de las peticiones de JavaScript asíncrono? (Salida API Python de selenio.) </li> <li> ¿Cómo se escribe una tela de araña o robot de búsqueda del motor que atraviesa gran parte de la web? </li> <li> ¿Qué es esta cosa Scrapy que tanto se habla? </li> </ul> <p> Estos son temas para otro post … Mantenga los ojos bien abiertos! Habrá un seguimiento que utiliza selenio y un navegador sin cabeza que lidiar con contenido dinámico: </p> <p> <strong> Informarte: </strong> no se pierda la continuación de este tutorial-Haga clic aquí para unirse a la Newsletter pitón real y sabrá cuando la próxima entrega sale. </p> <p> Hasta entonces, raspado feliz! </p> </div><!-- .entry-content --> </div><!-- .post-inner --> <div class="section-inner"> </div><!-- .section-inner --> </article><!-- .post --> <hr class="post-separator styled-separator is-style-wide section-inner" aria-hidden="true" /> <article class="post-7030 post type-post status-publish format-standard has-post-thumbnail hentry category-python" id="post-7030"> <header class="entry-header has-text-align-center"> <div class="entry-header-inner section-inner medium"> <div class="entry-categories"> <span class="screen-reader-text">Categorías</span> <div class="entry-categories-inner"> <a href="https://eltecnofilo.es/category/python/" rel="category tag">Python</a> </div><!-- .entry-categories-inner --> </div><!-- .entry-categories --> <h2 class="entry-title heading-size-1"><a href="https://eltecnofilo.es/el-anti-patron-del-piton-mas-diabolico/">El anti patrón del pitón más diabólico</a></h2> <div class="post-meta-wrapper post-meta-single post-meta-single-top"> <ul class="post-meta"> <li class="post-author meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Autor de la entrada</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20"><path fill="" d="M18,19 C18,19.5522847 17.5522847,20 17,20 C16.4477153,20 16,19.5522847 16,19 L16,17 C16,15.3431458 14.6568542,14 13,14 L5,14 C3.34314575,14 2,15.3431458 2,17 L2,19 C2,19.5522847 1.55228475,20 1,20 C0.44771525,20 0,19.5522847 0,19 L0,17 C0,14.2385763 2.23857625,12 5,12 L13,12 C15.7614237,12 18,14.2385763 18,17 L18,19 Z M9,10 C6.23857625,10 4,7.76142375 4,5 C4,2.23857625 6.23857625,0 9,0 C11.7614237,0 14,2.23857625 14,5 C14,7.76142375 11.7614237,10 9,10 Z M9,8 C10.6568542,8 12,6.65685425 12,5 C12,3.34314575 10.6568542,2 9,2 C7.34314575,2 6,3.34314575 6,5 C6,6.65685425 7.34314575,8 9,8 Z" /></svg> </span> <span class="meta-text"> Por <a href="https://eltecnofilo.es/author/admin/">admin</a> </span> </li> <li class="post-date meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Fecha de la entrada</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19"><path fill="" d="M4.60069444,4.09375 L3.25,4.09375 C2.47334957,4.09375 1.84375,4.72334957 1.84375,5.5 L1.84375,7.26736111 L16.15625,7.26736111 L16.15625,5.5 C16.15625,4.72334957 15.5266504,4.09375 14.75,4.09375 L13.3993056,4.09375 L13.3993056,4.55555556 C13.3993056,5.02154581 13.0215458,5.39930556 12.5555556,5.39930556 C12.0895653,5.39930556 11.7118056,5.02154581 11.7118056,4.55555556 L11.7118056,4.09375 L6.28819444,4.09375 L6.28819444,4.55555556 C6.28819444,5.02154581 5.9104347,5.39930556 5.44444444,5.39930556 C4.97845419,5.39930556 4.60069444,5.02154581 4.60069444,4.55555556 L4.60069444,4.09375 Z M6.28819444,2.40625 L11.7118056,2.40625 L11.7118056,1 C11.7118056,0.534009742 12.0895653,0.15625 12.5555556,0.15625 C13.0215458,0.15625 13.3993056,0.534009742 13.3993056,1 L13.3993056,2.40625 L14.75,2.40625 C16.4586309,2.40625 17.84375,3.79136906 17.84375,5.5 L17.84375,15.875 C17.84375,17.5836309 16.4586309,18.96875 14.75,18.96875 L3.25,18.96875 C1.54136906,18.96875 0.15625,17.5836309 0.15625,15.875 L0.15625,5.5 C0.15625,3.79136906 1.54136906,2.40625 3.25,2.40625 L4.60069444,2.40625 L4.60069444,1 C4.60069444,0.534009742 4.97845419,0.15625 5.44444444,0.15625 C5.9104347,0.15625 6.28819444,0.534009742 6.28819444,1 L6.28819444,2.40625 Z M1.84375,8.95486111 L1.84375,15.875 C1.84375,16.6516504 2.47334957,17.28125 3.25,17.28125 L14.75,17.28125 C15.5266504,17.28125 16.15625,16.6516504 16.15625,15.875 L16.15625,8.95486111 L1.84375,8.95486111 Z" /></svg> </span> <span class="meta-text"> <a href="https://eltecnofilo.es/el-anti-patron-del-piton-mas-diabolico/">marzo 5, 2020</a> </span> </li> <li class="post-comment-link meta-wrapper"> <span class="meta-icon"> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19"><path d="M9.43016863,13.2235931 C9.58624731,13.094699 9.7823475,13.0241935 9.98476849,13.0241935 L15.0564516,13.0241935 C15.8581553,13.0241935 16.5080645,12.3742843 16.5080645,11.5725806 L16.5080645,3.44354839 C16.5080645,2.64184472 15.8581553,1.99193548 15.0564516,1.99193548 L3.44354839,1.99193548 C2.64184472,1.99193548 1.99193548,2.64184472 1.99193548,3.44354839 L1.99193548,11.5725806 C1.99193548,12.3742843 2.64184472,13.0241935 3.44354839,13.0241935 L5.76612903,13.0241935 C6.24715123,13.0241935 6.63709677,13.4141391 6.63709677,13.8951613 L6.63709677,15.5301903 L9.43016863,13.2235931 Z M3.44354839,14.766129 C1.67980032,14.766129 0.25,13.3363287 0.25,11.5725806 L0.25,3.44354839 C0.25,1.67980032 1.67980032,0.25 3.44354839,0.25 L15.0564516,0.25 C16.8201997,0.25 18.25,1.67980032 18.25,3.44354839 L18.25,11.5725806 C18.25,13.3363287 16.8201997,14.766129 15.0564516,14.766129 L10.2979143,14.766129 L6.32072889,18.0506004 C5.75274472,18.5196577 4.89516129,18.1156602 4.89516129,17.3790323 L4.89516129,14.766129 L3.44354839,14.766129 Z" /></svg> </span> <span class="meta-text"> <a href="https://eltecnofilo.es/el-anti-patron-del-piton-mas-diabolico/#respond">No hay comentarios<span class="screen-reader-text"> en El anti patrón del pitón más diabólico</span></a> </span> </li> </ul><!-- .post-meta --> </div><!-- .post-meta-wrapper --> </div><!-- .entry-header-inner --> </header><!-- .entry-header --> <figure class="featured-media"> <div class="featured-media-inner section-inner medium"> <img width="1200" height="150" src="https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-1200x150.jpeg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" srcset="https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-1200x150.jpeg 1200w, https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-300x38.jpeg 300w, https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-1024x128.jpeg 1024w, https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-768x96.jpeg 768w, https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec.jpeg 1440w" sizes="(max-width: 1200px) 100vw, 1200px" /> </div><!-- .featured-media-inner --> </figure><!-- .featured-media --> <div class="post-inner thin "> <div class="entry-content"> <p> </p> <p> Tabla de Contenidos </p> <ul> <li> ¿Por qué hacemos esto a nosotros mismos? </li> <li> Las Soluciones </li> <li> lo que puede hacer NowExplicitly Prohibir en su codificación Entradas GuidelinesCreate Para existente overbroad Excepto ClausesEducate sus compañeros de los miembros del equipo </li> <li> Prohibir explícitamente en sus Reglas de codificación </li> <li> Crear entradas para los actuales overbroad Excepto cláusulas </li> <li> educar a sus compañeros Miembros del equipo </li> <li> Por qué Entrar La completa Seguimiento de la pila? </li> </ul> <ul> <li> Prohibir explícitamente en sus Reglas de codificación </li> <li> Crear entradas para los actuales overbroad Excepto cláusulas </li> <li> educar a sus compañeros de los miembros del equipo </li> </ul> <p> <img src="https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec.jpeg"> </p> <p> El siguiente es un puesto de invitado por Aaron Maxwell, autor de gran alcance Python. </p> <p> <strong> Hay un montón de maneras de escribir código malo. Pero en Python, uno de cada reina particulares como rey. </strong> </p> <p> estábamos agotados, sin embargo, de júbilo. Después de otros dos ingenieros habían intentado durante tres días a la <em> </em> para fijar un misterioso fallo Unicode antes de renunciar en vano, finalmente aislar la causa después de un simple día. Y diez minutos más tarde, tuvimos una solución candidata. </p> <p> La tragedia es que podríamos haber saltado los días siete y recta se ha ido a los diez minutos. Pero me estoy adelantando a mí mismo … </p> <p> Aquí está el remate. El siguiente fragmento de código es una de las cosas más autodestructivas un desarrollador de Python puede escribir: </p> <p> <code>try:<br /> do_something()<br /> except:<br /> pass<br /> </code> </p> <p> Hay variantes de esa cantidad a lo mismo, diciendo a excepción Excepción: o excepción Excepción como E :, por ejemplo. lo único que hacen el mismo flaco favor enorme: en silencio y de forma invisible ocultar las condiciones de error que de otra manera se pueden detectar de forma rápida y expiden. </p> <p> ¿Por qué afirmo esto es el anti-patrón más diabólico en el mundo de hoy Python? </p> <ul> <li> gente hace esto porque esperan un error específico que suceda allí. Sin embargo, la captura de excepciones oculta todos los errores … incluso aquellos que son completamente inesperado. </li> <li> Cuando el error se descubrió finalmente – con demasiada frecuencia, ya que ha aparecido en la producción – es posible que tenga poca o ninguna idea en qué parte del código base que está mal se ha ido. Se le puede tomar una cantidad verdaderamente desalentador de tiempo para averiguar el error es aún ocurriendo en ese bloque try. </li> <li> Una vez que se da cuenta del error que está ocurriendo allí, que está dificultado en gran medida en la solución de problemas por la falta de información crítica. ¿Cuál era la clase de error / excepción? Lo llamada o estructura de datos estaba involucrado? ¿Qué línea de código, y en qué archivo, se originó el error? </li> <li> va a tirar el seguimiento de pila – un cuerpo literalmente invaluable de información que puede hacer que el differencebetween solucionar un fallo en días o minutos. Sí, minutos. Más sobre esto más adelante. </li> <li> Lo peor de todo, esto puede fácilmente acabar dañando la moral, la felicidad, e incluso la autoestima de los ingenieros que trabajan en la base de código. Cuando el error levanta su cabeza, el solucionador de problemas puede hundir horas en la comprensión de la causa raíz solo. Ellos piensan que son un mal programador porque se necesita tanto tiempo para averiguar. Ellos no son; los errores que surgen por la captura de silencio Excepción son intrínsecamente difícil de identidad, localizar y resolver. </li> </ul> <p> En mis años de casi diez aplicaciones de la experiencia de escritura en Python, tanto a nivel individual y como parte de un equipo, este patrón se ha destacado como la única gran carga para la productividad del desarrollador y la fiabilidad de las aplicaciones … especialmente a largo plazo. Si usted piensa que tiene un candidato a algo peor, me encantaría escucharlo. </p> <h2> ¿Por qué hacemos esto a nosotros mismos? </h2> <p> Por supuesto, nadie <em> deliberadamente </em> escribe un código diseñado para estresarse al resto de desarrolladores y sabotear la fiabilidad de la aplicación. Hacemos esto porque se espera que el código en el bloque try a fallar a veces en el funcionamiento normal, de alguna manera específica. Con optimismo tratando luego coger una excepción es una manera excelente y totalmente Pythonic de acercarse a esta situación. </p> <p> insidiosa, a excepción de captura y luego continuar en silencio no parece que todo lo que una idea horrible en el momento. Pero tan pronto como guarde el archivo, se haya configurado el código para crear los peores tipos de errores: Errores </p> <ul> <li> que pueden escapar a la detección durante el desarrollo, y de ser expulsados ​​al sistema de producción en vivo. Errores </li> <li> que pueden vivir en el código de producción de minutos, horas, días o semanas antes de darse cuenta del error ha estado ocurriendo todo el tiempo. Errores </li> <li> que son difíciles de solucionar. Errores </li> <li> que son difíciles de fijar incluso una vez que sabe dónde se está levantando la excepción contenida. </li> </ul> <p> en cuenta que no estoy diciendo que nunca para capturar excepciones. Hay <em> son buenas razones </em> a excepción de captura, y luego continúan – justnot <em> silencio </em>. Un ejemplo bueno es un proceso de misión crítica que simplemente no quiere ir siempre hacia abajo. Allí, un patrón inteligente es inyectar cláusulas de excepción try que captura, registrar el seguimiento de la pila completa en la gravedad logging.ERROR o mayor, y continuar. </p> <h2> las soluciones </h2> <p> Así que si no queremos a excepción de captura, lo que hacemos en su lugar? Hay dos opciones. </p> <p> En la mayoría de los casos, la mejor opción es coger una excepción más específica. Algo como esto: </p> <p> <code>try:<br /> do_something()<br /> # Catch some very specific exception - KeyError, ValueError, etc.<br /> except ValueError:<br /> pass<br /> </code> </p> <p> Esto es lo primero que se debe tratar. Se necesita un poco de comprensión del código invocado, para que sepa qué tipos de errores que podrían aumentar. Esto es más fácil de hacer bien cuando se intenta por primera escritura del código, en contraposición a la limpieza de otra persona. </p> <p> Si alguna ruta de código simplemente <em> necesidad </em> ampliamente capturar todas las excepciones – por ejemplo, el bucle de alto nivel para un proceso persistente de larga duración – entonces cada excepción capturada <em> debe </em> escribir la <strong> completo seguimiento de la pila </strong> en un registro o archivo , junto con una marca de tiempo. Si está utilizando módulo de registro de Python, esto es muy fácil – cada objeto registrador tiene un método llamado excepción, teniendo una cadena de mensaje. Si usted lo llama en el bloque de excepción, la excepción capturada automáticamente se registra por completo, incluyendo la traza. </p> <p> <code>import logging</p> <p>def get_number():<br /> return int('foo')<br /> try:<br /> x = get_number()<br /> except Exception as ex:<br /> logging.exception('Caught an error')<br /> </code> </p> <p> El registro contendrá el mensaje de error, seguido de una pila de traza difusión formateado en varias líneas: </p> <p> <code>ERROR:root:Caught an error<br /> Traceback (most recent call last):<br /> File "example-logging-exception.py", line 8, in <module><br /> x = get_number()<br /> File "example-logging-exception.py", line 5, in get_number<br /> return int('foo')<br /> ValueError: invalid literal for int() with base 10: 'foo'<br /> </code> </p> <p> muy fácil. </p> <p> Qué pasa si su aplicación hace el registro de alguna otra manera – no se utiliza el módulo de registro? Suponiendo que usted no desea refactorizar su aplicación para hacerlo, sólo puede traer y formatear el rastreo asociado con la excepción. Esto es más fácil en Python 3: </p> <p> <code># The Python 3 version. It's a little less work.<br /> import traceback</p> <p>def log_traceback(ex):<br /> tb_lines = traceback.format_exception(ex.__class__, ex, ex.__traceback__)<br /> tb_text = ''.join(tb_lines)<br /> # I'll let you implement the ExceptionLogger class,<br /> # and the timestamping.<br /> exception_logger.log(tb_text)</p> <p>try:<br /> x = get_number()<br /> except Exception as ex:<br /> log_traceback(ex)<br /> </code> </p> <p> En Python 2, que tiene que hacer un poco más trabajo, porque los objetos de excepción no tienen su rastreo unido a ellos. Usted consigue esta llamando sys.exc_info () en el bloque de excepción: </p> <p> <code>import sys<br /> import traceback</p> <p>def log_traceback(ex, ex_traceback):<br /> tb_lines = traceback.format_exception(ex.__class__, ex, ex_traceback)<br /> tb_text = ''.join(tb_lines)<br /> exception_logger.log(tb_text)</p> <p>try:<br /> x = get_number()<br /> except Exception as ex:<br /> # Here, I don't really care about the first two values.<br /> # I just want the traceback.<br /> _, _, ex_traceback = sys.exc_info()<br /> log_traceback(ex, ex_traceback)<br /> </code> </p> <p> Como resultado, se puede definir una sola función de rastreo-registro que funcionará tanto para Python 2 y 3: </p> <p> <code>import traceback</p> <p>def log_traceback(ex, ex_traceback=None):<br /> if ex_traceback is None:<br /> ex_traceback = ex.__traceback__<br /> tb_lines = [ line.rstrip('\n') for line in<br /> traceback.format_exception(ex.__class__, ex, ex_traceback)]<br /> exception_logger.log(tb_lines)<br /> </code> </p> <h2> lo que puede hacer ahora </h2> <p> “De acuerdo Aaron, me has convencido. Lloro y lloro por todas las veces que he hecho esto en el pasado. ¿Cómo puedo reparar?” Estoy tan bueno que lo preguntas. Aquí hay algunas prácticas que usted puede comenzar hoy. </p> <h3> Prohibir explícitamente en sus Reglas de codificación </h3> <p> Si su equipo hace las revisiones de código, es posible que tenga un documento de directrices de codificación. Si no, es fácil empezar – esto puede ser tan simple como crear una nueva página wiki, y su primera entrada puede ser este. Sólo tiene que añadir las dos pautas siguientes: </p> <ul> <li> Si alguna ruta de código, simplemente debe ponerse en líneas generales todas las excepciones – por ejemplo, el bucle de alto nivel para un proceso persistente de larga duración – a continuación, cada uno de tales excepción capturada debe escribir la traza completa a una log o archivo, junto con una marca de tiempo. No sólo el tipo de excepción y el mensaje, pero la traza completa. </li> <li> Para todos los demás, excepto las cláusulas – que en realidad debería ser la gran mayoría – el tipo de excepción capturada debe ser lo más específico posible. Algo así como KeyError o ConnectionTimeout, etc. </li> </ul> <h3> Crear entradas para los actuales overbroad Excepto cláusulas </h3> <p> Lo anterior ayuda a prevenir nuevos problemas voluntad de convertirlo en su base de código. ¿Qué pasa con las capturas excesivamente amplias existentes? Simple: hacer que un billete o problema en su sistema de seguimiento de errores para solucionarlo. Este es un paso de acción sencilla que aumenta en gran medida las posibilidades de que se resolverá y no olvidado. En serio, puede hacerlo en este momento <em> </em>. </p> <p> recomiendo continuar haciendo un billete único para cada repositorio o aplicación, a través de la auditoría de código para encontrar todos los lugares de excepción es capturado. (Usted puede ser capaz de encontrar a todos ellos con sólo grepping sobre la base de código de “excepción” y “salvo excepciones”.) Para cada aparición, o bien convertirlo a coger un tipo de excepción muy específica; o si no está inmediatamente claro qué eso debería ser, en lugar de modificar el bloque de excepción para registrar la traza completa. </p> <p> Opcionalmente, el desarrollador puede crear entradas de auditoría adicionales para cualquier específica try / except bloque. Esto es una cosa buena que hacer si usted tiene la sensación de la clase excepción se puede hacer más específica, pero no saben que parte del código lo suficientemente bien como para estar seguros. En ese caso, se pone en código para registrar la traza completa; crear un ticket separado para investigar más a fondo; y asignarlo a alguien que podría ser más clara. Si encuentras gastando más de cinco minutos a pensar en un determinado bloque try / except, te recomiendo que hagas esto y pasar a la siguiente. </p> <h3> educar a sus compañeros de los miembros del equipo </h3> <p> ¿Tiene usted las reuniones regulares de ingeniería? Semanal, quincenal o mensualmente? Pedir cinco minutos en el siguiente para explicar este antipatrón, el coste que tiene para su productividad como un equipo, y las soluciones simples. </p> <p> Aún mejor, vaya a su ventaja tecnología o gerente de ingeniería de antemano y les dice al respecto. Eso será una venta mucho más fácil, ya que son por lo menos tan preocupados por la productividad del equipo como eres. Envíalas el enlace a este ensayo. Heck, si es necesario, yo te ayudaré – obtener en el teléfono conmigo, y voy a convencerlos. </p> <p> Se puede llegar aún más amplia en su comunidad. ¿Usted va a una reunión local de Python? ¿Tienen charlas relámpago, o se puede negociar de otra forma de cinco a quince minutos de tiempo de orador en la próxima reunión? Servir a sus colegas ingenieros evangelizando esta noble causa. </p> <h2> Por qué Entrar La completa Seguimiento de la pila? </h2> <p> Varias veces anteriormente, que han insistido en el registro de la traza completa, y el mensaje no sólo el objeto de excepción. Si esto parece más trabajo, eso es debido a que puede ser: la traza tiene saltos de línea que puede ensuciar con el formato de su sistema de registro, puede que tenga que ensuciar con el módulo de rastreo, y así sucesivamente. No se acaba de registrar el mensaje en sí suficiente? </p> <p> No, no lo es. Un mensaje de excepción bien elaborado sólo le dice que la cláusula de excepción es – lo archivo y qué línea de código. Es comúnmente ni siquiera reducirla mucho, pero asumamos que el mejor de los casos aquí. Inicio de sesión simplemente el mensaje es mejor que no registro nada, pero por desgracia, no le dice nada acerca de donde se origina el error. En general, se puede estar en un archivo o módulo completamente diferente, y con frecuencia no es muy fácil de adivinar. </p> <p> Más allá de esto, las aplicaciones reales desarrollados por los equipos tienden a tener múltiples rutas de código que pueden llamar el bloque de excepción de fondos. Tal vez el error se produce sólo cuando la barra método de la clase Foo se llama, pero nunca cuando barra de funciones () se llama. Inicio de sesión sólo el mensaje no le ayudará discernir entre estos dos. </p> <p> La mejor historia de guerra que tengo es de trabajar en un equipo de ingeniería de tamaño mediano, de unos cincuenta fuerte. Yo era relativamente nuevo, y me dieron un error Unicode que se despierta periódicamente el que estaba de guardia durante más de cuatro meses. La excepción fue capturado, y el mensaje registrado, pero ninguna otra información se registró. Dos ingenieros de más alto rango habían trabajado en él durante días cada uno, y luego abandonado, diciendo que no podían entenderlo. </p> <p> Estos fueron los ingenieros inteligentes formidables y de miedo, también. Por último, de la desesperación, intentaron pasar a mí. Utilizando sus extensas notas, inmediatamente me puse en reproducir el problema lo suficientemente bien como para obtener un seguimiento de la pila. Y después de seis horas, al fin entendí. Una vez que tuve que bleeping seguimiento de la pila, se puede adivinar el tiempo que me llevó a tener una solución? </p> <p> minutos </p> <p> <em> diez. </em> de ese derecho. Una vez que tuvimos un seguimiento de pila, la solución era obvia. Una semana <strong> literal </strong> de tiempo ingeniero podría haberse salvado si hubiéramos estado seguimientos de pila de registro desde el principio. Recuerde anterior, cuando digo un seguimiento de pila puede hacer la diferencia entre la resolución de un error en días y resolver en cuestión de minutos? Yo no estaba bromeando. </p> <p> (Curiosamente, algo bueno salió de él. Es experiencias como ésta, que me llevó a empezar a escribir más sobre Python, y cómo nosotros, como ingenieros puede ser más eficaz con el idioma.) </p> </div><!-- .entry-content --> </div><!-- .post-inner --> <div class="section-inner"> </div><!-- .section-inner --> </article><!-- .post --> <hr class="post-separator styled-separator is-style-wide section-inner" aria-hidden="true" /> <article class="post-7029 post type-post status-publish format-standard has-post-thumbnail hentry category-python" id="post-7029"> <header class="entry-header has-text-align-center"> <div class="entry-header-inner section-inner medium"> <div class="entry-categories"> <span class="screen-reader-text">Categorías</span> <div class="entry-categories-inner"> <a href="https://eltecnofilo.es/category/python/" rel="category tag">Python</a> </div><!-- .entry-categories-inner --> </div><!-- .entry-categories --> <h2 class="entry-title heading-size-1"><a href="https://eltecnofilo.es/configuracion-de-python-para-aprendizaje-automatico-en-windows/">Configuración de Python para aprendizaje automático en Windows</a></h2> <div class="post-meta-wrapper post-meta-single post-meta-single-top"> <ul class="post-meta"> <li class="post-author meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Autor de la entrada</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20"><path fill="" d="M18,19 C18,19.5522847 17.5522847,20 17,20 C16.4477153,20 16,19.5522847 16,19 L16,17 C16,15.3431458 14.6568542,14 13,14 L5,14 C3.34314575,14 2,15.3431458 2,17 L2,19 C2,19.5522847 1.55228475,20 1,20 C0.44771525,20 0,19.5522847 0,19 L0,17 C0,14.2385763 2.23857625,12 5,12 L13,12 C15.7614237,12 18,14.2385763 18,17 L18,19 Z M9,10 C6.23857625,10 4,7.76142375 4,5 C4,2.23857625 6.23857625,0 9,0 C11.7614237,0 14,2.23857625 14,5 C14,7.76142375 11.7614237,10 9,10 Z M9,8 C10.6568542,8 12,6.65685425 12,5 C12,3.34314575 10.6568542,2 9,2 C7.34314575,2 6,3.34314575 6,5 C6,6.65685425 7.34314575,8 9,8 Z" /></svg> </span> <span class="meta-text"> Por <a href="https://eltecnofilo.es/author/admin/">admin</a> </span> </li> <li class="post-date meta-wrapper"> <span class="meta-icon"> <span class="screen-reader-text">Fecha de la entrada</span> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19"><path fill="" d="M4.60069444,4.09375 L3.25,4.09375 C2.47334957,4.09375 1.84375,4.72334957 1.84375,5.5 L1.84375,7.26736111 L16.15625,7.26736111 L16.15625,5.5 C16.15625,4.72334957 15.5266504,4.09375 14.75,4.09375 L13.3993056,4.09375 L13.3993056,4.55555556 C13.3993056,5.02154581 13.0215458,5.39930556 12.5555556,5.39930556 C12.0895653,5.39930556 11.7118056,5.02154581 11.7118056,4.55555556 L11.7118056,4.09375 L6.28819444,4.09375 L6.28819444,4.55555556 C6.28819444,5.02154581 5.9104347,5.39930556 5.44444444,5.39930556 C4.97845419,5.39930556 4.60069444,5.02154581 4.60069444,4.55555556 L4.60069444,4.09375 Z M6.28819444,2.40625 L11.7118056,2.40625 L11.7118056,1 C11.7118056,0.534009742 12.0895653,0.15625 12.5555556,0.15625 C13.0215458,0.15625 13.3993056,0.534009742 13.3993056,1 L13.3993056,2.40625 L14.75,2.40625 C16.4586309,2.40625 17.84375,3.79136906 17.84375,5.5 L17.84375,15.875 C17.84375,17.5836309 16.4586309,18.96875 14.75,18.96875 L3.25,18.96875 C1.54136906,18.96875 0.15625,17.5836309 0.15625,15.875 L0.15625,5.5 C0.15625,3.79136906 1.54136906,2.40625 3.25,2.40625 L4.60069444,2.40625 L4.60069444,1 C4.60069444,0.534009742 4.97845419,0.15625 5.44444444,0.15625 C5.9104347,0.15625 6.28819444,0.534009742 6.28819444,1 L6.28819444,2.40625 Z M1.84375,8.95486111 L1.84375,15.875 C1.84375,16.6516504 2.47334957,17.28125 3.25,17.28125 L14.75,17.28125 C15.5266504,17.28125 16.15625,16.6516504 16.15625,15.875 L16.15625,8.95486111 L1.84375,8.95486111 Z" /></svg> </span> <span class="meta-text"> <a href="https://eltecnofilo.es/configuracion-de-python-para-aprendizaje-automatico-en-windows/">marzo 5, 2020</a> </span> </li> <li class="post-comment-link meta-wrapper"> <span class="meta-icon"> <svg class="svg-icon" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19"><path d="M9.43016863,13.2235931 C9.58624731,13.094699 9.7823475,13.0241935 9.98476849,13.0241935 L15.0564516,13.0241935 C15.8581553,13.0241935 16.5080645,12.3742843 16.5080645,11.5725806 L16.5080645,3.44354839 C16.5080645,2.64184472 15.8581553,1.99193548 15.0564516,1.99193548 L3.44354839,1.99193548 C2.64184472,1.99193548 1.99193548,2.64184472 1.99193548,3.44354839 L1.99193548,11.5725806 C1.99193548,12.3742843 2.64184472,13.0241935 3.44354839,13.0241935 L5.76612903,13.0241935 C6.24715123,13.0241935 6.63709677,13.4141391 6.63709677,13.8951613 L6.63709677,15.5301903 L9.43016863,13.2235931 Z M3.44354839,14.766129 C1.67980032,14.766129 0.25,13.3363287 0.25,11.5725806 L0.25,3.44354839 C0.25,1.67980032 1.67980032,0.25 3.44354839,0.25 L15.0564516,0.25 C16.8201997,0.25 18.25,1.67980032 18.25,3.44354839 L18.25,11.5725806 C18.25,13.3363287 16.8201997,14.766129 15.0564516,14.766129 L10.2979143,14.766129 L6.32072889,18.0506004 C5.75274472,18.5196577 4.89516129,18.1156602 4.89516129,17.3790323 L4.89516129,14.766129 L3.44354839,14.766129 Z" /></svg> </span> <span class="meta-text"> <a href="https://eltecnofilo.es/configuracion-de-python-para-aprendizaje-automatico-en-windows/#respond">No hay comentarios<span class="screen-reader-text"> en Configuración de Python para aprendizaje automático en Windows</span></a> </span> </li> </ul><!-- .post-meta --> </div><!-- .post-meta-wrapper --> </div><!-- .entry-header-inner --> </header><!-- .entry-header --> <figure class="featured-media"> <div class="featured-media-inner section-inner medium"> <img width="1200" height="150" src="https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-1200x150.jpeg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" srcset="https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-1200x150.jpeg 1200w, https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-300x38.jpeg 300w, https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-1024x128.jpeg 1024w, https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec-768x96.jpeg 768w, https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec.jpeg 1440w" sizes="(max-width: 1200px) 100vw, 1200px" /> </div><!-- .featured-media-inner --> </figure><!-- .featured-media --> <div class="post-inner thin "> <div class="entry-content"> <p> </p> <p> Tabla de Contenidos </p> <ul> <li> ¿Por qué hacemos esto a nosotros mismos? </li> <li> Las Soluciones </li> <li> lo que puede hacer NowExplicitly Prohibir en su codificación Entradas GuidelinesCreate Para existente overbroad Excepto ClausesEducate sus compañeros de los miembros del equipo </li> <li> Prohibir explícitamente en sus Reglas de codificación </li> <li> Crear entradas para los actuales overbroad Excepto cláusulas </li> <li> educar a sus compañeros Miembros del equipo </li> <li> Por qué Entrar La completa Seguimiento de la pila? </li> </ul> <ul> <li> Prohibir explícitamente en sus Reglas de codificación </li> <li> Crear entradas para los actuales overbroad Excepto cláusulas </li> <li> educar a sus compañeros de los miembros del equipo </li> </ul> <p> <img src="https://eltecnofilo.es/wp-content/uploads/2020/03/655d5b5272a07eaebc6a0885e3bc64ec.jpeg"> </p> <p> El siguiente es un puesto de invitado por Aaron Maxwell, autor de gran alcance Python. </p> <p> <strong> Hay un montón de maneras de escribir código malo. Pero en Python, uno de cada reina particulares como rey. </strong> </p> <p> estábamos agotados, sin embargo, de júbilo. Después de otros dos ingenieros habían intentado durante tres días a la <em> </em> para fijar un misterioso fallo Unicode antes de renunciar en vano, finalmente aislar la causa después de un simple día. Y diez minutos más tarde, tuvimos una solución candidata. </p> <p> La tragedia es que podríamos haber saltado los días siete y recta se ha ido a los diez minutos. Pero me estoy adelantando a mí mismo … </p> <p> Aquí está el remate. El siguiente fragmento de código es una de las cosas más autodestructivas un desarrollador de Python puede escribir: </p> <p> <code>try:<br /> do_something()<br /> except:<br /> pass<br /> </code> </p> <p> Hay variantes de esa cantidad a lo mismo, diciendo a excepción Excepción: o excepción Excepción como E :, por ejemplo. lo único que hacen el mismo flaco favor enorme: en silencio y de forma invisible ocultar las condiciones de error que de otra manera se pueden detectar de forma rápida y expiden. </p> <p> ¿Por qué afirmo esto es el anti-patrón más diabólico en el mundo de hoy Python? </p> <ul> <li> gente hace esto porque esperan un error específico que suceda allí. Sin embargo, la captura de excepciones oculta todos los errores … incluso aquellos que son completamente inesperado. </li> <li> Cuando el error se descubrió finalmente – con demasiada frecuencia, ya que ha aparecido en la producción – es posible que tenga poca o ninguna idea en qué parte del código base que está mal se ha ido. Se le puede tomar una cantidad verdaderamente desalentador de tiempo para averiguar el error es aún ocurriendo en ese bloque try. </li> <li> Una vez que se da cuenta del error que está ocurriendo allí, que está dificultado en gran medida en la solución de problemas por la falta de información crítica. ¿Cuál era la clase de error / excepción? Lo llamada o estructura de datos estaba involucrado? ¿Qué línea de código, y en qué archivo, se originó el error? </li> <li> va a tirar el seguimiento de pila – un cuerpo literalmente invaluable de información que puede hacer que el differencebetween solucionar un fallo en días o minutos. Sí, minutos. Más sobre esto más adelante. </li> <li> Lo peor de todo, esto puede fácilmente acabar dañando la moral, la felicidad, e incluso la autoestima de los ingenieros que trabajan en la base de código. Cuando el error levanta su cabeza, el solucionador de problemas puede hundir horas en la comprensión de la causa raíz solo. Ellos piensan que son un mal programador porque se necesita tanto tiempo para averiguar. Ellos no son; los errores que surgen por la captura de silencio Excepción son intrínsecamente difícil de identidad, localizar y resolver. </li> </ul> <p> En mis años de casi diez aplicaciones de la experiencia de escritura en Python, tanto a nivel individual y como parte de un equipo, este patrón se ha destacado como la única gran carga para la productividad del desarrollador y la fiabilidad de las aplicaciones … especialmente a largo plazo. Si usted piensa que tiene un candidato a algo peor, me encantaría escucharlo. </p> <h2> ¿Por qué hacemos esto a nosotros mismos? </h2> <p> Por supuesto, nadie <em> deliberadamente </em> escribe un código diseñado para estresarse al resto de desarrolladores y sabotear la fiabilidad de la aplicación. Hacemos esto porque se espera que el código en el bloque try a fallar a veces en el funcionamiento normal, de alguna manera específica. Con optimismo tratando luego coger una excepción es una manera excelente y totalmente Pythonic de acercarse a esta situación. </p> <p> insidiosa, a excepción de captura y luego continuar en silencio no parece que todo lo que una idea horrible en el momento. Pero tan pronto como guarde el archivo, se haya configurado el código para crear los peores tipos de errores: Errores </p> <ul> <li> que pueden escapar a la detección durante el desarrollo, y de ser expulsados ​​al sistema de producción en vivo. Errores </li> <li> que pueden vivir en el código de producción de minutos, horas, días o semanas antes de darse cuenta del error ha estado ocurriendo todo el tiempo. Errores </li> <li> que son difíciles de solucionar. Errores </li> <li> que son difíciles de fijar incluso una vez que sabe dónde se está levantando la excepción contenida. </li> </ul> <p> en cuenta que no estoy diciendo que nunca para capturar excepciones. Hay <em> son buenas razones </em> a excepción de captura, y luego continúan – justnot <em> silencio </em>. Un ejemplo bueno es un proceso de misión crítica que simplemente no quiere ir siempre hacia abajo. Allí, un patrón inteligente es inyectar cláusulas de excepción try que captura, registrar el seguimiento de la pila completa en la gravedad logging.ERROR o mayor, y continuar. </p> <h2> las soluciones </h2> <p> Así que si no queremos a excepción de captura, lo que hacemos en su lugar? Hay dos opciones. </p> <p> En la mayoría de los casos, la mejor opción es coger una excepción más específica. Algo como esto: </p> <p> <code>try:<br /> do_something()<br /> # Catch some very specific exception - KeyError, ValueError, etc.<br /> except ValueError:<br /> pass<br /> </code> </p> <p> Esto es lo primero que se debe tratar. Se necesita un poco de comprensión del código invocado, para que sepa qué tipos de errores que podrían aumentar. Esto es más fácil de hacer bien cuando se intenta por primera escritura del código, en contraposición a la limpieza de otra persona. </p> <p> Si alguna ruta de código simplemente <em> necesidad </em> ampliamente capturar todas las excepciones – por ejemplo, el bucle de alto nivel para un proceso persistente de larga duración – entonces cada excepción capturada <em> debe </em> escribir la <strong> completo seguimiento de la pila </strong> en un registro o archivo , junto con una marca de tiempo. Si está utilizando módulo de registro de Python, esto es muy fácil – cada objeto registrador tiene un método llamado excepción, teniendo una cadena de mensaje. Si usted lo llama en el bloque de excepción, la excepción capturada automáticamente se registra por completo, incluyendo la traza. </p> <p> <code>import logging</p> <p>def get_number():<br /> return int('foo')<br /> try:<br /> x = get_number()<br /> except Exception as ex:<br /> logging.exception('Caught an error')<br /> </code> </p> <p> El registro contendrá el mensaje de error, seguido de una pila de traza difusión formateado en varias líneas: </p> <p> <code>ERROR:root:Caught an error<br /> Traceback (most recent call last):<br /> File "example-logging-exception.py", line 8, in <module><br /> x = get_number()<br /> File "example-logging-exception.py", line 5, in get_number<br /> return int('foo')<br /> ValueError: invalid literal for int() with base 10: 'foo'<br /> </code> </p> <p> muy fácil. </p> <p> Qué pasa si su aplicación hace el registro de alguna otra manera – no se utiliza el módulo de registro? Suponiendo que usted no desea refactorizar su aplicación para hacerlo, sólo puede traer y formatear el rastreo asociado con la excepción. Esto es más fácil en Python 3: </p> <p> <code># The Python 3 version. It's a little less work.<br /> import traceback</p> <p>def log_traceback(ex):<br /> tb_lines = traceback.format_exception(ex.__class__, ex, ex.__traceback__)<br /> tb_text = ''.join(tb_lines)<br /> # I'll let you implement the ExceptionLogger class,<br /> # and the timestamping.<br /> exception_logger.log(tb_text)</p> <p>try:<br /> x = get_number()<br /> except Exception as ex:<br /> log_traceback(ex)<br /> </code> </p> <p> En Python 2, que tiene que hacer un poco más trabajo, porque los objetos de excepción no tienen su rastreo unido a ellos. Usted consigue esta llamando sys.exc_info () en el bloque de excepción: </p> <p> <code>import sys<br /> import traceback</p> <p>def log_traceback(ex, ex_traceback):<br /> tb_lines = traceback.format_exception(ex.__class__, ex, ex_traceback)<br /> tb_text = ''.join(tb_lines)<br /> exception_logger.log(tb_text)</p> <p>try:<br /> x = get_number()<br /> except Exception as ex:<br /> # Here, I don't really care about the first two values.<br /> # I just want the traceback.<br /> _, _, ex_traceback = sys.exc_info()<br /> log_traceback(ex, ex_traceback)<br /> </code> </p> <p> Como resultado, se puede definir una sola función de rastreo-registro que funcionará tanto para Python 2 y 3: </p> <p> <code>import traceback</p> <p>def log_traceback(ex, ex_traceback=None):<br /> if ex_traceback is None:<br /> ex_traceback = ex.__traceback__<br /> tb_lines = [ line.rstrip('\n') for line in<br /> traceback.format_exception(ex.__class__, ex, ex_traceback)]<br /> exception_logger.log(tb_lines)<br /> </code> </p> <h2> lo que puede hacer ahora </h2> <p> “De acuerdo Aaron, me has convencido. Lloro y lloro por todas las veces que he hecho esto en el pasado. ¿Cómo puedo reparar?” Estoy tan bueno que lo preguntas. Aquí hay algunas prácticas que usted puede comenzar hoy. </p> <h3> Prohibir explícitamente en sus Reglas de codificación </h3> <p> Si su equipo hace las revisiones de código, es posible que tenga un documento de directrices de codificación. Si no, es fácil empezar – esto puede ser tan simple como crear una nueva página wiki, y su primera entrada puede ser este. Sólo tiene que añadir las dos pautas siguientes: </p> <ul> <li> Si alguna ruta de código, simplemente debe ponerse en líneas generales todas las excepciones – por ejemplo, el bucle de alto nivel para un proceso persistente de larga duración – a continuación, cada uno de tales excepción capturada debe escribir la traza completa a una log o archivo, junto con una marca de tiempo. No sólo el tipo de excepción y el mensaje, pero la traza completa. </li> <li> Para todos los demás, excepto las cláusulas – que en realidad debería ser la gran mayoría – el tipo de excepción capturada debe ser lo más específico posible. Algo así como KeyError o ConnectionTimeout, etc. </li> </ul> <h3> Crear entradas para los actuales overbroad Excepto cláusulas </h3> <p> Lo anterior ayuda a prevenir nuevos problemas voluntad de convertirlo en su base de código. ¿Qué pasa con las capturas excesivamente amplias existentes? Simple: hacer que un billete o problema en su sistema de seguimiento de errores para solucionarlo. Este es un paso de acción sencilla que aumenta en gran medida las posibilidades de que se resolverá y no olvidado. En serio, puede hacerlo en este momento <em> </em>. </p> <p> recomiendo continuar haciendo un billete único para cada repositorio o aplicación, a través de la auditoría de código para encontrar todos los lugares de excepción es capturado. (Usted puede ser capaz de encontrar a todos ellos con sólo grepping sobre la base de código de “excepción” y “salvo excepciones”.) Para cada aparición, o bien convertirlo a coger un tipo de excepción muy específica; o si no está inmediatamente claro qué eso debería ser, en lugar de modificar el bloque de excepción para registrar la traza completa. </p> <p> Opcionalmente, el desarrollador puede crear entradas de auditoría adicionales para cualquier específica try / except bloque. Esto es una cosa buena que hacer si usted tiene la sensación de la clase excepción se puede hacer más específica, pero no saben que parte del código lo suficientemente bien como para estar seguros. En ese caso, se pone en código para registrar la traza completa; crear un ticket separado para investigar más a fondo; y asignarlo a alguien que podría ser más clara. Si encuentras gastando más de cinco minutos a pensar en un determinado bloque try / except, te recomiendo que hagas esto y pasar a la siguiente. </p> <h3> educar a sus compañeros de los miembros del equipo </h3> <p> ¿Tiene usted las reuniones regulares de ingeniería? Semanal, quincenal o mensualmente? Pedir cinco minutos en el siguiente para explicar este antipatrón, el coste que tiene para su productividad como un equipo, y las soluciones simples. </p> <p> Aún mejor, vaya a su ventaja tecnología o gerente de ingeniería de antemano y les dice al respecto. Eso será una venta mucho más fácil, ya que son por lo menos tan preocupados por la productividad del equipo como eres. Envíalas el enlace a este ensayo. Heck, si es necesario, yo te ayudaré – obtener en el teléfono conmigo, y voy a convencerlos. </p> <p> Se puede llegar aún más amplia en su comunidad. ¿Usted va a una reunión local de Python? ¿Tienen charlas relámpago, o se puede negociar de otra forma de cinco a quince minutos de tiempo de orador en la próxima reunión? Servir a sus colegas ingenieros evangelizando esta noble causa. </p> <h2> Por qué Entrar La completa Seguimiento de la pila? </h2> <p> Varias veces anteriormente, que han insistido en el registro de la traza completa, y el mensaje no sólo el objeto de excepción. Si esto parece más trabajo, eso es debido a que puede ser: la traza tiene saltos de línea que puede ensuciar con el formato de su sistema de registro, puede que tenga que ensuciar con el módulo de rastreo, y así sucesivamente. No se acaba de registrar el mensaje en sí suficiente? </p> <p> No, no lo es. Un mensaje de excepción bien elaborado sólo le dice que la cláusula de excepción es – lo archivo y qué línea de código. Es comúnmente ni siquiera reducirla mucho, pero asumamos que el mejor de los casos aquí. Inicio de sesión simplemente el mensaje es mejor que no registro nada, pero por desgracia, no le dice nada acerca de donde se origina el error. En general, se puede estar en un archivo o módulo completamente diferente, y con frecuencia no es muy fácil de adivinar. </p> <p> Más allá de esto, las aplicaciones reales desarrollados por los equipos tienden a tener múltiples rutas de código que pueden llamar el bloque de excepción de fondos. Tal vez el error se produce sólo cuando la barra método de la clase Foo se llama, pero nunca cuando barra de funciones () se llama. Inicio de sesión sólo el mensaje no le ayudará discernir entre estos dos. </p> <p> La mejor historia de guerra que tengo es de trabajar en un equipo de ingeniería de tamaño mediano, de unos cincuenta fuerte. Yo era relativamente nuevo, y me dieron un error Unicode que se despierta periódicamente el que estaba de guardia durante más de cuatro meses. La excepción fue capturado, y el mensaje registrado, pero ninguna otra información se registró. Dos ingenieros de más alto rango habían trabajado en él durante días cada uno, y luego abandonado, diciendo que no podían entenderlo. </p> <p> Estos fueron los ingenieros inteligentes formidables y de miedo, también. Por último, de la desesperación, intentaron pasar a mí. Utilizando sus extensas notas, inmediatamente me puse en reproducir el problema lo suficientemente bien como para obtener un seguimiento de la pila. Y después de seis horas, al fin entendí. Una vez que tuve que bleeping seguimiento de la pila, se puede adivinar el tiempo que me llevó a tener una solución? </p> <p> minutos </p> <p> <em> diez. </em> de ese derecho. Una vez que tuvimos un seguimiento de pila, la solución era obvia. Una semana <strong> literal </strong> de tiempo ingeniero podría haberse salvado si hubiéramos estado seguimientos de pila de registro desde el principio. Recuerde anterior, cuando digo un seguimiento de pila puede hacer la diferencia entre la resolución de un error en días y resolver en cuestión de minutos? Yo no estaba bromeando. </p> <p> (Curiosamente, algo bueno salió de él. Es experiencias como ésta, que me llevó a empezar a escribir más sobre Python, y cómo nosotros, como ingenieros puede ser más eficaz con el idioma.) </p> </div><!-- .entry-content --> </div><!-- .post-inner --> <div class="section-inner"> </div><!-- .section-inner --> </article><!-- .post --> <div class="pagination-wrapper section-inner"> <hr class="styled-separator pagination-separator is-style-wide" aria-hidden="true" /> <nav class="navigation pagination" role="navigation" aria-label="Entradas"> <h2 class="screen-reader-text">Navegación de entradas</h2> <div class="nav-links"><a class="prev page-numbers" href="https://eltecnofilo.es/"><span aria-hidden="true">←</span> <span class="nav-prev-text">Entradas <span class="nav-short">siguientes</span></span></a> <a class="page-numbers" href="https://eltecnofilo.es/">1</a> <span aria-current="page" class="page-numbers current">2</span> <a class="page-numbers" href="https://eltecnofilo.es/page/3/">3</a> <span class="page-numbers dots">…</span> <a class="page-numbers" href="https://eltecnofilo.es/page/21/">21</a> <a class="next page-numbers" href="https://eltecnofilo.es/page/3/"><span class="nav-next-text">Entradas <span class="nav-short">anteriores</span></span> <span aria-hidden="true">→</span></a></div> </nav> </div><!-- .pagination-wrapper --> </main><!-- #site-content --> <div class="footer-nav-widgets-wrapper header-footer-group"> <div class="footer-inner section-inner"> <aside class="footer-widgets-outer-wrapper" role="complementary"> <div class="footer-widgets-wrapper"> <div class="footer-widgets column-one grid-item"> <div class="widget widget_search"><div class="widget-content"><form role="search" method="get" class="search-form" action="https://eltecnofilo.es/"> <label for="search-form-2"> <span class="screen-reader-text">Buscar:</span> <input type="search" id="search-form-2" class="search-field" placeholder="Buscar …" value="" name="s" /> </label> <input type="submit" class="search-submit" value="Buscar" /> </form> </div></div> <div class="widget widget_recent_entries"><div class="widget-content"> <h2 class="widget-title subheading heading-size-3">Entradas recientes</h2> <ul> <li> <a href="https://eltecnofilo.es/vps-cloud-hosting/">VPS cloud hosting</a> </li> <li> <a href="https://eltecnofilo.es/versiones-de-ejecucion-de-python-en-acoplable-como-probar-la-ultima-release-python/">Versiones de ejecución de Python en acoplable: Cómo probar la última Release Python</a> </li> <li> <a href="https://eltecnofilo.es/leer-y-escribir-archivos-csv/">Leer y escribir archivos CSV</a> </li> <li> <a href="https://eltecnofilo.es/python-puro-vs-vs-numpy-tensorflow-comparacion-de-rendimiento/">Python puro vs vs NumPy TensorFlow Comparación de Rendimiento</a> </li> <li> <a href="https://eltecnofilo.es/estructura-python-programa-lexico/">Estructura Python Programa léxico</a> </li> </ul> </div></div><div class="widget widget_recent_comments"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Comentarios recientes</h2><ul id="recentcomments"><li class="recentcomments"><span class="comment-author-link"><a href="https://wordpress.org/" rel="external nofollow ugc" class="url">A WordPress Commenter</a></span> en <a href="https://eltecnofilo.es/hello-world/#comment-1">Hello world!</a></li></ul></div></div> </div> <div class="footer-widgets column-two grid-item"> <div class="widget widget_archive"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Archivos</h2> <ul> <li><a href='https://eltecnofilo.es/2020/04/'>abril 2020</a></li> <li><a href='https://eltecnofilo.es/2020/03/'>marzo 2020</a></li> <li><a href='https://eltecnofilo.es/2019/12/'>diciembre 2019</a></li> </ul> </div></div><div class="widget widget_categories"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Categorías</h2> <ul> <li class="cat-item cat-item-22"><a href="https://eltecnofilo.es/category/python/">Python</a> </li> <li class="cat-item cat-item-1"><a href="https://eltecnofilo.es/category/uncategorized/">Uncategorized</a> </li> </ul> </div></div><div class="widget widget_meta"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Meta</h2> <ul> <li><a rel="nofollow" href="https://eltecnofilo.es/wp-login.php">Acceder</a></li> <li><a href="https://eltecnofilo.es/feed/">Feed de entradas</a></li> <li><a href="https://eltecnofilo.es/comments/feed/">Feed de comentarios</a></li> <li><a href="https://es.wordpress.org/">WordPress.org</a></li> </ul> </div></div> </div> </div><!-- .footer-widgets-wrapper --> </aside><!-- .footer-widgets-outer-wrapper --> </div><!-- .footer-inner --> </div><!-- .footer-nav-widgets-wrapper --> <footer id="site-footer" role="contentinfo" class="header-footer-group"> <div class="section-inner"> <div class="footer-credits"> <p class="footer-copyright">© 2020 <a href="https://eltecnofilo.es/">My Blog</a> </p><!-- .footer-copyright --> <p class="powered-by-wordpress"> <a href="https://es.wordpress.org/"> Funciona gracias a WordPress </a> </p><!-- .powered-by-wordpress --> </div><!-- .footer-credits --> <a class="to-the-top" href="#site-header"> <span class="to-the-top-long"> Ir arriba <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-long --> <span class="to-the-top-short"> Subir <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-short --> </a><!-- .to-the-top --> </div><!-- .section-inner --> </footer><!-- #site-footer --> <script src='https://eltecnofilo.es/wp-includes/js/wp-embed.min.js?ver=5.3.3'></script> <script> /(trident|msie)/i.test(navigator.userAgent)&&document.getElementById&&window.addEventListener&&window.addEventListener("hashchange",function(){var t,e=location.hash.substring(1);/^[A-z0-9_-]+$/.test(e)&&(t=document.getElementById(e))&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())},!1); </script> </body> </html>