Jaunt Logo

    Aprende todo sobre Python

    Aprende todo sobre Python

    P3 months ago 242
    Aprende todo sobre Python - Page 1
    1/1068
    Descubre como llevar tu carrera de
programación al siguiente nivel y 
conviértete en ese programador 
que todos quieren ser
QUIERO LEERLO HOY MISMO
GUIA PARA PROGRAMADORES: Lo 
que nadie te cuenta ni siquiera tu 
profesor de programación
Descárgalo ahora dando click al siguiente 
botón
    2/1068
    Tabla de contenido
Acerca de 1
Capítulo1:Empezando conPython Language 2 
Observaciones 2 
Versiones 3 
Python 3.x 3 
Python 2.x 3 
Examples 4 
Empezando 4 
Verificar si Python está instalado 4 
Hola, MundoenPythonusando IDLE 5 
Hola archivo de World Python 5 
Ejecutar un shell interactivo de Python 6 
Otras conchas enlínea 7 
Ejecutar comandos como una cadena 8 
Conchas ymas alla 8 
Creando variables y asignando valores. 8 
Entrada del usuario 13
    3/1068
    IDLE - GUI de Python 14 
Solución de problemas 14 
Tipos de datos 15 
Tipos incorporados 15 
Booleanos 15 
Números 16 
Instrumentos de cuerda 16 
Secuencias y colecciones. 17 
Constantes incorporadas 17 
Probandoeltipodevariables 18 
Convertirentretiposdedatos 19 
Tipodecadenaexplícitaenladefiniciónde literales 19
    4/1068
    Tiposdedatosmutableseinmutables 19 
Construido en módulos y funciones 20 
Sangría de bloque 24 
Espaciosvs.Pestañas 25 
Tipos de colección 26 
Utilidad de ayuda 31 
Creando un modulo 32 
Función de cadena - str () y repr () 33 
repr () 33 
str () 33 
Instalación de módulos externos utilizando pip 34 
Encontrar/instalarunpaquete 35 
Actualización depaquetes instalados 35 
Actualización de pip 35 
Instalación de Python 2.7.xy 3.x 36 
Capítulo 2:* args y ** kwargs 39 
Observaciones 39 
h11 39 
h12 39 
h13 39 
Examples 40 
Usando * args al escribir funciones 40 
Usando ** kwargs al escribir funciones 40 
Usando * args al llamar a funciones 41 
Usando ** kwargs al llamar a funciones 42 
Usando * args al llamar a funciones 42 
Argumentos solo de palabra clave y requeridos de palabra clave 43 
Poblando los valores kwarg con un diccionario 43
** kwargs y valores por defecto 43 
Capítulo 3: Acceso a labasede datos 44 
Observaciones 44 
Examples 44
    5/1068
    Accediendo a la base de datos MySQL usando MySQLdb 44 
SQLite 45
La sintaxis de SQLite: un análisis en profundidad 46 
Empezando 46 
h21 46 
Atributos importantes y funciones de Connection 47 
Funciones importantes del Cursor 47 
Tipos de datos SQLite y Python 51 
Acceso a la base de datos PostgreSQL usando psycopg2 51 
Estableciendo una conexión a la base de datos y creando una tabla. 51 
Insertando datos en la tabla: 52 
Recuperando datos de la tabla: 52 
Base de datos Oracle 52 
Conexión 54 
Usando sqlalchemy 55 
Capítulo4:Accesoalcódigofuenteycódigodebytes dePython 56 
Examples 56 
Mostrar el bytecode de una función 56 
Explorando el código objeto de una función. 56 
Mostrar el código fuente de un objeto. 56 
Objetos que no están incorporados 56 
Objetos definidos interactivamente. 57 
Objetos incorporados 57 
Capítulo5:Accesodeatributo 59 
Sintaxis 59
Examples 59
Acceso a atributos básicos utilizando la notación de puntos 59 
Setters, Getters & Properties 59
Capítulo6:agruparpor() 62 
Introducción 62 
Sintaxis 62 
Parámetros 62
    6/1068
    Observaciones 62
Examples 62
Ejemplo 1 62
Ejemplo 2 63
Ejemplo 3 64
Ejemplo 4 65 
Capítulo 7: Alcance variable y vinculante 67 
Sintaxis 67 
Examples 67 
Variables globales 67 
Variables locales 68 
Variables no locales 69 
Ocurrencia vinculante 69
Las funciones omiten el alcance de la clase al buscar nombres 70 
El comando del 71
del v 71 
del v.name 71 
del v[item] 71 
del v[a:b] 72 
Ámbito local vs global 72
¿Cuálessonelalcance local yglobal? 72
¿Qué pasa con los choques de nombre? 73 
Funciones dentrode funciones 73 
globalvsnonlocal(soloPython3) 74 
Capítulo8:Almohada 76 
Examples 76 
Leer archivo de imagen 76 
Convertir archivos a JPEG 76 
Capítulo 9: Alternativas para cambiarla declaración de otros idiomas 77 
Observaciones 77 
Examples 77 
Usa lo que el lenguaje ofrece: la construcción if / else. 77
    7/1068
    Usa un dictado de funciones. 78
Usa la introspección de clase. 78 
Usando un administrador de contexto 79 
Capítulo 10: Ambiente Virtual Python - virtualenv 81 
Introducción 81 
Examples 81 
Instalación 81
Uso 81 
Instala un paquete en tu Virtualenv 82 
Otros comandos virtuales útiles 82 
Capítulo11:Análisisdeargumentosdelíneadecomandos 83 
Introducción 83 
Examples 83 
Hola mundo en argparse 83 
Ejemplo básico con docopt. 84 
Estableciendo argumentos mutuamente excluyentes con argparse 84 
Usando argumentos de línea de comando con argv 85
Mensaje de error del analizador personalizado con argparse 86
Agrupación conceptual de argumentos con argparse.add_argument_group () 86 
Ejemplo avanzado con docopt y docopt_dispatch 88 
Capítulo 12: Análisis deHTML 89 
Examples 89 
Localiza un texto después de un elemento en BeautifulSoup. 89 
Usando selectores de CSS en BeautifulSoup 89 
PyQuery 90 
Capítulo 13: Anti-patrones de Python 91 
Examples 91 
Con exceso de celo excepto la cláusula 91 
Mirando antes de saltar con la función de procesador intensivo 92 
Claves del diccionario 92 
Capítulo14: Apilar 94 
Introducción 94 
Sintaxis 94
    8/1068
    Observaciones 94
Examples 94
Creación de una clase de pila con un objeto de lista 94 
Paréntesis de paréntesis 96 
Capítulo 15: Árbol de sintaxis abstracta 97 
Examples 97 
Analizar funciones en un script de python 97 
Capítulo 16: Archivos ycarpetas I/ O 99 
Introducción 99 
Sintaxis 99 
Parámetros 99 
Observaciones 99 
Evitarelinfierno decodificación multiplataforma 99 
Examples 100 
Modos de archivo 100 
Leyendo un archivo línea por línea 102 
Obtener el contenido completo de un archivo 103 
Escribiendo en un archivo 103 
Copiando los contenidos de un archivo a un archivo diferente 104 
Compruebe si existe un archivo o ruta 104 
Copiar un árbol de directorios 105 
Iterar archivos (recursivamente) 105 
Leer un archivo entre un rango de líneas. 106 
Acceso aleatorio a archivos usando mmap 106 
Reemplazo de texto en un archivo 107 
Comprobando si un archivo está vacío 107 
Capítulo 17: ArcPy 108 
Observaciones 108 
Examples 108 
Impresión del valor de un campo para todas las filas de la clase de entidad en la geodatab 108 
createDissolvedGDB para crear un archivo gdb en el área de trabajo 108 
Capítulo18: Arrays 109
    9/1068
    Introducción 109 
Parámetros 109 
Examples 109 
Introducción básica a las matrices 109 
Accede a elementos individuales a través de índices. 110 
Agregue cualquier valor a la matriz usando el método append () 111 
Insertar valor en una matriz usando el método insert () 111 
Extiende la matriz de python usando el método extend () 111 
Agregue elementos de la lista a la matriz usando el método fromlist () 111 
Elimine cualquier elemento del arreglo usando el método remove () 111 
Eliminar el último elemento de la matriz utilizando el método pop () 112 
Obtenga cualquier elemento a través de su índice usando el método index () 112 
Invertir una matriz de python usando el método reverse () 112 
Obtener información de búfer de matriz a través del método buffer_info () 112 
Compruebe el número de apariciones de un elemento utilizando el método count () 113 
Convierte una matriz en una cadena usando el método tostring () 113 
Convierta la matriz a una lista de python con los mismos elementos utilizando el método to 113 
Agregue una cadena a la matriz de caracteres utilizando el método fromstring () 113 
Capítulo 19: Audio 114 
Examples 114 
Audio con pyglet 114 
Trabajando con archivos WAV 114 
WinSound 114 
ola 114 
Convierte cualquier archivo de sonido con python y ffmpeg 115 
Tocando los pitidos de Windows 115 
Capítulo 20: Aumentar errores / excepciones personalizados 116 
Introducción 116 
Excepción personalizada 116 
Atrapar Excepción personalizada 116 
Capítulo 21: Bibliotecade subproceso 118 
Sintaxis 118 
Parámetros 118
    10/1068
    Examples 118
Llamando Comandos Externos 118 
Más flexibilidad con Popen 119 
Lanzarunsubproceso 119 
Esperando en unsubproceso para completar 119 
Salidadelecturadeunsubproceso 119 
Accesointeractivo a subprocesos enejecución. 119 
Escribiendo a un subproceso 119 
Leyendo un stream desde un subproceso 120 
Cómo crear el argumento de la lista de comandos 120 
Capítulo 22: Bloques de código, marcos de ejecución y espacios de nombres. 122 
Introducción 122 
Examples 122 
Espacios de nombres de bloque de código 122 
Capítulo23: Bucles 124 
Introducción 124 
Sintaxis 124 
Parámetros 124 
Examples 124 
Iterando sobre listas 124
Para bucles 125 
Objetos iterablese iteradores. 126 
Romper y continuar en bucles 126 
declaracióndebreak 126 
continue declaración 127 
Bucles anidados 128
Usa el return desde dentro de una función como un break 128
Bucles con una cláusula "else" 129
¿Por qué uno usaría esta construcción extraña? 130 
Iterando sobre los diccionarios 131 
Mientras bucle 132
    11/1068
    La Declaración de Pase 133
Iterando diferentes partes de una lista con diferentes tamaños de paso 133 
Iteraciónsobre toda lalista. 134 
Iterar sobre la sub-lista 134 
El "half loop" do-while 135 
Bucle y desembalaje 135 
Capítulo24:buscando 137 
Observaciones 137 
Examples 137 
Obtención del índice para cadenas: str.index (), str.rindex () y str.find (), str.rfind () 137 
Buscando un elemento 137 
Lista 138 
Tupla 138 
Cuerda 138 
Conjunto 138 
Dictado 138 
Obtención de la lista de índice y las tuplas: list.index (), tuple.index () 138 
Buscando clave (s) para un valor en dict 139 
Obtención del índice para secuencias ordenadas: bisect.bisect_left () 140 
Buscando secuencias anidadas 140 
Búsqueda en clases personalizadas: contains y iter 141 
Capítulo 25: Características ocultas 143 
Examples 143 
Sobrecarga del operador 143 
Capítulo 26: ChemPy-paquetedepython 145 
Introducción 145
Fórmulas de análisis 145
Equilibrio de la estequiometría de una reacción química. 145 
Reacciones de equilibrio 145 
Equilibrios quimicos 146 
Fuerza iónica 146 
Cinética química (sistema de ecuaciones diferenciales ordinarias) 146 
Capítulo27:Clasesbase abstractas(abc) 148
    12/1068
    Examples 148
Configuración de la metaclase ABCMeta 148 
Por qué / Cómo usar ABCMeta y @abstractmethod 149 
Capítulo 28: Clasificación, mínimo y máximo 151 
Examples 151 
Obteniendo el mínimo o máximo de varios valores. 151 
Usando el argumento clave 151 
Argumento predeterminado a max, min 151 
Caso especial: diccionarios 152 
Por valor 152 
Obteniendo una secuencia ordenada 153 
Mínimo y máximo de una secuencia. 153 
Hacer clases personalizables ordenable 154 
Extraer N artículos más grandes o N más pequeños de un iterable 156 
Capítulo 29: Comentarios y Documentación 158 
Sintaxis 158 
Observaciones 158 
Examples 158 
Comentarios de línea única, en línea y multilínea. 158 
Accediendo programáticamente a las cadenas de documentación 159 
Una función de ejemplo 159 
Otra función de ejemplo 159 
Ventajas de docstrings sobre comentarios regulares 160 
Escribir documentación utilizando cadenas de documentación. 160 
Convenciones de sintaxis 160
PEP 257 160
Esfinge 161 
Guía de estilo de Google Python 162 
Capítulo 30: Comparaciones 163 
Sintaxis 163 
Parámetros 163 
Examples 163
    13/1068
    Mayor o menor que 163
No igual a 164 
Igual a 164 
Comparaciones de cadena 165 
Estilo 165 
Efectos secundarios 165 
Comparación por `is` vs` == ` 166 
Comparando objetos 167 
Common Gotcha: Python no impone la escritura 168 
Capítulo 31: Complementos y clases de extensión 169 
Examples 169 
Mixins 169 
Plugins con clases personalizadas 170 
Capítulo 32: Comprobando la existencia de ruta y permisos 172 
Parámetros 172 
Examples 172 
Realizar comprobaciones utilizando os.access 172 
Capítulo 33:Computación paralela 174 
Observaciones 174 
Examples 174 
Uso del módulo multiprocesamiento para paralelizar tareas. 174 
Usando scripts de Padres e Hijos para ejecutar código en paralelo 174 
Usando una extensión C para paralelizar tareas 175 
Usando el módulo PyPar para paralelizar 175
Capítulo 34: Comunicación Serial Python (pyserial) 177 
Sintaxis 177 
Parámetros 177 
Observaciones 177 
Examples 177 
Inicializar dispositivo serie 177 
Leer del puerto serial 177 
Compruebe qué puertos serie están disponibles en su máquina 178
    14/1068
    Capítulo 35: Concurrencia de Python 179
Observaciones 179
Examples 179 
El módulo de enhebrado. 179 
El módulo multiprocesamiento. 179 
Transferencia de datos entre procesos de multiprocesamiento. 180
Capítulo 36: Condicionales 183 
Introducción 183 
Sintaxis 183 
Examples 183 
si, elif, y si no 183 
Expresión condicional (o "El operador ternario") 183 
Si declaración 184 
Otra declaración 184 
Expresiones lógicas booleanas 185
Yoperador 185
O operador 185
Evaluación perezosa 185
Pruebas paracondiciones múltiples 186
Valores de verdad 187 
Usando la función cmp para obtener el resultado de comparación de dos objetos 187 
Evaluación de expresiones condicionales usando listas de comprensión 188 
Probar si un objeto es Ninguno y asignarlo 189
Capítulo37:ConectandoPythonaSQLServer 190 
Examples 190 
Conectar al servidor, crear tabla, consultar datos 190 
Capítulo 38: ConexiónseguradeshellenPython 192 
Parámetros 192 
Examples 192 
conexión ssh 192 
Capítulo 39: configparser 193
    15/1068
    Introducción 193
Sintaxis 193 
Observaciones 193 
Examples 193 
Uso básico 193 
Creando programáticamente el archivo de configuración. 194 
Capítulo40:Conjunto 195 
Sintaxis 195 
Observaciones 195 
Examples 195 
Consigue los elementos únicos de una lista. 195 
Operaciones en sets 196 
Conjuntos versus multisets 197 
Establecer operaciones usando métodos e incorporaciones 198 
Intersección 198 
Unión 198 
Diferencia 198 
Diferencia simétrica 198
Subconjuntoysuperconjunto 199
Conjuntos desunidos 199
Membresía de prueba 200
Longitud 200
Conjunto de conjuntos 200
Capítulo41:Contando 201 
Examples 201 
Contando todas las apariciones de todos los elementos en un iterable: colecciones.Contador 201 
Obtención del valor más común (-s): collections.Counter.most_common () 201 
Contando las ocurrencias de un elemento en una secuencia: list.count () y tuple.count () 202 
Contando las ocurrencias de una subcadena en una cadena: str.count () 202 
Contando ocurrencias en matriz numpy 202 
Capítulo42:Copiandodatos 204
    16/1068
    Examples 204
Realizando una copia superficial 204 
Realizando una copia profunda 204 
Realizando una copia superficial de una lista 204 
Copiar un diccionario 204 
Copiar un conjunto 205 
Capítulo43: Cortede listas(seleccióndepartes de listas) 206
Sintaxis 206
Observaciones 206 
Examples 206 
Usando el tercer argumento del "paso" 206 
Seleccionando una lista secundaria de una lista 206 
Invertir una lista con rebanar 207 
Desplazando una lista usando rebanar 207 
Capítulo44:CreandopaquetesdePython 209 
Observaciones 209 
Examples 209 
Introducción 209 
Subiendo a PyPI 210 
Configurar unarchivo .pypirc 210 
Registrarse y subir a testpypi (opcional) 210 
Pruebas 211 
Registrarse ysubir aPyPI 211
Documentación 211 
Readme 212 
Licenciamiento 212 
Haciendo paquete ejecutable 212 
Capítulo 45: Creando unservicio de Windows usando Python 214 
Introducción 214 
Examples 214 
Un script de Python que se puede ejecutar como un servicio 214
    17/1068
    Ejecutando una aplicación web de Flask como un servicio 215 
Capítulo 46: Crear entorno virtual con virtualenvwrapper en windows 217
Examples 217
Entorno virtual con virtualenvwrapper para windows 217 
Capítulo 47:ctypes 219 
Introducción 219 
Examples 219 
Uso básico 219 
Errores comunes 219
Nocargarunarchivo 219
No acceder auna función 220 
Objeto de ctypes básico 220 
arrays de ctypes 221 
Funciones de envoltura para ctypes. 222 
Uso complejo 222 
Capítulo48:Datosbinarios 224 
Sintaxis 224 
Examples 224 
Formatear una lista de valores en un objeto byte 224 
Desempaquetar un objeto byte de acuerdo con una cadena de formato 224 
Embalaje de una estructura 224 
Capítulo49:Decoradores 226 
Introducción 226 
Sintaxis 226 
Parámetros 226 
Examples 226 
Función decoradora 226 
Clase de decorador 227 
Métodosdedecoración 228
¡Advertencia! 229
Hacer que un decorador se vea como la función decorada. 229
Comounafunción 229
    18/1068
    Como una clase 230 
Decorador con argumentos (decorador de fábrica). 230 
Funciones de decorador 230 
Nota IMPORTANTE: 231
Clasesdedecorador 231
Crea una clase de singleton con un decorador. 231 
Usando un decorador para cronometrar una función. 232 
Capítulo 50: Definiendo funciones con argumentos de lista 233 
Examples 233 
Función y Llamada 233 
Capítulo 51: dejarde lado 234 
Introducción 234 
Observaciones 234 
Advertencia: 234 
Restricciones 234 
Examples 234 
Código de muestra para estantería 235 
Para resumir la interfaz (la clave es una cadena, los datos son un objeto arbitrario): 235 
Creando un nuevo estante 235 
Respóndeme 236 
Capítulo52:Depuración 239 
Examples 239 
El depurador de Python: depuración paso a paso con _pdb_ 239
A través de IPython y ipdb 241 
Depurador remoto 241 
Capítulo 53:Descomprimir archivos 243 
Introducción 243 
Examples 243 
Usando Python ZipFile.extractall () para descomprimir un archivo ZIP 243 
Usando Python TarFile.extractall () para descomprimir un tarball 243 
Capítulo54:Descriptor 244 
Examples 244
    19/1068
    Descriptor simple 244
Conversiones bidireccionales 245 
Capítulo 55: Despliegue 247 
Examples 247 
Cargando un paquete Conda 247 
Capítulo 56: Diccionario 249 
Sintaxis 249 
Parámetros 249 
Observaciones 249 
Examples 249 
Accediendo a los valores de un diccionario. 249
El constructor dict () 250 
Evitar las excepciones de KeyError 250 
Acceso a claves y valores. 251 
Introducción al Diccionario 252 
creando undict 252 
sintaxis literal 252 
comprensión de dictado 252 
clase incorporada: dict() 252
modificando un dict 253
Diccionario con valores por defecto 253 
Creando un diccionario ordenado 254 
Desempaquetando diccionarios usando el operador ** 254 
Fusionando diccionarios 255 
Python 3.5+ 255 
Python 3.3+ 255 
Python 2.x, 3.x 255 
La coma final 256 
Todas las combinaciones de valores de diccionario. 256 
Iterando sobre un diccionario 256 
Creando un diccionario 257 
Diccionarios ejemplo 258
    20/1068
    Capítulo57:DiferenciaentreMóduloyPaquete 259 
Observaciones 259 
Examples 259 
Módulos 259 
Paquetes 259 
Capítulo 58: Distribución 261 
Examples 261 
py2app 261 
cx_Freeze 262 
Capítulo 59: Django 264 
Introducción 264 
Examples 264 
Hola mundo con django 264 
Capítulo60:Ejecucióndecódigodinámicocon`exec`y` eval` 266 
Sintaxis 266 
Parámetros 266 
Observaciones 266 
Examples 267 
Evaluando declaraciones con exec 267 
Evaluando una expresión con eval 267 
Precompilando una expresión para evaluarla varias veces. 267 
Evaluar una expresión con eval utilizando globales personalizados 267 
Evaluar una cadena que contiene un literal de Python con ast.literal_eval 268 
Código de ejecución proporcionado por un usuario no confiable que utiliza exec, eval o ast 268 
Capítulo 61:Eldismódulo 269
Examples 269
Constantes en el módulo dis 269
¿Qué es el código de bytes de Python? 269 
Desmontaje de módulos. 269 
Capítulo62:Elintérprete(consoladelíneadecomandos) 271 
Examples 271 
Obtención de ayuda general 271
    21/1068
    Refiriéndose a la última expresión. 271
Abriendo la consola de Python 272 
La variable PYTHONSTARTUP 272 
Argumentos de línea de comando 272 
Obteniendo ayuda sobre un objeto 273 
Capítulo 63:El módulobase64 275 
Introducción 275 
Sintaxis 275 
Parámetros 275 
Observaciones 277 
Examples 277 
Codificación y decodificación Base64 277 
Codificación y decodificación Base32 279 
Codificación y decodificación Base16 279 
Codificación y decodificación ASCII85 280 
Codificación y decodificación Base85 280 
Capítulo 64: El módulo de configuración regional 282 
Observaciones 282 
Examples 282 
Formato de moneda Dólares estadounidenses utilizando el módulo de configuración regional 282 
Capítulo 65:Elmóduloos 283 
Introducción 283 
Sintaxis 283 
Parámetros 283 
Examples 283 
Crear un directorio 283 
Obtener directorio actual 283 
Determinar el nombre del sistema operativo. 283 
Eliminar un directorio 284 
Seguir un enlace simbólico (POSIX) 284 
Cambiar permisos en un archivo 284 
makedirs - creación de directorio recursivo 284 
Capítulo 66:Empezando conGZip 286
    22/1068
    Introducción 286
Examples 286 
Lee y escribe archivos zip de GNU 286 
Capítulo67:Enchufes 287 
Introducción 287 
Parámetros 287 
Examples 287 
Envío de datos a través de UDP 287 
Recepción de datos a través de UDP 287 
Envío de datos a través de TCP 288 
Servidor de socket TCP multihilo 289 
Raw Sockets en Linux 290 
Capítulo68:entorno virtualconvirtualenvwrapper 292 
Introducción 292 
Examples 292 
Crear entorno virtual con virtualenvwrapper 292 
Capítulo 69:Entornos virtuales 294 
Introducción 294 
Observaciones 294 
Examples 294 
Creando y utilizando un entorno virtual. 294 
Instalando laherramienta virtualenv 294 
Creando unnuevoentorno virtual. 294 
Activando unentorno virtual existente 295 
Guardar y restaurar dependencias. 295 
Salirdeunentornovirtual. 296 
Usando un entorno virtual en un host compartido 296 
Entornosvirtualesincorporados 296 
Instalación de paquetes en un entorno virtual 297 
Creando un entorno virtual para una versión diferente de python 298 
Gestionar múltiples entornos virtuales con virtualenvwrapper 298 
Instalación 298
    23/1068
    Uso 299 
Directorios de proyectos 299 
Descubrir qué entorno virtual está utilizando 300 
Especificando la versión específica de Python para usar en el script en Unix / Linux 300 
Usando virtualenv con cáscara de pescado 301 
Realización de entornos virtuales utilizando Anaconda. 301 
Crear un entorno 302 
Activa y desactiva tu entorno. 302 
Ver una lista de entornos creados. 302 
Eliminar un entorno 302 
Comprobando si se ejecuta dentro de un entorno virtual 302
Capítulo70:Entrada ysalida básica 304
Examples 304 
Usando input () y raw_input () 304 
Usando la función de impresión 304 
Función para pedir al usuario un número 305 
Imprimir una cadena sin una nueva línea al final 305 
Leer de stdin 306 
Entrada desde un archivo 306 
Capítulo 71: Entrada, subconjunto y salida de archivos de datos externos utilizando Pandas 309
Introducción 309
Examples 309 
Código básico para importar, subcontratar y escribir archivos de datos externos mediante P 309 
Capítulo72:Enumerar 311 
Observaciones 311 
Examples 311 
Creación de una enumeración (Python 2.4 a 3.3) 311 
Iteración 311 
Capítulo73:Errorescomunes 312 
Introducción 312 
Examples 312 
Cambiando la secuencia sobre la que estás iterando 312 
Argumento predeterminado mutable 315
    24/1068
    Lista de multiplicación y referencias comunes. 316 
Identidad entera y de cadena 320 
Accediendo a los atributos de int literals. 321 
Encadenamiento de u operador 322 
sys.argv [0] es el nombre del archivo que se está ejecutando 323 
h14 323
Los diccionarios están desordenados. 323
Bloqueo global de intérprete (GIL) y bloqueo de hilos 324 
Fugas variables en listas de comprensión y para bucles. 325 
Retorno múltiple 326 
Teclas JSON pitónicas 326 
Capítulo74:EscribiendoaCSVdesdeStringoList 328 
Introducción 328 
Parámetros 328 
Observaciones 328 
Examples 328
Ejemplo básico de escritura 328 
Anexando una cadena como nueva línea en un archivo CSV 329 
Capítulo75:EventosenviadosdePythonServer 330 
Introducción 330 
Examples 330 
Frasco SSE 330 
Asyncio SSE 330 
Capítulo 76: Examen de launidad 331 
Observaciones 331 
Examples 331 
Pruebas de excepciones 331 
Funciones de simulación con unittest.mock.create_autospec 332 
Configuración de prueba y desmontaje dentro de un unittest.TestCase 333 
Afirmación de excepciones 334 
Eligiendo aserciones dentro de unitests 335 
Pruebas unitarias con pytest 336
    25/1068
    Capítulo77:Excepciones 340 
Introducción 340 
Sintaxis 340 
Examples 340 
Levantando excepciones 340 
Atrapar excepciones 340 
Ejecutando código de limpieza con finalmente 341 
Re-elevando excepciones 341 
Cadena de excepciones con aumento de 342 
Jerarquía de excepciones 342 
Las excepciones son objetos también 345 
Creación de tipos de excepción personalizados 345 
No atrapes todo! 346 
Atrapando múltiples excepciones 347 
Ejemplos prácticos de manejo de excepciones. 347
Entradadelusuario 347
Los diccionarios 348
Más 348 
Capítulo 78: Excepciones del Commonwealth 350 
Introducción 350 
Examples 350 
IndentationErrors (o indentation SyntaxErrors) 350 
IndentationError/SyntaxError: sangría inesperada 350 
Ejemplo 350 
IndentationError/SyntaxError: unindent no coincide con ningún nivel de sangría externa 351 
Ejemplo 351 
Error Tabulación: Se esperaba un bloque tabulado 351 
Ejemplo 351 
IndentationError: usoincoherente de tabulaciones y espacios en sangría 351 
Ejemplo 352 
Cómo evitar este error 352 
TypeErrors 352
    26/1068
    TypeError:[definición /método]toma? argumentos posicionales pero? se le dio 352 
Ejemplo 352 
TypeError: tipo (s) de operando nocompatibles para [operando]: '???' y '???' 353 
Ejemplo 353 
Error de tecleado: '???' El objeto noes iterable / subscriptible: 353 
Ejemplo 353 
Errordetecleado:'???' elobjeto noesllamable 354 
Ejemplo 354 
NameError: name '???' no está definido 354
Simplemente no está definido en ninguna parte en el código 354 
Tal vez se define más adelante: 354 
O no fue import 355 
Los alcances de Python y la Regla LEGB: 355 
Otros errores 355 
AssertError 355 
Teclado interrumpir 356
ZeroDivisionError 356 
Error de sintaxis en buen código 357 
Capítulo 79:Explotación florestal 358 
Examples 358 
Introducción al registro de Python 358 
Excepciones de registro 359 
Capítulo80:Exposiciónción 362 
Sintaxis 362 
Examples 362 
Raíz cuadrada: math.sqrt () y cmath.sqrt 362 
Exposiciónción utilizando builtins: ** y pow () 363 
Exposiciónción utilizando el módulo matemático: math.pow () 363 
Función exponencial: math.exp () y cmath.exp () 364 
Función exponencial menos 1: math.expm1 () 364 
Métodos mágicos y exponenciales: incorporados, matemáticos y matemáticos. 365 
Exponenciación modular: pow () con 3 argumentos. 366
    27/1068
    Raíces: raíz nth con exponentes fraccionarios 367 
Cálculo de grandes raíces enteras 367
Capítulo 81: Expresiones Regulares (Regex) 369 
Introducción 369 
Sintaxis 369 
Examples 369 
Coincidiendo con el comienzo de una cadena 369 
buscando 371 
Agrupamiento 371 
Grupos nombrados 372
Grupos no capturadores 372
Escapar de personajes especiales 373 
Reemplazo 373 
Reemplazo de cuerdas 373 
Usandoreferenciasdegrupo 373
Usandounafuncióndereemplazo 374 
Encontrar todos los partidos no superpuestos 374 
Patrones precompilados 374 
Comprobación de caracteres permitidos 375 
Dividir una cadena usando expresiones regulares 375 
Banderas 376 
Bandera de palabras clave 376 
Banderas en linea 376 
Iterando sobre los partidos usando `re.finditer` 377 Unir 
una expresión solo en lugares específicos 377 
Capítulo 82: Extensiones de escritura 379
Examples 379 
Hola mundo con extensión C 379 
Pasando un archivo abierto a C Extensions 380 
Extensión C usando c ++ y Boost 380 
Código C ++ 380
    28/1068
    Capítulo 83: Fecha yhora 383
Observaciones 383
Examples 383 
Análisis de una cadena en un objeto de fecha y hora compatible con la zona horaria 383 
Aritmética de fecha simple 383 
Uso básico de objetos datetime 384 
Iterar sobre fechas 384 
Analizar una cadena con un nombre de zona horaria corto en un objeto de fecha y hora con f 385 
Construyendo tiempos de datos conscientes de la zona horaria 386 
Análisis de fecha y hora difuso (extracción de fecha y hora de un texto) 388 
Cambio entre zonas horarias 388 
Análisis de una marca de tiempo ISO 8601 arbitraria con bibliotecas mínimas 389 
Convertir la marca de tiempo a datetime 389 
Restar meses de una fecha con precisión 390 
Calcular las diferencias de tiempo 390 
Obtener una marca de tiempo ISO 8601 391
Sin zona horaria,con microsegundos. 391 
Con zona horaria,con microsegundos. 391 
Con zona horaria,sin microsegundos. 391 
Capítulo84:Filtrar 392 
Sintaxis 392 
Parámetros 392 
Observaciones 392 
Examples 392 
Uso básico del filtro. 392 
Filtro sin función 393 
Filtrar como comprobación de cortocircuito. 393 
Función complementaria: filterfalse, ifilterfalse 394 
Capítulo 85:Formato de cadena 396 
Introducción 396 
Sintaxis 396 
Observaciones 396
    29/1068
    Examples 396
Conceptos básicos de formato de cadena 396 
Alineación y relleno. 398 
Formato literales (f-string) 398 
Formato de cadena con fecha y hora 399 
Formato utilizando Getitem y Getattr 400 
Formato flotante 400 
Formato de valores numéricos 401 
Formato personalizado para una clase 402 
Formateo anidado 403 
Acolchado y cuerdas truncantes, combinadas. 403 
Marcadores de posición nombrados 404 
Usando un diccionario (Python 2.x) 404 
Usando un diccionario (Python 3.2+) 404 
Sin un diccionario: 404
Capítulo 86:Formatode fecha 405
Examples 405 
Tiempo entre dos fechas 405 
Analizando la cadena al objeto datetime 405 
Salida de objetos de fecha y hora a cadena 405 
Capítulo 87:Función demapa 406 
Sintaxis 406 
Parámetros 406 
Observaciones 406 
Examples 406 
Uso básico de map, itertools.imap y future_builtins.map 406 
Mapeando cada valor en una iterable 407 
Mapeo de valores de diferentes iterables. 408 
Transposición con mapa: uso de "Ninguno" como argumento de función (solo python 2.x) 409 
Series y mapeo paralelo 410 
Capítulo88:Funciones 413 
Introducción 413 
Sintaxis 413
    30/1068
    Parámetros 413
Observaciones 413 
Recursos adicionales 414 
Examples 414 
Definiendo y llamando funciones simples. 414 
Devolviendo valores desde funciones 416 
Definiendo una función con argumentos. 417 
Definiendo una función con argumentos opcionales. 417 
Advertencia 418 
Definiendo una función con múltiples argumentos. 418 
Definiendo una función con un número arbitrario de argumentos. 418 
Número arbitrario deargumentos posicionales: 418 
Número arbitrario de argumentos de palabras clave 419 
Advertencia 420
Nota sobre nombrar 421 
Nota sobre la singularidad 421 
Nota sobre funciones de anidamiento con argumentos opcionales 421 
Definiendo una función con argumentos mutables opcionales. 421 
Explicación 422 
Solución 422 
Funciones Lambda (Inline / Anónimo) 423 
Argumento de paso y mutabilidad. 426 
Cierre 427 
Funciones recursivas 427 
Límite de recursión 428 
Funciones anidadas 429 
Iterable y desempaquetado del diccionario. 429 
Forzando el uso de parámetros nombrados 431 
Lambda recursiva utilizando variable asignada 431 
Descripción del código 432 
Capítulo 89:Funciones parciales 433 
Introducción 433
    31/1068
    Sintaxis 433
Parámetros 433 
Observaciones 433 
Examples 433 
Elevar el poder 433 
Capítulo90:Generadores 435 
Introducción 435 
Sintaxis 435 
Examples 435 
Iteración 435
La siguiente función () 435 
Enviando objetos a un generador. 436 
Expresiones generadoras 437 
Introducción 437 
Usando un generador para encontrar los números de Fibonacci 440 
Secuencias infinitas 440 
Ejemplo clásico - números de Fibonacci 441 
Rindiendo todos los valores de otro iterable. 441 
Coroutines 442 
Rendimiento con recursión: listado recursivo de todos los archivos en un directorio 442 
Iterando sobre generadores en paralelo. 443 
Código de construcción de lista de refactorización 444 
buscando 444 
Capítulo91:Gestores de contexto (declaración “con”) 446 
Introducción 446 
Sintaxis 446 
Observaciones 446 
Examples 447 
Introducción a los gestores de contexto y con la declaración. 447 
Asignar a un objetivo 447 
Escribiendo tu propio gestor de contexto. 448 
Escribiendo tu propio administrador de contexto usando la sintaxis del generador. 449
    32/1068
    Gestores de contexto multiples 450
Gestionar recursos 450 
Capítulo92:Gráficosdetortuga 452 
Examples 452 
Ninja Twist (Tortuga Gráficos) 452 
Capítulo93:hashlib 453 
Introducción 453 
Examples 453 
Hash MD5 de una cadena 453 
algoritmo proporcionado por OpenSSL 454 
Capítulo 94: Heapq 455 
Examples 455 
Artículos más grandes y más pequeños en una colección. 455 
Artículo más pequeño en una colección. 455
Capítulo95:Herramienta 2to3 457 
Sintaxis 457 
Parámetros 457 
Observaciones 458 
Examples 458 
Uso básico 458 
Unix 458 
Windows 458 
Unix 459 
Windows 459 
Capítulo 96: herramienta grafica 460 
Introducción 460 
Examples 460 
PyDotPlus 460 
Instalación 460 
PyGraphviz 461 
Capítulo97:ijson 463 
Introducción 463
    33/1068
    Examples 463
Ejemplo simple 463 
Capítulo 98: Implementaciones no oficiales de Python 464 
Examples 464 
IronPython 464 
Hola Mundo 464 
enlacesexternos 464 
Jython 464 
Hola Mundo 465 
enlacesexternos 465 
Transcrypt 465 
Tamañoyvelocidaddelcódigo 465 
IntegraciónconHTML 466
IntegraciónconJavaScriptyDOM 466
Integracióncon otras bibliotecas de JavaScript 467
Relación entre Python y código JavaScript 467
enlacesexternos 468
Capítulo 99:Importando modulos 469
Sintaxis 469 
Observaciones 469 
Examples 469 
Importando un modulo 469 
Importando nombres específicos desde un módulo 471 
Importando todos los nombres de un módulo 471
La variable especial all 472 
Importación programática 473 
Importar módulos desde una ubicación de sistema de archivos arbitraria. 473 
Reglas PEP8 para Importaciones 474 
Importando submódulos 474
 importar () función 474 
Reimportando un módulo 475
    34/1068
    Python 2 475 
Python 3 475 
Capítulo100:IncompatibilidadesquesemuevendePython2aPython3 477 
Introducción 477
Observaciones 477 
Examples 478 
Declaración de impresión vs. función de impresión 478 
Cuerdas: Bytes contra Unicode 479 
División entera 481 
Reducir ya no es una función incorporada. 483 
Diferencias entre las funciones de rango y rango 484 
Compatibilidad 485 
Desembalaje Iterables 486 
Levantando y manejando excepciones 488
.next () método en los iteradores renombrados 490 
Comparación de diferentes tipos 490 
Entrada del usuario 491 
Cambios en el método del diccionario 492 
La sentencia exec es una función en Python 3 493 
Error de la función hasattr en Python 2 493 
Módulos renombrados 494 
Compatibilidad 495 
Constantes octales 495 
Todas las clases son "clases de nuevo estilo" en Python 3. 495 
Se eliminaron los operadores <> y ``, sinónimo de! = Y repr () 496 
codificar / decodificar a hex ya no está disponible 497 
Función cmp eliminada en Python 3 498 
Variables filtradas en la lista de comprensión. 498 
mapa() 499 
filter (), map () y zip () devuelven iteradores en lugar de secuencias 500 
Importaciones absolutas / relativas 501 
Más sobre Importaciones Relativas 502 
Archivo I / O 503
    35/1068
    La función round () rompe el empate y devuelve el tipo 503 
rotura de corbata redonda () 503
round () tipo de retorno 504 
Verdadero, Falso y Ninguno 504 
Devolver valor al escribir en un objeto de archivo 505 
largo vs. int 505 
Valor booleano de clase 506 
Capítulo101:Indexaciónycorte 507 
Sintaxis 507 
Parámetros 507 
Observaciones 507 
Examples 507 
Rebanado basico 507 
Hacer una copia superficial de una matriz 508 
Invertir un objeto 509 
Clases personalizadas de indexación: getitem , setitem y delitem 509 
Asignación de rebanada 510 
Rebanar objetos 511 
Indexación básica 511 
Capítulo 102: Interfazdepuertade enlacedeservidorweb(WSGI) 513 
Parámetros 513 
Examples 513 
Objeto de servidor (Método) 513 
Capítulo 103:Introducción a RabbitMQ utilizando AMQPStorm 515 
Observaciones 515 
Examples 515 
Cómo consumir mensajes de RabbitMQ 515 
Cómo publicar mensajes a RabbitMQ 516 
Cómo crear una cola retrasada en RabbitMQ 517 
Capítulo104:Iterableseiteradores 519
Examples 519
Iterador vs Iterablevs generador 519 
Lo que puede ser iterable 520
    36/1068
    Iterando sobre todo iterable 520
Verificar solo un elemento en iterable. 521 
Extraer valores uno por uno. 521
¡El iterador no es reentrante! 521 
Capítulo 105: kivy - Framework Python multiplataforma para el desarrollo de NUI 522 
Introducción 522 
Examples 522 
Primera aplicación 522 
Capítulo 106:Ladeclaracióndepase 525 
Sintaxis 525 
Observaciones 525 
Examples 527 
Ignorar una excepción 527 
Crear una nueva excepción que puede ser capturada 527 
Capítulo107:Lafuncióndeimpresión 528 
Examples 528 
Fundamentos de impresión 528 
Parámetros de impresión 529 
Capítulo108:Lavariableespecial name 531 
Introducción 531 
Observaciones 531 
Examples 531
 name == ' main ' 531
Situación 1 531 
Situación 2 531 
function_class_or_module . name 532 
Utilizar en el registro 533 
Capítulo 109:Las clases 534 
Introducción 534 
Examples 534 
Herencia basica 534 
Funcionesincorporadas que funcionanconherencia. 535
    37/1068
    Variables de clase e instancia 536
Métodos enlazados, no enlazados y estáticos. 537 
Clases de estilo nuevo vs. estilo antiguo 539 
Valores por defecto para variables de instancia 540 
Herencia múltiple 541 
Descriptores y búsquedas punteadas 543 
Métodos de clase: inicializadores alternos 544 
Composición de la clase 545 
Parche de mono 546 
Listado de todos los miembros de la clase 547 
Introducción a las clases 548 
Propiedades 550 
Clase de singleton 552 
Capítulo110:Lectura yEscritura CSV 554 
Examples 554 
Escribiendo un archivo TSV 554 
Pitón 554 
Archivodesalida 554 
Usando pandas 554 
Capítulo 111: Lista 555 
Introducción 555 
Sintaxis 555 
Observaciones 555 
Examples 555 
Acceso a los valores de la lista 555 
Lista de métodos y operadores soportados. 557 
Longitud de una lista 562 
Iterando sobre una lista 562 
Comprobando si un artículo está en una lista 563 
Elementos de la lista de inversión 564 
Comprobando si la lista está vacía 564 
Concatenar y fusionar listas 564
    38/1068
    Examples 582
Todos y cada uno 565
Eliminar valores duplicados en la lista 566 
Acceso a valores en lista anidada 566 
Comparacion de listas 568 
Inicializando una lista a un número fijo de elementos 568 
Capítulo 112: Lista de Comprensiones 570
Introducción 570 
Sintaxis 570 
Observaciones 570 
Examples 570 
Lista de comprensiones condicionales 570 
Lista de Comprensiones con Bucles Anidados 572 
Refactorización de filtro y mapa para enumerar las comprensiones. 573 
Refactorización - Referencia rápida 574 
Comprensiones de lista anidadas 575 
Iterar dos o más listas simultáneamente dentro de la comprensión de la lista 575 
Capítulo 113: Lista de desestructuración (también conocido como embalaje y desembalaje) 577
Examples 577 
Tarea de destrucción 577
La destrucción como valores. 577
La destrucción como lista 577 
Ignorar valores en las tareas de desestructuración. 578 
Ignorar listas en tareas de desestructuración. 578 
Argumentos de la función de embalaje 578 
Empaquetando una lista de argumentos 579 
Packing argumentos de palabras clave 579 
Desempaquetando argumentos de funciones 581
Capítulo 114:Listar comprensiones 582 
Introducción 582 
Sintaxis 582 
Observaciones 582
    39/1068
    Examples 604
Lista de Comprensiones 582
más 583
Dobleiteración 584
Mutación in situ y otros efectos secundarios 584
Losespaciosenblancoenlalistadecomprensión 585
Diccionario de Comprensiones 586 
Expresiones del generador 587 
Casos de uso 589 
Establecer Comprensiones 590 
Evite operaciones repetitivas y costosas usando cláusula condicional 590 
Comprensiones que involucran tuplas 592
Contando Ocurrencias Usando Comprensión 592 
Cambio de tipos en una lista 593 
Capítulo115:Listasenlazadas 594 
Introducción 594 
Examples 594 
Ejemplo de lista enlazada única 594 
Capítulo 116: Llama a Pythondesde C # 598 
Introducción 598 
Observaciones 598 
Examples 599 
Script de Python para ser llamado por la aplicación C # 599 
Código C # llamando al script Python 600 
Capítulo 117: Maldiciones básicas con pitón 602 
Observaciones 602 
Examples 602 
Ejemplo básico de invocación 602
La función de ayuda wrapper (). 602 
Capítulo118:ManipulandoXML 604 
Observaciones 604
    40/1068
    Abriendo y leyendo usando un ElementTree 604 
Modificar un archivo XML 604
Crear y construir documentos XML 605 
Abrir y leer archivos XML grandes utilizando iterparse (análisis incremental) 605 
Buscando el XML con XPath 606 
Capítulo 119:Matemáticas complejas 608 
Sintaxis 608 
Examples 608 
Aritmética compleja avanzada 608 
Aritmética compleja básica 609 
Capítulo 120: Matraz 610 
Introducción 610 
Sintaxis 610 
Examples 610 
Los basicos 610 
URL de enrutamiento 611 
Métodos HTTP 611 
Archivos y plantillas 612 
Jinja Templando 613
El objeto de solicitud 614
Parámetros de URL ..... 614
Cargasde archivos ..... 615
Galletas ....................... 615
Capítulo 121:Matrices multidimensionales 616
Examples ........................ 616 
Listas en listas ..................... 616 
Listas en listas en listas en.... 617
Capítulo122:Metaclases 618 
Introducción 618 
Observaciones 618 
Examples 618 
Metaclases basicas 618
    41/1068
    Singletons utilizando metaclases 619
Usando una metaclase 620 
Sintaxisdemetaclase 620
CompatibilidaddePython2 y3 consix 620
Funcionalidad personalizada con metaclases. 620 
Introducción a las metaclases 621
¿Qué es una metaclase? 621 
La metaclase mas simple 621 
Una metaclase que hace algo 621 
La metaclase por defecto. 622 
Capítulo123:MétodoAnulando 624 
Examples 624 
Método básico anulando 624 
Capítulo 124: Métodosde cuerda 625 
Sintaxis 625 
Observaciones 626 
Examples 626 
Cambiar la capitalización de una cadena 626 
str.casefold() 626 
str.upper() 627 
str.lower() 627 
str.capitalize() 627 
str.title() 627 
str.swapcase() 627
Uso como métodos de clase str 627 
Dividir una cadena basada en un delimitador en una lista de cadenas 628 
str.split(sep=None, maxsplit=-1) 628 
str.rsplit(sep=None, maxsplit=-1) 629 
Reemplace todas las ocurrencias de una subcadena por otra subcadena 629 
str.replace(old, new[, count]) : 629 
str.format y f-strings: formatea valores en una cadena 630 
Contando el número de veces que una subcadena aparece en una cadena 631 
str.count(sub[, start[, end]]) 631
    42/1068
    Prueba los caracteres iniciales y finales de una cadena. 632 
str.startswith(prefix[, start[, end]]) 632 
str.endswith(prefix[, start[, end]]) 632 
Probando de qué está compuesta una cuerda 633 
str.isalpha 633
str.isupper , str.islower , str.istitle 633 
str.isdecimal , str.isdigit , str.isnumeric 634 
str.isalnum 634 
str.isspace 635 
str.translate: Traducir caracteres en una cadena 635 
Eliminar caracteres iniciales / finales no deseados de una cadena 636
str.strip([chars]) 636 
str.rstrip([chars]) y str.lstrip([chars]) 636 
Comparaciones de cadenas insensibles al caso 637 Unir 
una lista de cadenas en una cadena 638 
Constantes útiles del módulo de cadena 638 
string.ascii_letters : 639 
string.ascii_lowercase 639 
string.ascii_uppercase : 639 
string.digits : 639 
string.hexdigits : 639 
string.octaldigits : 639 
string.punctuation : 639 
string.whitespace : 640 
string.printable : 640 
Invertir una cadena 640 
Justificar cuerdas 641 
Conversión entre str o bytes de datos y caracteres Unicode 641 
Cadena contiene 642 
Capítulo 125: Métodos definidos por el usuario 644
Examples 644
Creando objetos de método definidos por el usuario 644 
Ejemplo de tortuga 645
    43/1068
    Capítulo126:Mixins 646 
Sintaxis 646 
Observaciones 646 
Examples 646 
Mezclar 646 
Métodos de anulación en Mixins 647 
Capítulo127:Modismos 649 
Examples 649 
Inicializaciones clave del diccionario 649 
Variables de conmutacion 649 Use 
la prueba de valor de verdad 649 
Prueba de " main " para evitar la ejecución inesperada del código 650 
Capítulo128:Móduloaleatorio 651 
Sintaxis 651 
Examples 651 
Aleatorio y secuencias: barajar, selección y muestra. 651 
barajar() 651 
elección() 651 
muestra() 651
Creación de enteros y flotadores aleatorios: randint, randrange, random y uniform 652
randint () 652
randrange () 652 
aleatorio 653 
uniforme 653 
Números aleatorios reproducibles: semilla y estado 653 
Crear números aleatorios criptográficamente seguros 654 
Creando una contraseña de usuario aleatoria 655 
Decisión Binaria Aleatoria 656 
Capítulo129:Móduloasyncio 657 
Examples 657 
Sintaxis de Coroutine y Delegación 657 
Ejecutores asincronos 658
    44/1068
    Usando UVLoop 659
Primitiva de sincronización: Evento 659 
Concepto 659 
Ejemplo 660 
Un simple websocket 660 
Error común sobre asyncio 661 
Capítulo 130: Módulo decola 663 
Introducción 663 
Examples 663 
Ejemplo simple 663 
Capítulo 131: Módulo de colecciones 664 
Introducción 664 
Observaciones 664 
Examples 664 
colecciones. 664 
colecciones.defaultdict 666 
colecciones.OrdenedDict 667 
colecciones.namedu tupla 668 
colecciones.deque 669 
colecciones.ChainMap 670 
Capítulo132:Módulodefunciones 672 
Examples 672 
parcial 672 
ordenamiento total 672 
reducir 673 
lru_cache 673 
cmp_to_key 674 
Capítulo133:Módulodematemáticas 675
Examples 675
Redondeo: redondo, suelo, ceil, trunc 675
¡Advertencia! 676 
Advertencia sobre la división de números negativos en el piso, corte y número entero 676
    45/1068
    Logaritmos 676
Copiando carteles 677 
Trigonometría 677 
Cálculo de la longitud de la hipotenusa. 677 
Convertir grados a / desde radianes 677 
Funciones seno, coseno, tangente e inversa. 677 
Seno hiperbólico, coseno y tangente. 678 
Constantes 678 
Números imaginarios 679 
Infinito y NaN ("no es un número") 679 
Pow para una exponenciación más rápida 682 
Números complejos y el módulo cmath. 682
Capítulo134:Módulodenavegadorweb 686 
Introducción 686 
Sintaxis 686 
Parámetros 686 
Observaciones 687 
Examples 688 
Abrir una URL con el navegador predeterminado 688 
Abrir una URL con diferentes navegadores 688 
Capítulo 135: Módulo Deque 690 
Sintaxis 690 
Parámetros 690 
Observaciones 690 
Examples 690 
Uso básico deque 690 
límite de tamaño de salida 691 
Métodos disponibles en deque. 691 
Amplia primera búsqueda 692 
Capítulo 136:Módulo Itertools 693 
Sintaxis 693 
Examples 693 
Agrupando elementos de un objeto iterable usando una función 693
    46/1068
    Toma una rebanada de un generador 694
itertools.product 695 
itertools.count 695 
itertools.takewhile 696 
itertools.dropwhile 697 
Zipping dos iteradores hasta que ambos están agotados 698 
Método de combinaciones en el módulo Itertools 698 
Encadenando múltiples iteradores juntos 699
itertools.repeat 699 
Obtener una suma acumulada de números en un iterable 699 
Recorre los elementos en un iterador 700 
itertools.permutaciones 700 
Capítulo 137: Módulo JSON 701 
Observaciones 701 
Los tipos 701 
Valores predeterminados 701 
Tipos de serialización: 701 
Tipos de serialización: 701 
Personalización (des) serialización 702 
Publicación por entregas: 702
De serialización: 702 
Mayor (des) serialización personalizada: 703 
Examples 703 
Creando JSON desde el dictado de Python 703 
Creando el dictado de Python desde JSON 703 
Almacenamiento de datos en un archivo 704 
Recuperando datos de un archivo 704
`load` vs` loads`, `dump` vs` dumps` 704 
Llamando a `json.tool` desde la línea de comandos a la salida JSON de impresión bonita 705 
Formato de salida JSON 706 
Configuración de sangría para obtener una salida más bonita 706
Ordenando las teclas alfabéticamente para obtener unresultadoconsistente 706
    47/1068
    Deshacersedelosespaciosenblancoparaobtener unasalidacompacta 707
JSON que codifica objetos personalizados 707 
Capítulo138:Módulooperador 709
Examples 709
Operadores como alternativa a un operador infijo. 709 
Methodcaller 709 
Itemgetter 709 
Capítulo 139: módulo pyautogui 711 
Introducción 711 
Examples 711 
Funciones del mouse 711 
Funciones del teclado 711 
ScreenShot y reconocimiento de imágenes 711 
Capítulo140:MóduloSqlite3 712 
Examples 712 
Sqlite3 - No requiere proceso de servidor separado. 712 
Obtención de los valores de la base de datos y manejo de errores. 712 
Capítulo141:Multihilo 714 
Introducción 714 
Examples 714 
Conceptos básicos de multihilo 714 
Comunicando entre hilos 715 
Creando un grupo de trabajadores 716 Uso 
avanzado de multihilos 717 
Impresora avanzada (logger) 717 
Hilo que se puede detener con un bucle de tiempo 718 
Capítulo142: Multiprocesamiento 720 
Examples 720 
Ejecutando dos procesos simples 720 Uso 
de la piscina y el mapa 721 
Capítulo143:MutablevsInmutable(yHashable)enPython 722 
Examples 722
    48/1068
    Mutable vs inmutable 722
Inmutables 722 
Ejercicio 723 
Mutables 723 
Ejercicio 724 
Mutables e inmutables como argumentos 724 
Ejercicio 725 
Capítulo 144: Neo4j yCypher usandoPy2Neo 726 
Examples 726 
Importación y Autenticación 726 
Añadiendo nodos a Neo4j Graph 726 
Agregando relaciones a Neo4j Graph 726 
Consulta 1: Autocompletar en títulos de noticias 727 
Consulta 2: obtener artículos de noticias por ubicación en una fecha en particular 727 
Cypher Query Samples 727 
Capítulo 145: Nodode lista enlazada 729 
Examples 729 
Escribe un nodo de lista enlazada simple en python 729 
Capítulo146:Objetosdepropiedad 730 
Observaciones 730 
Examples 730 
Usando el decorador @property 730 
Usando el decorador de propiedad para las propiedades de lectura-escritura 730 
Anulando solo un captador, configurador o un eliminador de un objeto de propiedad 731 
Usando propiedades sin decoradores 731 
Capítulo 147:Operadores booleanos 734 
Examples 734
y 734 
o 734 
no 735 
Evaluación de cortocircuito 735
`and` y` or` no están garantizados para devolver un valor booleano 736
    49/1068
    Un simple ejemplo 736
Capítulo148:OperadoresdeBitwise 737 
Introducción 737 
Sintaxis 737 
Examples 737 
Y a nivel de bit 737 
Bitwise o 737 
XOR de bitwise (OR exclusivo) 738 
Desplazamiento a la izquierda en modo de bits 738 
Cambio a la derecha en el modo de bits 739 
Bitwise NO 739 
Operaciones in situ 741
Capítulo 149: Operadores matemáticos simples 742 
Introducción 742 
Observaciones 742 
Tipos numéricos ysus metaclases. 742 
Examples 742 
Adición 742 
Sustracción 743 
Multiplicación 743 
División 744 
Exponer 746 
Funciones especiales 746 
Logaritmos 747 
Operaciones in situ 747 
Funciones trigonométricas 748 
Módulo 748 
Capítulo 150: Optimizacióndelrendimiento 750 
Observaciones 750 
Examples 750 
Código de perfil 750 
Capítulo 151:os.path 753
    50/1068
    Introducción 753
Sintaxis 753 
Examples 753 
Unir caminos 753 
Camino Absoluto desde el Camino Relativo 753 
Manipulación de componentes del camino 754 
Obtener el directorio padre 754
Si el camino dado existe. 754 
compruebe si la ruta dada es un directorio, archivo, enlace simbólico, punto de montaje, e 754
Capítulo152:Pandas Transform:Preforma operaciones engrupos yconcatenalos resultados. 
756
Examples 756 
Transformada simple 756 
Primero, vamos a crear un marco de datos ficticio 756 
Ahora, usaremos la función de transform pandas para contar el número de pedidos por client 756 
Múltiples resultados por grupo 757 
Usando funciones de transform que devuelvensub-cálculos por grupo. 757 
Capítulo153:Patronesdediseño 759 
Introducción 759 
Examples 759 
Patrón de estrategia 759 
Introducción a los patrones de diseño y patrón Singleton. 760 
Apoderado 762 
Capítulo154:Perfilado 765 
Examples 765
%% timeit y% timeit en IPython 765
función timeit () 765 
línea de comandos de timeit 765 
line_profiler en linea de comando 766 
Usando cProfile (Perfilador preferido) 766 
Capítulo 155:Persistencia Python 768
Sintaxis 768
    51/1068
    Parámetros 768
Examples 768 
Persistencia Python 768 
Función de utilidad para guardar y cargar. 769 
Capítulo 156:pip:PyPIPackage Manager 770 
Introducción 770 
Sintaxis 770 
Observaciones 770 
Examples 771 
Instalar paquetes 771 
Instalar desde archivos de requisitos 771 
Desinstalar paquetes 771 
Para listar todos los paquetes instalados usando `pip` 772 
Paquetes de actualización 772 
Actualizando todos los paquetes desactualizados en Linux 772 
Actualizando todos los paquetes desactualizados en Windows 773 
Cree un archivo Requirements.txt de todos los paquetes en el sistema 773 
Cree un archivo Requirements.txt de paquetes solo en el virtualenv actual 773 
Usando una determinada versión de Python con pip 773 
Instalación de paquetes aún no en pip como ruedas 774 
Nota sobre la instalación de versiones preliminares 776 
Nota sobre la instalación de versiones de desarrollo 776 
Capítulo157:Plantillasenpython 779 
Examples 779 
Programa de salida de datos simple usando plantilla 779 
Cambiando delimitador 779 
Capítulo 158: Polimorfismo 780 
Examples 780 
Polimorfismo basico 780 
Escribiendo pato 782 
Capítulo159:PostgreSQL 784 
Examples 784
    52/1068
    Empezando 784
Instalación utilizando pip 784 
Uso básico 784 
Capítulo160:Precedenciadeloperador 786 
Introducción 786 
Observaciones 786 
Examples 787 
Ejemplos simples de precedencia de operadores en python. 787 
Capítulo161:Procesosehilos 788 
Introducción 788 
Examples 788 
Bloqueo de intérprete global 788 
Corriendo en múltiples hilos 790 
Ejecutando en múltiples procesos 790 
Compartir el estado entre hilos 791 
Estado de intercambio entre procesos 791 
Capítulo 162: Programación Funcionalen Python 793 
Introducción 793 
Examples 793 
Función lambda 793 
Función de mapa 793 
Función de reducción 793 
Función de filtro 793 
Capítulo163:ProgramaciónIoTconPythonyRaspberryPI 795 
Examples 795 
Ejemplo - sensor de temperatura 795 
Capítulo164:py.test 798 
Examples 798 
Configurando py.test 798
El código a probar 798 
El código de prueba 798 
Corriendo la prueba 798
    53/1068
    Pruebas de falla 799
Introducción a los accesorios de prueba 799 
Py.test accesorios para el rescate! 800 
Limpieza después de las pruebas. 802 
Capítulo165:pyaudio 804 
Introducción 804 
Observaciones 804 
Examples 804 
Modo de devolución de llamada de audio I / O 804 
Modo de bloqueo de E / S de audio 805 
Capítulo 166:pygame 807 
Introducción 807 
Sintaxis 807 
Parámetros 807 
Examples 807 
Instalando pygame 807 
Modulo mezclador de pygame 808 
Inicializando 808 
Posibles acciones 808 
Los canales 808 
Capítulo 167: Pyglet 810 
Introducción 810 
Examples 810 
Hola Mundo en Pyglet 810 
Instalación de Pyglet 810 
Reproducción de sonido en Pyglet 810 
Usando Pyglet para OpenGL 810 
Dibujar puntos usando Pyglet y OpenGL 811 
Capítulo 168: PyInstaller - Distribuir código dePython 812 
Sintaxis 812 
Observaciones 812 
Examples 812
Instalación y configuración 812
    54/1068
    Usando Pyinstaller 813 
Agrupar en una carpeta 813 
Ventajas: 813 
Desventajas 814
Agrupar en un solo archivo 814 
Capítulo169:PythonLex-Yacc 815 
Introducción 815 
Observaciones 815 
Examples 815 
Empezando con PLY 815
El "¡Hola mundo!" de PLY - Una calculadora simple 815 
Parte 1: Tokenizing entrada con Lex 817 
Descompostura 818 
h22 819
h23 819
h24 820
h25 820
h26 820
h27 820
h28 820
h29 821
h210 821
h211 821
Parte 2: Análisis de entrada Tokenized con Yacc 821 
Descompostura 822 
h212 824
Capítulo170:PythonRequestsPost 825 
Introducción 825 
Examples 825 
Post simple 825
    55/1068
    Formulario de datos codificados 826
Subir archivo 827 
Respuestas 827 
Autenticación 828 
Proxies 829 
Capítulo 171:PythonyExcel 830
Examples 830
Ponga los datos de la lista en un archivo de Excel. 830 
OpenPyXL 830 
Crear gráficos de Excel con xlsxwriter 831 
Lee los datos de excel usando el módulo xlrd 833 
Formato de archivos de Excel con xlsxwriter 834
Capítulo172:Recoleccióndebasura 836
Observaciones 836 
Recolección de basura generacional 836 
Examples 838 
Recuento de referencias 838 
Recolector de basura para ciclos de referencia 839 
Efectos del comando del 840 
Reutilización de objetos primitivos. 841 
Viendo el refcount de un objeto 841 
Forzar la desasignación de objetos. 841 
Gestionando la recogida de basura. 842 
No espere a que la recolección de basura se limpie 843
Capítulo 173: Reconocimiento óptico de caracteres 845
Introducción 845 
Examples 845 
PyTesseract 845 
PyOCR 845
Capítulo174:Recursion 847 
Observaciones 847 
Examples 847 
Suma de números del 1 al n 847
    56/1068
    El qué, cómo y cuándo de la recursión 847
Exploración de árboles con recursión 851 
Incrementando la profundidad máxima de recursión 852 
Recursión de cola - Mala práctica 853
Optimización de la recursión de cola a través de la introspección de la pila 853 
Capítulo 175: RedesPython 855
Observaciones 855 
Examples 855
El ejemplo más simple de cliente / servidor de socket de Python. 855 
Creando un servidor HTTP simple 855 
Creando un servidor TCP 856 
Creando un Servidor UDP 857 
Inicie Simple HttpServer en un hilo y abra el navegador 857 
Capítulo176:Reducir 859 
Sintaxis 859 
Parámetros 859 
Observaciones 859 
Examples 859 
Visión general 859 
Utilizando reducir 860
Producto acumulativo 861 
Variante sin cortocircuito de alguno / todos. 861 
Primer elemento verdadero / falso de una secuencia (o último elemento si no hay ninguno) 861
Capítulo 177: Representaciones de cadena de instancias de clase: métodos str y repr_ 
862
Observaciones 862 
Una nota sobre la implementación de ambos métodos. 862
Notas 862
Examples 863 
Motivación 863
El problema 864
La Solución(Parte 1) 864
    57/1068
    La Solución(Parte 2) 865 
Sobre esas funciones duplicadas 867 
Resumen 867 
Ambos métodos implementados, eval-round-trip style repr () 868 
Capítulo 178: Sangría 869 
Examples 869 
Errores de sangría 869 
Ejemplo simple 869
¿Espacios o pestañas? 870 
Cómo se analiza la sangría 870 
Capítulo 179: Seguridad y criptografía 872 
Introducción 872 
Sintaxis 872 
Observaciones 872 
Examples 872 
Cálculo de un resumen del mensaje 872 
Algoritmos de hash disponibles 873 
Contraseña segura Hashing 873 
Hash de archivo 874 
Cifrado simétrico utilizando pycrypto 874 
Generando firmas RSA usando pycrypto 875 
Cifrado RSA asimétrico utilizando pycrypto 876 
Capítulo180:Serializacióndedatos 878 
Sintaxis 878 
Parámetros 878 
Observaciones 878 
Examples 879 
Serialización utilizando JSON 879 
Serialización utilizando Pickle 879 
Capítulo181:Serializacióndedatosdesalmuera 881 
Sintaxis 881 
Parámetros 881
    58/1068
    Observaciones 881
Tipos pickleable 881 
pickleyseguridad 881 
Examples 882 
Usando Pickle para serializar y deserializar un objeto 882 
Para serializarelobjeto. 882 
Deserializarelobjeto. 882 
Usandoobjetosdepickle ybyte 882 
Personalizar datos en escabeche 883 
Capítulo 182:ServidorHTTPdePython 885 
Examples 885 
Ejecutando un servidor HTTP simple 885 
Archivos de servicio 885
API programática de SimpleHTTPServer 887 
Manejo básico de GET, POST, PUT usando BaseHTTPRequestHandler 888 
Capítulo183:setup.py 890 
Parámetros 890 
Observaciones 890 
Examples 890 
Propósito de setup.py 890 
Agregando scripts de línea de comandos a su paquete de Python 891 
Usando metadatos de control de fuente en setup.py 892 
Añadiendo opciones de instalación 892 
Capítulo 184:Similitudes enlasintaxis,diferencias enelsignificado:Pythonvs.JavaSc 894 
Introducción 894 
Examples 894
`in` con listas 894
Capítulo185:Sobrecarga 895 
Examples 895 
Métodos de magia / Dunder 895 
Contenedor y tipos de secuencia. 896 
Tipos callables 897
    59/1068
    Manejando conductas no implementadas. 897
Sobrecarga del operador 898 
Capítulo186:Socketsycifrado/descifradodemensajesentreelclienteyelservidor 901 
Introducción 901 
Observaciones 901 
Examples 904 
Implementación del lado del servidor 904 
Implementación del lado del cliente 906 
Capítulo187:SubcomandosCLIconsalida deayudaprecisa 909 
Introducción 909 
Observaciones 909 
Examples 909 
Forma nativa (sin bibliotecas) 909 
argparse (formateador de ayuda predeterminado) 910 
argparse (formateador de ayuda personalizado) 911 
Capítulo 188: sys 913 
Introducción 913 
Sintaxis 913 
Observaciones 913 
Examples 913 
Argumentos de línea de comando 913 
Nombre del script 913 
Flujo de error estándar 914 
Finalización prematura del proceso y devolución de un código de salida. 914 
Capítulo 189:tempfile NamedTemporaryFile 915 
Parámetros 915 
Examples 915 
Cree (y escriba en) un archivo temporal persistente conocido 915 
Capítulo190:Tipodesugerencias 917 
Sintaxis 917 
Observaciones 917 
Examples 917
    60/1068
    Tipos genéricos 917 
Añadiendo tipos a una función 917 
Miembros de la clase y métodos 919 
Variables y atributos 919 
NamedTuple 920 
Escriba sugerencias para argumentos de palabras clave 920 
Capítulo 191:TiposdedatosdePython 921 
Introducción 921 
Examples 921 
Tipo de datos numeros 921 
Tipo de datos de cadena 921 
Tipo de datos de lista 921 
Tipo de datos de la tupla 921 
Tipo de datos del diccionario 922 
Establecer tipos de datos 922 
Capítulo 192: Tipos de datos inmutables (int, float, str, tuple y frozensets) 923 
Examples 923 
Los caracteres individuales de las cadenas no son asignables 923
Los miembros individuales de Tuple no son asignables 923 
Los Frozenset son inmutables y no asignables. 923 
Capítulo193:tkinter 924 
Introducción 924 
Observaciones 924 
Examples 924 
Una aplicación tkinter mínima 924 
Gerentes de geometría 925 
Lugar 925 
Paquete 926 
Cuadrícula 926 
Capítulo 194: Trabajando alrededor del bloqueo global de intérpretes (GIL) 928 
Observaciones 928
¿Por qué hay un GIL? 928
    61/1068
    Detallessobre cómofuncionaelGIL: 928
Beneficiosde la GIL 929 
Consecuencias de laGIL 929 
Referencias: 929 
Examples 930 
Multiprocesamiento.Pool 930 
CódigodeDavidBeazleyquemostrabaproblemasdesubprocesosde GIL 930
Cython Nogil: 931 
CódigodeDavidBeazleyquemostrabaproblemasdesubprocesosde GIL 931 
Reescrito usando nogil(SOLOFUNCIONAEN CYTHON): 931 
Capítulo195:TrabajandoconarchivosZIP 933 
Sintaxis 933 
Observaciones 933 
Examples 933 
Apertura de archivos zip 933 
Examinando los contenidos de Zipfile 933 
Extraer el contenido del archivo zip a un directorio. 934 
Creando nuevos archivos 934 
Capítulo 196: Trazado con matplotlib 936 
Introducción 936 
Examples 936 
Una parcela simple en Matplotlib 936 
Agregar más características a un gráfico simple: etiquetas de eje, título, marcas de eje, 937 
Haciendo múltiples parcelas en la misma figura por superposición similar a MATLAB 938 
Realización de varios gráficos en la misma figura utilizando la superposición de gráficos 939 
Gráficos con eje X común pero eje Y diferente: usando twinx () 940 
Gráficos con eje Y común y eje X diferente usando twiny () 942 
Capítulo 197:Tupla 945 
Introducción 945 
Sintaxis 945 
Observaciones 945 
Examples 945
    62/1068
    Tuplas de indexación 945
Las tuplas son inmutables 946 
Tuple son elementos sabios hashable y equiparables 946 
Tupla 947 
Embalaje y desembalaje de tuplas 948 
Elementos de inversión 949 
Funciones de tupla incorporadas 949 
Comparación 949
Longitudde latupla 950
Max deuna tupla 950 
Min deuna tupla 950 
Convertirunalistaentupla 950 
Concatenación de tuplas 950 
Capítulo198:Unicode 952 
Examples 952 
Codificación y decodificación. 952 
Capítulo 199: Unicodeybytes 953 
Sintaxis 953 
Parámetros 953 
Examples 953 
Lo esencial 953 
Unicode a bytes 953 
Bytes a Unicode 954 
Codificación / decodificación de manejo de errores. 955 
Codificación 955 
Descodificación 955 
Moral 955 
Archivo I / O 955 
Capítulo200:urllib 957 
Examples 957 
HTTP GET 957
    63/1068
    Python 2 957 
Python 3 957 
POST HTTP 958
Python 2 ................ 958 
Python 3 .................. 958 
Decodificar bytes recibidos de acuerdo a la codificación del tipo de contenido 958 
Capítulo 201: Usando bucles dentro de funciones 960 
Introducción ................ 960 
Examples .................... 960 
Declaración de retorno dentro del bucle en una función 960 
Capítulo202:Usodelmódulo"pip":PyPIPackageManager 961 
Introducción ................ 961 
Sintaxis ....................... 961 
Examples .................... 962 
Ejemplo de uso de comandos 962 
Manejo de la excepción de ImportError 962 
Fuerza de instalación ...... 963 
Capítulo203:VelocidaddePythondelprograma. 964 
Examples .................... 964 
Notación ......................... 964 
Lista de operaciones ....... 964 
Operaciones de deque .... 965 
Establecer operaciones .. 966 
Notaciones algorítmicas... 966
Capítulo 204: Visualización de datos con Python 968 
Examples 968 
Matplotlib 968 
Seaborn 969 
MayaVI 972 
Plotly 973 
Capítulo205:WebraspadoconPython 976 
Introducción 976
    64/1068
    Observaciones 976
Paquetes de Python útiles para raspado web (orden alfabético) 976 
Realización de solicitudes y recogida de datos. 976 
requests 976 
requests-cache 976 
scrapy 976 
selenium 976 
Análisis de HTML 976 
BeautifulSoup 977 lxml
977 
Examples 977 
Ejemplo básico de uso de solicitudes y lxml para raspar algunos datos 977 
Mantenimiento de sesión web-scraping con peticiones. 977 
Raspado utilizando el marco de Scrapy 978 
Modificar agente de usuario de Scrapy 978 
Raspado utilizando BeautifulSoup4 979 
Raspado utilizando Selenium WebDriver 979 
Descarga de contenido web simple con urllib.request 979 
Raspado con rizo 980 
Capítulo206:Websockets 981 
Examples 981 
Eco simple con aiohttp 981 
Clase de envoltura con aiohttp 981 
Usando Autobahn como una Websocket Factory 982 
Creditos 985
    65/1068
    1
Acerca de
Puedes compartir este PDF con cualquier persona que creas que podría beneficiarse.
Es un libro electrónico no oficial y gratuito sobre PYTHON creado con fines educativos. 
Todo el contenido se extrae de la documentación de Stack Overflow, escrita por muchas personas 
trabajadoras en Stack Overflow. No está afiliado a Stack Overflow ni al lenguaje oficial de Python.
El contenido se publica bajo Creative Commons BY-SA, y la lista de contribuyentes a cada capítulo se 
proporciona en la sección de créditos al final de este libro. Las imágenes pueden ser propiedad de sus 
respectivos dueños a menos que se especifique lo contrario. Todas las marcas comerciales y marcas 
registradas son propiedad de sus respectivos dueños.
Usa el contenido presentado en este libro bajo tu propio riesgo; no se garantiza que sea
correcto ni exacto.
    66/1068
    2
if something: 
x = 1
else:
x = 'this is a string' 
print(x)
1 + '1' # raises an error
1 + int('1') # results with 2
Capítulo 1: Empezando con Python Language
Observaciones
Python es un lenguaje de programación muy utilizado. Es:
• Alto nivel : Python automatiza las operaciones de bajo nivel, como la administración de 
memoria. Deja al programador con un poco menos de control, pero tiene muchos beneficios 
que incluyen la legibilidad del código y expresiones de código mínimas.
• Propósito general : Python está diseñado para ser utilizado en todos los contextos y 
entornos. Un ejemplo de un lenguaje de uso no general es PHP: está diseñado 
específicamente como un lenguaje de script de desarrollo web del lado del servidor. En 
contraste, Python puede usarse para el desarrollo web del lado del servidor, pero también 
para crear aplicaciones de escritorio.
• Escrito dinámicamente : cada variable en Python puede hacer referencia a cualquier tipo 
de datos. Una sola expresión puede evaluar datos de diferentes tipos en diferentes 
momentos. Debido a eso, el siguiente código es posible:
• Se escribe con fuerza : durante la ejecución del programa, no se le permite hacer nada 
que sea incompatible con el tipo de datos con los que está trabajando. Por ejemplo, no hay 
conversiones ocultas de cadenas a números; una cadena hecha de dígitos nunca se tratará 
como un número a menos que la conviertas explícitamente:
• Amigable para principiantes :) : la sintaxis y la estructura de Python son muy intuitivas. Es 
de alto nivel y proporciona construcciones destinadas a permitir la escritura de programas 
claros tanto a pequeña como a gran escala. Python es compatible con múltiples paradigmas 
de programación, incluidos la programación orientada a objetos, la imperativa y funcional o 
los estilos de procedimiento. Tiene una biblioteca estándar grande y completa y muchas 
bibliotecas de terceros fáciles de instalar.
Sus principios de diseño se describen en el Zen de Python .
Actualmente, hay dos ramas principales de lanzamiento de Python que tienen algunas diferencias
    67/1068
    3
significativas. Python 2.x es la versión heredada, aunque sigue teniendo un uso generalizado. 
Python 3.x realiza un conjunto de cambios incompatibles con versiones anteriores que tienen 
como objetivo reducir la duplicación de características. Para obtener ayuda para decidir qué 
versión es la mejor para usted, consulte este artículo .
La documentación oficial de Python también es un recurso completo y útil, que contiene 
documentación para todas las versiones de Python, así como tutoriales para ayudarlo a 
comenzar.
Existe una implementación oficial del lenguaje suministrado por Python.org, generalmente 
denominado CPython, y varias implementaciones alternativas del lenguaje en otras plataformas 
de tiempo de ejecución. Estos incluyen IronPython (que ejecuta Python en la plataforma .NET), 
Jython (en el tiempo de ejecución de Java) y PyPy (que implementa Python en un subconjunto de 
sí mismo).
Versiones 
Python 3.x
Versión Fecha de lanzamiento
[3.7] 2017-05-08
3.6 2016-12-23
3.5 2015-09-13
3.4 2014-03-17
3.3 2012-09-29
3.2 2011-02-20
3.1 2009-06-26
3.0 2008-12-03
Python 2.x
Versión Fecha de lanzamiento
2.7 2010-07-03
2.6 2008-10-02
2.5 2006-09-19
    68/1068
    4
$ python --version
Versión Fecha de lanzamiento
2.4 2004-11-30
2.3 2003-07-29
2.2 2001-12-21
2.1 2001-04-15
2.0 2000-10-16
Examples
Empezando
Python es un lenguaje de programación de alto nivel ampliamente utilizado para la programación 
de propósito general, creado por Guido van Rossum y lanzado por primera vez en 1991. Python 
cuenta con un sistema de tipo dinámico y gestión automática de memoria y soporta múltiples 
paradigmas de programación, incluyendo imperativo, orientado a objetos. Programación 
funcional, y estilos procesales. Tiene una biblioteca estándar grande y completa.
Dos versiones principales de Python están actualmente en uso activo:
• Python 3.x es la versión actual y está en desarrollo activo.
• Python 2.x es la versión heredada y solo recibirá actualizaciones de seguridad hasta 2020. 
No se implementarán nuevas funciones. Tenga en cuenta que muchos proyectos siguen 
utilizando Python 2, aunque la migración a Python 3 es cada vez más sencilla.
Puede descargar e instalar cualquiera de las versiones de Python aquí . Ver Python 3 contra
Python 2 para una comparación entre ellos. Además, algunos terceros ofrecen versiones 
reenvasadas de Python que agregan bibliotecas de uso común y otras características para 
facilitar la configuración de casos de uso comunes, como matemáticas, análisis de datos o uso 
científico. Vea la lista en el sitio oficial .
Verificar si Python está instalado
Para confirmar que Python se instaló correctamente, puede verificarlo ejecutando el siguiente 
comando en su terminal favorita (si está usando el sistema operativo Windows, debe agregar la 
ruta de acceso de python a la variable de entorno antes de usarlo en el símbolo del sistema):
Python 3.x 3.0
Si tiene Python 3 instalado y es su versión predeterminada (consulte la sección Solución de
problemas para obtener más detalles), debería ver algo como esto:
    69/1068
    5
$ python --version 
Python 2.7.13
>>>
>>> print("Hello, World")
>>> print("Hello, World") 
Hello, World
Python 2.x 2.7
Si tiene instalado Python 2 y es su versión predeterminada (consulte la sección Solución de
problemas para obtener más detalles), debería ver algo como esto:
Si ha instalado Python 3, pero $ python --version genera una versión de Python 2, también tiene 
Python 2instalado.Este esa menudo el caso de MacOSy muchas distribuciones de Linux. Use $ 
python3 en $ python3 lugar para usar explícitamente el intérprete de Python 3.
Hola, Mundo en Python usando IDLE
IDLE es un editor simple para Python, que viene incluido con Python.
Cómo crear el programa Hello, World en IDLE.
• Abra IDLE en su sistema de elección.
○ En versiones anteriores de Windows, se puede encontrar en All Programs en el menú 
de Windows.
○ En Windows 8+, busque IDLE o encuéntrelo en las aplicaciones que están presentes 
en su sistema.
○ EnsistemasbasadosenUnix (incluyendo Mac),puedeabrirlo desdeel shell 
escribiendo $ idle python_file.py .
• Se abrirá una concha con opciones a lo largo de la parte superior.
En la cáscara, hay un indicador de tres corchetes de ángulo recto:
Ahora escriba el siguiente código en el indicador:
Presiona Enter .
Hola archivo de World Python
Crea un nuevo archivo hello.py que contenga la siguiente línea:
$ python --version 
Python 3.6.0
    70/1068
    6
print('Hello, World')
from future import print_function
print 'Hello, World'
$ python
Python 2.7.12 (default, Jun 28 2016, 08:46:01)
[GCC 6.1.1 20160602] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'Hello, World' 
Hello, World
>>>
Python 3.x 3.0
Python 2.x 2.6
Puede usar la función de print Python 3 en Python 2 con la siguiente declaración de import :
Python 2 tiene una serie de funcionalidades que pueden importarse opcionalmente desde Python 
3 usando el módulo future , como se explica aquí .
Python 2.x 2.7
Si usa Python 2, también puede escribir la siguiente línea. Tenga en cuenta que esto no es válido 
en Python 3 y, por lo tanto, no se recomienda porque reduce la compatibilidad de código entre 
versiones.
En suterminal,navegue al directorio quecontieneel archivohello.py. 
Escriba python hello.py , luego python hello.py la tecla Intro .
Deberías ver Hello, World impreso en la consola.
Tambiénpuede sustituir hello.py conla ruta a suarchivo.Por ejemplo, sitiene el archivoensu 
directorio de inicio y su usuario es "usuario" en Linux, puede escribir python /home/user/hello.py .
Ejecutar un shell interactivo de Python
Al ejecutar (ejecutar) el comando python en su terminal, se le presenta un shell interactivo de 
Python.Esto también se conoce como el intérprete de Python o REPL (para 'LeerEvaluar 
Imprimir Loop').
Si desea ejecutar Python 3 desde su terminal, ejecute el comando python3 .
$ python hello.py 
Hello, World
    71/1068
    7
>>> exit()
>>> quit()
Alternativamente,inicielasolicitudinteractivaycargueelarchivoconpython -i <file.py> . 
En la línea de comando,ejecute:
Hay varias formas de cerrar el shell de Python:
o
Alternativamente, CTRL + D cerrará el shell y lo pondrá nuevamente en la línea de comando de su 
terminal.
Si desea cancelar un comando que está escribiendo y volver a un indicador de comandos limpio, 
mientras permanece dentro del intérprete de intérprete, use CTRL + C.
Pruebe un shell interactivo de Python en línea .
Otras conchas en línea
Varios sitios web proporcionan acceso en línea a las conchas de Python. 
Los depósitos en línea pueden ser útiles para los siguientes propósitos:
• Ejecute un pequeño fragmento de código desde una máquina que carece de la instalación 
de Python (teléfonos inteligentes, tabletas, etc.).
• Aprende o enseña Python básico.
• Resolver problemas de jueces en línea.
Ejemplos:
Descargo de responsabilidad: los autores de la documentación no están afiliados a los 
recursos que se enumeran a continuación.
• https://www.python.org/shell/ - El shell de Python en línea alojado en el sitio web oficial de
$ python -i hello.py 
"Hello World"
>>>
$ python3
Python 3.6.0 (default, Jan 13 2017, 00:00:00)
[GCC 6.1.1 20160602] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print('Hello, World') 
Hello, World
>>>
    72/1068
    8
$ python -c 'print("Hello, World")' 
Hello, World
Python.
• https://ideone.com/ : se utiliza ampliamente en la red para ilustrar el comportamiento del 
fragmento de código.
• https://repl.it/languages/python3 - Compilador en línea, IDE e intérprete en línea potente y 
simple. Codifique, compile y ejecute el código en Python.
• https://www.tutorialspoint.com/execute_python_online.php : shell UNIX con todas las 
funciones y un explorador de proyectos fácil de usar.
• http://rextester.com/l/python3_online_compiler - IDE simple y fácil de usar que muestra el 
tiempo de ejecución
Ejecutar comandos como una cadena
Python puede pasar un código arbitrario como una cadena en el shell:
Esto puede ser útil cuando se concatenan los resultados de los scripts juntos en el shell.
Conchas y mas alla
Administración depaquetes:la herramienta recomendadaporPyPAparainstalarpaquetesde 
Python es PIP . Para instalar, en su línea de comando ejecute pip install <the package name> . 
Por ejemplo, pip install numpy .(Nota: en Windows debe agregar pip asus variables de entorno 
PATH. Para evitar esto, use python -m pip install <the package name> )
Shells : hasta ahora, hemos discutido diferentes formas de ejecutar código usando el shell 
interactivo nativo de Python. Los shells utilizan el poder interpretativo de Python para 
experimentar con el código en tiempo real. Los shells alternativos incluyen IDLE , una GUI preempaquetada, IPython , conocida por extender la experiencia interactiva, etc.
Programas : para el almacenamiento a largo plazo, puede guardar el contenido en archivos .py y 
editarlos / ejecutarlos como secuencias de comandos o programas con herramientas externas, 
como shell, IDE (como PyCharm ), cuadernos Jupyter , etc. Los usuarios intermedios pueden usar 
estas herramientas; sin embargo, los métodos discutidos aquí son suficientes para comenzar.
El tutor de Python te permite recorrer el código de Python para que puedas visualizar cómo fluirá 
el programa, y te ayuda a entender dónde salió mal tu programa.
PEP8 define las pautas para formatear el código Python. Formatear bien el código es importante 
para que pueda leer rápidamente lo que hace el código.
Creando variables y asignando valores.
Para crear una variable en Python, todo lo que necesita hacer es especificar el nombre de la
    73/1068
    9
<variable name> = <value>
# Integer 
a = 2 
print(a)
# Output: 2
# Integer
b = 9223372036854775807
print(b)
# Output: 9223372036854775807
# Floating point 
pi = 3.14
print(pi)
# Output: 3.14
# String 
c = 'A'
print(c) 
#Output: A
# String
name = 'John Doe' 
print(name)
# Output: John Doe
# Boolean 
q = True 
print(q)
# Output: True
# Empty value or null data type 
x = None
print(x)
# Output: None
0 = x
=> Output: SyntaxError: can't assign to literal
import keyword 
print(keyword.kwlist)
variable y luego asignarle un valor.
Python usa = para asignar valores a las variables. No es necesario declarar una variable por 
adelantado (o asignarle un tipo de datos), al asignar un valor a una variable, se declara e inicializa 
la variable con ese valor. No hay forma de declarar una variable sin asignarle un valor inicial.
La asignación de variables funciona de izquierda a derecha. Así que lo siguiente te dará un error 
de sintaxis.
No puede utilizar palabras clave de python como un nombre de variable válido. Puedes ver la lista 
de palabras clave por:
    74/1068
    10
x = True # valid
_y = True # valid
9x = False # starts with numeral
=> SyntaxError: invalid syntax
$y = False # starts with symbol
=> SyntaxError: invalid syntax
has_0_in_it = "Still Valid"
x = 9
y = X*5
=>NameError: name 'X' is not defined
a = 2 
print(type(a))
# Output: <type 'int'>
b = 9223372036854775807
print(type(b))
# Output: <type 'int'>
pi = 3.14
print(type(pi))
# Output: <type 'float'>
c = 'A'
print(type(c))
# Output: <type 'str'>
name = 'John Doe' 
print(type(name))
# Output: <type 'str'>
q = True 
print(type(q))
# Output: <type 'bool'>
x = None 
print(type(x))
# Output: <type 'NoneType'>
Reglas para nombrar variables:
1. Los nombres de las variables deben comenzar con una letra o un guión bajo.
2. El resto de su nombre de variable puede consistir en letras, números y guiones bajos.
3. Los nombres son mayúsculas y minúsculas.
Aunque no es necesario especificar un tipo de datos al declarar una variable en Python, mientras 
se asigna el área necesaria en la memoria para la variable, el intérprete de Python selecciona 
automáticamente el tipo incorporado más adecuado para ella:
    75/1068
    11
a_name = an_object # "a_name" is now a name for the reference to the object "an_object"
a, b, c = 1, 2, 3
print(a, b, c) 
# Output: 1 2 3
a, b, c = 1, 2
=> Traceback (most recent call last):
=> File "name.py", line N, in<module>
=> a, b, c = 1, 2
=> ValueError: need more than 2 values to unpack
a, b = 1, 2, 3
=> Traceback (most recent call last):
=> File "name.py", line N, in<module>
=> a, b = 1, 2, 3
=> ValueError: too many values to unpack
a, b, _ = 1, 2, 3
print(a, b)
# Output: 1, 2
a, b, _ = 1,2,3,4
=>Traceback (most recent calllast):
=>File "name.py", line N, in <module>
=>a, b, _ = 1,2,3,4
=>ValueError: too many values to unpack (expected 3)
Ahora que conoce los conceptos básicos de la asignación, dejemos de lado esta sutileza acerca 
de la asignación en python.
Cuando usa = para realizar una operación de asignación, lo que está a la izquierda de = es un 
nombre para el objeto a la derecha. Finalmente, lo que hace = es asignar la referencia del 
objeto a la derecha al nombre a la izquierda.
Es decir:
Entonces, de los muchos ejemplos de asignación anteriores, si seleccionamos pi = 3.14 , pi es 
un nombre (no el nombre, ya que un objeto puede tener varios nombres) para el objeto 3.14 . Si 
noentiende algo a continuación, vuelva a estepunto y lea esto nuevamente.Además, puedes 
echarle un vistazo a esto para una mejor comprensión.
Puede asignar múltiples valores a múltiples variables en una línea. Tenga en cuenta que debe 
haber el mismo número de argumentos en los lados derecho e izquierdo del operador = :
El error en el último ejemplo puede obviarse asignando valores restantes a un número igual de 
variables arbitrarias. Esta variable ficticia puede tener cualquier nombre, pero es convencional 
usar el subrayado ( _ ) para asignar valores no deseados:
Tenga en cuenta que el número de _ y el número de valores restantes deben ser iguales. De lo 
contrario, se lanzan 'demasiados valores para descomprimir el error' como se indica arriba:
    76/1068
    12
a = b = c = 1 
print(a, b, c) 
# Output: 1 1 1
x = y = [7, 8, 9] # x and y refer to the same list object just created, [7, 8, 9] 
x = [13, 8, 9] # x now refers to a different list object just created, [13, 8, 9] 
print(y) # y still refers to the list it was first assigned
# Output: [7, 8, 9]
x = [1, 2, [3, 4, 5], 6, 7] # this is nested list 
print x[2]
# Output: [3, 4, 5]
print x[2][1] 
# Output: 4
También puede asignar un solo valor a varias variables simultáneamente.
Cuando se utiliza dicha asignación en cascada, es importante tener en cuenta que las tres 
variables a , b y c se refieren al mismo objeto en la memoria, un int objeto con el valor de 1. En 
otras palabras, a , b y c son tres nombres diferentes dado al mismo objeto int.Asignar un objeto 
diferente a uno de ellos después no cambia los otros, como se esperaba:
a = b = c = 1 
print(a, b, c) 
# Output: 1 1 1
b = 2
print(a, b, c) 
# Output: 1 2 1
# all three names a, b and c refer to same int object with value 1
# b now refers to another int object, one with a value of 2 
# so output is as expected.
Loanteriortambiénesválidoparalostiposmutables(comolist ,dict,etc.),aligualqueparalos 
tipos inmutables (como int , string , tuple , etc.):
Hasta ahora tan bueno. Las cosas son un poco diferentes cuando se trata de modificar el objeto 
(en contraste con asignar el nombre a un objeto diferente, como hicimos anteriormente) cuando la 
asignación en cascada se usa para tipos mutables. Echa un vistazo a continuación, y lo verás de 
primera mano:
x = y = [7, 8, 9]
[7, 8, 9]
x[0] = 13
names, x in this case 
print(y)
# Output: [13, 8, 9]
# x and y are two different names for the same list object just created, 
# we are updating the value of the list [7, 8, 9] through one of its
# printing the value of the list using its other name 
# hence, naturally the change is reflected
Las listas anidadas también son válidas en python. Esto significa que una lista puede contener 
otra lista como un elemento.
Por último, las variables en Python no tienen que ser del mismo tipo de las que se definieron por 
primera vez; simplemente puede usar = para asignar un nuevo valor a una variable, incluso si ese 
valor es de un tipo diferente.
    77/1068
    13
name = raw_input("What is your name? ") 
# Out: What is your name? _
name = input("What is your name? ") 
# Out: What is your name? _
name = input("What is your name? ") 
# Out: What is your name?
name = input("What is your name? ") 
# Out: What is your name? Bob 
print(name)
# Out: Bob
Si esto te molesta, piensa en el hecho de que lo que está a la izquierda de = es solo un nombre 
para un objeto. En primer lugar se llama a la int objeto con valor de 2 a , a continuación, cambia 
de opinión y decide dar el nombre a a una string objeto, que tiene un valor 'Valor nuevo'. Simple,
¿verdad?
Entrada del usuario
Entrada interactiva
Para obtener información del usuario, use la función de input ( nota : en Python 2.x, la función se 
llama raw_input en raw_input lugar, aunque Python 2.x tiene su propia versión de input que es 
completamente diferente):
Python 2.x 2.3
Observación de seguridad No use input() en Python2: el texto ingresado se 
evaluará como si fuera una expresión de Python (equivalente a eval(input()) en 
Python3), que podría convertirse fácilmente en una vulnerabilidad. Consulte este
artículo para obtener más información sobre los riesgos de usar esta función.
Python 3.x 3.0
El resto de este ejemplo utilizará la sintaxis de Python 3.
La función toma un argumento de cadena, que lo muestra como una solicitud y devuelve una 
cadena. El código anterior proporciona un aviso, esperando que el usuario ingrese.
Si el usuario escribe "Bob" y pulsa enter, el name la variable se asignará a la cadena "Bob" :
a = 2 
print(a)
# Output: 2
a = "New value" 
print(a)
# Output: New value
    78/1068
    14
x = input("Write a number:") 
# Out: Write a number: 10
x / 2
#Out: TypeError: unsupported operand type(s)for/: 'str' and 'int' 
float(x) / 2
# Out: 5.0
Tengaen cuenta quela input siempre es de tipo str ,loque esimportantesi desea queel usuario 
ingresenúmeros.Porlotanto,necesitaconvertirelstrantesdeintentarusarlocomounnúmero:
NB:serecomiendautilizarlosbloquesdetry/exceptparadetectarexcepcionescuandosetrata
de entradas de usuario .Por ejemplo, si su código quiere convertir un raw_inputen un int , y lo 
que el usuario escribe es inasible, genera un ValueError .
IDLE - GUI de Python
IDLE es un entorno integrado de desarrollo y aprendizaje de Python y es una alternativa a la línea 
de comandos. Como su nombre puede implicar, IDLE es muy útil para desarrollar un nuevo 
código o aprender Python. En Windows, esto viene con el intérprete de Python, pero en otros 
sistemas operativos puede que necesite instalarlo a través de su administrador de paquetes.
Los principales propósitos de IDLE son:
• Editor de texto de múltiples ventanas con resaltado de sintaxis, autocompletado y sangría 
inteligente
• Python shell con resaltado de sintaxis
• Depurador integrado con pasos, puntos de interrupción persistentes y visibilidad de la pila 
de llamadas
• Sangría automática (útil para los principiantes que aprenden sobre la sangría de Python)
• Guardando el programa Python como archivos .py, ejecútelos y edítelos más tarde en 
cualquiera de ellos usando IDLE.
En IDLE, presione F5 o run Python Shell para iniciar un intérprete. Usar IDLE puede ser una mejor 
experienciadeaprendizajeparalos nuevos usuarios porqueel códigoseinterpreta a medidaque 
el usuario escribe.
Tenga en cuenta que hay muchas alternativas, vea, por ejemplo, esta discusión o esta lista .
Solución de problemas
• Windows
SiestásenWindows,elcomandopredeterminadoespython .Sirecibeunerror "'python' is 
not recognized" Python "'python' is not recognized" , la causa más probable es que la 
ubicacióndePythonnoseencuentreenla PATH entorno PATH susistema.Sepuedeacceder 
aestohaciendoclicconelbotónderechoen'MiPC'yseleccionando'Propiedades'o 
navegandoa'Sistema' a través de'Panel de control'.Hagaclicen'Configuración avanzada 
delsistema'yluegoen'Variablesdeentorno...'.EditelavariablePATHparaincluirel
    79/1068
    15
x or y # if x is False then y otherwise x 
x and y # if x is False then x otherwise y
not x # if x is True then False, otherwise True
directorio de su instalación de Python, así como la carpeta Script (generalmente 
C:\Python27;C:\Python27\Scripts ). Esto requiere privilegios administrativos y puede requerir 
un reinicio.
Cuando se usan varias versiones de Python en la misma máquina, una posible solución es 
cambiar el nombre de uno de los archivos python.exe . Por ejemplo, nombrar una versión 
python27.exe haría que python27 convierta en el comando de Python para esa versión.
También puedeusar elLanzadordePythonparaWindows, que estádisponiblea travésdel 
instaladoryvienepordefecto.LepermiteseleccionarlaversióndePythonparaejecutar 
usando py -[xy] lugar de python[xy] . Puede usarla última versión de Python 2 ejecutando 
scripts con py -2 y la última versión de Python 3 ejecutando scripts con py -3 .
• Debian / Ubuntu / MacOS
Esta sección asume que la ubicación del ejecutable de python se ha agregado a la PATH
entorno PATH .
Si estás en Debian / Ubuntu / MacOS, abre el terminal y escribe python para Python 2.xo
python3 para Python 3.x.
Escriba which python para ver qué intérprete de Python se utilizará.
• Arco de linux
El Python predeterminado en Arch Linux (y sus descendientes) es Python 3, así que usa
python o python3 para Python python2 para Python 2.x.
• Otros sistemas
Python 3a veces está vinculado a python lugarde python3 .Para usarPython 2 en estos 
sistemas donde está instalado, puede usar python2 .
Tipos de datos
Tipos incorporados
Booleanos
bool : Un valor booleano de True o False . Las operaciones lógicas como and , or , not se pueden 
realizar en valores booleanos.
EnPython2.xyenPython 3.x,un booleano estambiénunint .Eltipoboolesuna subclasedel 
tipo int y True y False son sus únicas instancias:
    80/1068
    16
True + False == 1 # 1 + 0 == 1
True * True == 1 # 1 * 1 == 1
a = 2
b = 100
c = 123456789
d = 38563846326424324
a = 2.0
b = 100.e0
c = 123456789.e1
a = 2 + 1j
b = 100 + 10j
Si se usan valores booleanos en operaciones aritméticas, sus valores enteros ( 1 y 0 para True y
False ) se usarán para devolver un resultado entero:
Números
• int : número entero
Los enteros en Python son de tamaños arbitrarios.
Nota: en versiones anteriores de Python, había un tipo long disponible y esto era distinto de
int . Los dos se han unificado.
• float : número de punto flotante; La precisión depende de la implementación y la 
arquitectura del sistema, para CPython el tipo de datos float corresponde a un C doble.
• complex : números complejos
Los operadores < , <= , > y >= generarán una excepción TypeError cuando cualquier operando sea 
un número complejo.
Instrumentos de cuerda
Python 3.x 3.0
• str:unacadenadeUnicode.Eltipode'hello'
• bytes: una cadena de bytes .El tipo de b'hello'
Python 2.x 2.7
issubclass(bool, int) # True
isinstance(True, bool) # True 
isinstance(False, bool) # True
    81/1068
    17
a = reversed('hello')
a = (1, 2, 3)
b = ('a', 1, 'python', (1, 2))
b[2] = 'something else' # returns a TypeError
a = [1, 2, 3]
b = ['a', 1, 'python', (1, 2), [1, 2]]
b[2] = 'something else' # allowed
a = {1, 2, 'a'}
a = {1: 'one',
2: 'two'}
b = {'a': [1, 2, 3],
'b': 'a string'}
• str : una cadena de bytes . El tipo de 'hello'
• bytes : sinónimo de str
• unicode : una cadena de Unicode . El tipo de u'hello'
Secuencias y colecciones.
Python diferencia entre secuencias ordenadas y colecciones no ordenadas (como set y dict ).
• Las cadenas ( str , bytes , unicode ) sonsecuencias.
• reversed : un orden invertido de str con funciónreversed
• tuple : una colección ordenada de n valores de cualquier tipo ( n >= 0 ).
Soporta indexación; inmutable; hashable si todos sus miembros son hashable
• list : una colección ordenada de n valores ( n >= 0)
No hashable; mudable.
• set : Una colección desordenada de valores únicos. Los artículos deben ser hashable .
• dict : una colección desordenada de pares clave-valor únicos; Las claves deben ser
hashable .
Unobjetoeshashablesitieneunvalorhashquenuncacambiadurantesuvidaútil 
(necesitaun hash () )ypuedecompararseconotrosobjetos(necesitaun eq ()
). Los objetos hashable que comparan la igualdad deben tener el mismo valor hash.
Constantes incorporadas
    82/1068
    18
a = None # No value will be assigned. Any valid datatype can be assigned later
a = '123'
print(type(a))
# Out: <class 'str'> 
b = 123
print(type(b))
# Out: <class 'int'>
i = 7
if isinstance(i, int): 
i += 1
elif isinstance(i, str): 
i = int(i)
i += 1
Junto con los tipos de datos incorporados, hay una pequeña cantidad de constantes incorporadas 
en el espacio de nombres integrado:
• True : El valor verdadero del tipo incorporado bool
• False : el valor falso del tipo incorporado bool
• None : un objeto singleton utilizado para indicar que un valor está ausente.
• Ellipsis o ...: se utiliza en Python3 + en cualquier lugar y uso limitado en Python2.7 + 
como parte de la notación de matriz. numpy paquetes numpy y relacionados usan esto como 
una referencia 'incluir todo' en los arreglos.
• NotImplemented : un singleton utilizado para indicar a Python que un método especial no es 
compatible con los argumentos específicos, y Python probará alternativas si están 
disponibles.
Python 3.x 3.0
None no tiene ningún orden natural. El uso de operadores de comparación de pedidos ( < , <= , >= ,
> ) ya no es compatible y generará un TypeError . 
Python 2.x 2.7
None siempre es menor que cualquier número ( None < -32 evalúa como True ).
Probando el tipo de variables
En Python, podemos verificar el tipo de datos de un objeto usando el type función incorporada.
En declaraciones condicionales es posible probar el tipo de datos con isinstance . Sin embargo, 
generalmente no se recomienda confiar en el tipo de variable.
Para obtenerinformación sobrelas diferenciasentre type()y isinstance()lea: Diferencias entre
isinstance y type enPython
Para probar si algo es de NoneType :
    83/1068
    19
a = '123'
b = int(a)
a = '123.456'
b = float(a)
c = int(a) # ValueError: invalid literal for int() with base 10: '123.456' 
d = int(b) # 123
a = 'hello'
list(a) # ['h', 'e', 'l', 'l', 'o']
set(a) # {'o', 'e', 'l', 'h'}
tuple(a) # ('h', 'e', 'l', 'l', 'o')
# foo 
# bar
# foo\nbar
raw = r'foo\nbar' # foo\nbar
normal = 'foo\nbar'
escaped = 'foo\\nbar'
Convertir entre tipos de datos
Puede realizar la conversión explícita de tipos de datos.
Por ejemplo, '123' es de tipo str y se puede convertir en entero usando la función int .
La conversión de una cadena flotante como '123.456' se puede hacer usando la función float .
También puedes convertir secuencias o tipos de colección.
Tipo de cadena explícita en la definición de 
literales
Con las etiquetas de una letra justo delante de las comillas, puede indicar qué tipo de cadena 
desea definir.
• b'foo bar' : bytes resultados en Python 3, str en Python2
• u'foo bar' : results str en Python 3, unicode en Python2
• 'foo bar' : resultados str
• r'foo bar':resultados llamados cadenas enbruto,dondenoesnecesarioescapar 
caracteres especiales, todo setoma literalmente a medida que se escribe
x = None
if x is None:
print('Not a surprise, I just defined x as None.')
    84/1068
    20
def f(m):
m.append(3) # adds a number to the list. This is a mutation.
x = [1, 2]
f(x)
x == [1, 2] # False now, since an item was added to the list
def bar():
x = (1, 2)
g(x)
x == (1, 2) # Will always be True, since no function can change the object (1, 2)
>>> pow(2,3) #8
Tipos de datos mutables e inmutables
Un objeto se llama mutable si se puede cambiar. Por ejemplo, cuando pasa una lista a alguna 
función, la lista se puede cambiar:
Un objeto se llama inmutable si no se puede cambiar de ninguna manera. Por ejemplo, los 
enteros son inmutables, ya que no hay forma de cambiarlos:
Tenga en cuenta que las variables en sí mismas son mutables, por lo que podemos reasignar la 
variable x , pero esto no cambia el objeto al que x había apuntado anteriormente. Solo hizo que x 
apunte a un nuevo objeto.
Los tipos de datos cuyas instancias son mutables se denominan tipos de datos mutables , y de 
manera similar para los objetos y tipos de datos inmutables.
Ejemplos de tipos de datos inmutables:
• int , long , float , complex
• str
• bytes
• tuple
• frozenset
Ejemplos de tipos de datos mutables:
• bytearray
• list
• set
• dict
Construido en módulos y funciones
Un módulo es un archivo que contiene definiciones y declaraciones de Python. La función es un 
fragmento de código que ejecuta alguna lógica.
Para verificar la función incorporada en python podemos usar dir(). Si se llama sin un
    85/1068
    21
argumento, devuelve los nombres en el alcance actual. De lo contrario, devuelve una lista 
alfabética de nombres que comprenden (algunos de) el atributo del objeto dado y de los atributos 
a los que se puede acceder.
>>> dir( builtins ) 
[
'ArithmeticError', 
'AssertionError', 
'AttributeError', 
'BaseException', 
'BufferError', 
'BytesWarning', 
'DeprecationWarning', 
'EOFError', 
'Ellipsis', 
'EnvironmentError', 
'Exception',
'False', 
'FloatingPointError', 
'FutureWarning', 
'GeneratorExit', 
'IOError', 
'ImportError', 
'ImportWarning', 
'IndentationError', 
'IndexError', 
'KeyError', 
'KeyboardInterrupt', 
'LookupError', 
'MemoryError', 
'NameError',
'None', 
'NotImplemented',
'NotImplementedError', 
'OSError', 
'OverflowError',
'PendingDeprecationWarning', 
'ReferenceError', 
'RuntimeError', 
'RuntimeWarning', 
'StandardError', 
'StopIteration', 
'SyntaxError', 
'SyntaxWarning', 
'SystemError',
'SystemExit', 
'TabError', 
'True', 
'TypeError',
'UnboundLocalError', 
'UnicodeDecodeError', 
'UnicodeEncodeError', 
'UnicodeError', 
'UnicodeTranslateError', 
'UnicodeWarning', 
'UserWarning', 
'ValueError',
'Warning', 
'ZeroDivisionError', 
' debug ',
    86/1068
    22
' doc ', ' import ', 
' name ', ' package', 
'abs',
'all',
'any',
'apply', 
'basestring', 
'bin',
'bool',
'buffer', 
'bytearray', 
'bytes', 
'callable', 
'chr', 
'classmethod', 
'cmp',
'coerce', 
'compile', 
'complex', 
'copyright', 
'credits', 
'delattr', 
'dict',
'dir',
'divmod', 
'enumerate', 
'eval', 
'execfile', 
'exit',
'file',
'filter',
'float',
'format', 
'frozenset', 
'getattr', 
'globals', 
'hasattr', 
'hash',
'help',
'hex',
'id',
'input',
'int',
'intern', 
'isinstance', 
'issubclass', 
'iter',
'len', 
'license', 
'list',
'locals',
'long',
'map',
'max', 
'memoryview', 
'min',
'next',
'object',
'oct',
    87/1068
    23
>>> help(max)
Help on built-in function max in module builtin : 
max(...)
max(iterable[, key=func]) -> value 
max(a, b, c, ...[, key=func]) -> value
With a single iterable argument, return its largest item. 
With two or more arguments, return the largest argument.
>>> import math
>>> math.sqrt(16) # 4.0
>>> import math
>>> dir(math)
[' doc ', ' name ', ' package ', 'acos', 'acosh',
'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign',
'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1',
Para conocer la funcionalidad de cualquier función, podemos utilizar la help incorporada de la 
función.
Los módulos incorporados contienen funcionalidades adicionales. Por ejemplo, para obtener la 
raíz cuadrada de un número, necesitamos incluir math módulo math .
Para conocer todas las funciones de un módulo, podemos asignar la lista de funciones a una 
variable y luego imprimir la variable.
'open',
'ord',
'pow',
'print', 
'property', 
'quit',
'range', 
'raw_input', 
'reduce',
'reload',
'repr', 
'reversed', 
'round',
'set', 
'setattr', 
'slice',
'sorted', 
'staticmethod', 
'str',
'sum',
'super',
'tuple',
'type',
'unichr', 
'unicode', 
'vars',
'xrange', 
'zip'
]
    88/1068
    24
>>> math. doc
'This module is always available. It provides access to the\nmathematical 
functions defined by the Cstandard.'
"""This is the module docstring."""
def sayHello():
"""This is the function docstring.""" 
return 'Hello World'
>>> import helloWorld
>>> helloWorld. doc
'This is the module docstring.'
>>> helloWorld.sayHello. doc
'This is the function docstring.'
>>> class MyClassObject(object):
... pass
...
>>> dir(MyClassObject)
[' class ', ' delattr ', ' dict ', ' doc ', ' format ', ' getattribute ',
' hash ', ' init ', ' module ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', 
' setattr ', ' sizeof ', ' str ', ' subclasshook ', ' weakref ']
>>> str(123) # "123"
Parece que doc es útil para proporcionar alguna documentación en, digamos, funciones
Además de las funciones, la documentación también se puede proporcionar en módulos. 
Entonces, si tienes un archivo llamado helloWorld.py como este:
Puedes acceder a sus documentos como este:
• Para cualquier tipo definido por el usuario, sus atributos, los atributos de su clase y 
recursivamente los atributos de las clases base de su clase se pueden recuperar usando dir 
()
Cualquier tipo de datos se puede convertir simplemente a cadena usando una función 
incorporada llamada str .Esta función se llama de forma predeterminada cuando se pasa un tipo 
de datos para print
Sangría de bloque
Python utiliza la sangría para definir el control y las construcciones de bucle. Esto contribuye a la 
legibilidad de Python, sin embargo, requiere que el programador preste mucha atención al uso del 
espacio en blanco. Por lo tanto, la mala calibración del editor podría resultar en un código que se
'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma',
'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10',
'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 
'tan', 'tanh', 'trunc']
    89/1068
    25
def my_function(): # This is a function definition. Note the colon (:) 
a = 2 # This line belongs to the function because it's indented 
return a # This line also belongs to the same function
print(my_function()) # This line is OUTSIDE the functionblock
if a > b: print(a) 
else: print(b)
if x > y: y = x
print(y) # IndentationError: unexpected indent
if x > y: while y != z: y -= 1 # SyntaxError: invalid syntax
def will_be_implemented_later(): 
pass
comporta de manera inesperada.
Python usa el símbolo de dos puntos ( : ) y sangría para mostrar dónde bloques de código 
empiezan y terminan (Si viene de otro idioma, no confunda esto con alguna manera estar 
relacionado con el operador ternario ).Es decir,los bloques enPython, tales como funciones, 
bucles,cláusulas ifyotras construcciones,notienenidentificadores finales.Todoslosbloques 
comienzan con dos puntos y luego contienen las líneas sangradas debajo de él.
Por ejemplo:
o
if a > b:
print(a) 
else:
print(b)
# If block starts here
# This is part of the if block
# else must be at the same level as if 
# This line is part of the else block
Los bloques que contienen exactamente una instrucción de una sola línea se pueden colocar en 
la misma línea, aunque esta forma generalmente no se considera un buen estilo:
Intentar hacer esto con más de una sola declaración no funcionará:
Un bloque vacío causa un IndentationError . Use pass (un comando que no hace nada) cuando 
tiene un bloque sin contenido:
Espacios vs. Pestañas
En resumen: siempre usa 4 espacios para la sangría.
El uso exclusivo de pestañas es posible, pero PEP 8 , la guía de estilo para el código Python, 
indica que se prefieren los espacios.
Python 3.x 3.0
    90/1068
    26
int_list = [1, 2, 3] 
string_list = ['abc', 'defghi']
Python3nopermitemezclar elusodetabulacionesyespaciosparalasangría.Entalcaso,se 
genera un error en tiempo de compilación: Inconsistent use of tabs and spaces in indentation y el 
programa no se ejecutará.
Python 2.x 2.7
Python 2 permite mezclar tabulaciones y espacios en sangría; Esto es fuertemente desalentado. 
El carácter de la pestaña completa la sangría anterior para ser un múltiplo de 8 espacios . Como 
es común que los editores estén configurados para mostrar pestañas como múltiplos de 4 
espacios, esto puede causar errores sutiles.
Citando el PEP 8 :
Cuandoseinvocaal intérpretedelíneadecomandosdePython2conlaopción -t, 
emite advertencias sobre el código que mezcla de forma ilegal las pestañas y los 
espacios.Al usar -tt estas advertencias se convierten en errores.Estas opciones son 
muy recomendables!
Muchos editores tienen configuración de "pestañas a espacios". Al configurar el editor, uno debe 
diferenciar entre el carácter de la pestaña ('\ t') y la tecla Tab .
• El carácter de la pestaña debe configurarse para mostrar 8 espacios, para que coincida con
la semántica del idioma, al menos en los casos en que es posible una sangría (accidental). 
Los editores también pueden convertir automáticamente el carácter de tabulación a 
espacios.
• Sin embargo, puede ser útil configurar el editor para que al presionar la tecla Tab , se 
inserten 4 espacios, en lugar de insertar un carácter de pestaña.
El código fuente de Python escrito con una combinación de tabulaciones y espacios, o con un 
número no estándar de espacios de sangría se puede hacer compatible con pep8 usando 
autopep8 . (Una alternativa menos poderosa viene con la mayoría de las instalaciones de Python: 
reindent.py )
Tipos de colección
Hayvarios tiposdecoleccionesenPython.Mientrasquelostiposcomointystrtienenunsolo 
valor, los tipos de colección tienen múltiplesvalores.
Liza
El tipo de list es probablemente el tipo de colección más utilizado en Python. A pesar de su 
nombre, una lista es más como una matriz en otros idiomas, principalmente JavaScript. En 
Python, una lista es simplemente una colección ordenada de valores válidos de Python. Se puede 
crear una lista encerrando valores, separados por comas, entre corchetes:
Una lista puede estar vacía:
    91/1068
    27
mixed_list = [1, 'abc', True, 2.34, None]
nested_list = [['a', 'b', 'c'], [1, 2, 3]]
names = ['Alice', 'Bob', 'Craig', 'Diana', 'Eric'] 
print(names[0]) # Alice
print(names[2]) # Craig
print(names[-1]) # Eric 
print(names[-4]) # Bob
names[0] = 'Ann' 
print(names)
# Outputs ['Ann', 'Bob', 'Craig', 'Diana', 'Eric']
names.insert(1, "Nikki") 
print(names)
# Outputs ['Alice', 'Nikki', 'Bob', 'Craig', 'Diana', 'Eric', 'Sia']
names.remove("Bob")
Los elementos de una lista no están restringidos a un solo tipo de datos, lo que tiene sentido dado 
que Python es un lenguaje dinámico:
Una lista puede contener otra lista como su elemento:
Se puede acceder a los elementos de una lista a través de un índice o representación numérica 
de su posición. Las listas en Python tienen índice cero, lo que significa que el primer elemento de 
la lista está en el índice 0, el segundo elemento está en el índice 1 y así sucesivamente:
Los índices también pueden ser negativos, lo que significa contar desde el final de la lista ( -1 es 
el índice del último elemento). Entonces, usando la lista del ejemplo anterior:
Las listas son mutables, por lo que puede cambiar los valores en una lista:
Además, es posible agregar y / o eliminar elementos de una lista: 
Agregar objeto al final de la lista con L.append(object) , devuelve None .
Agregue un nuevo elemento a la lista en un índice específico. L.insert(index, object)
Elimine la primera aparición de un valor con L.remove(value) , devuelve None
names = ['Alice', 'Bob', 'Craig', 'Diana', 'Eric'] 
names.append("Sia")
print(names)
# Outputs ['Alice', 'Bob', 'Craig', 'Diana', 'Eric', 'Sia']
empty_list = []
    92/1068
    28
name.index("Alice") 
0
len(names) 
6
a = [1, 1, 1, 2, 3, 4]
a.count(1) 
3
a.reverse()
[4, 3, 2, 1, 1, 1]
# or 
a[::-1]
[4, 3, 2, 1, 1, 1]
names.pop() # Outputs 'Sia'
for element in my_list: 
print (element)
ip_address = ('10.20.30.40', 8080)
Obtenga el índice en la lista del primer elemento cuyo valor es x. Se mostrará un error si no hay 
tal elemento.
Cuenta la longitud de la lista
cuenta la ocurrencia de cualquier artículo en la lista
Revertir la lista
Elimine y devuelva el elemento en el índice (predeterminado al último elemento) con
L.pop([index]) , devuelve el elemento
Puede iterar sobre los elementos de la lista como a continuación:
Tuplas
Una tuple es similar a una lista, excepto que es de longitud fija e inmutable. Por lo tanto, los 
valores de la tupla no se pueden cambiar ni los valores se pueden agregar o quitar de la tupla. 
Las tuplas se usan comúnmente para pequeñas colecciones de valores que no será necesario 
cambiar, como una dirección IPyunpuerto. Las tuplas se representan conparéntesis enlugar de 
corchetes:
Las mismas reglas de indexación para las listas también se aplican a las tuplas. Las tuplas 
también se pueden anidar y los valores pueden ser válidos para cualquier Python válido.
print(names) # Outputs ['Alice', 'Nikki', 'Craig', 'Diana', 'Eric', 'Sia']
    93/1068
    29
one_member_tuple = ('Only member',)
one_member_tuple = 'Only member', # No brackets
one_member_tuple = tuple(['Only member'])
state_capitals = {
'Arkansas': 'Little Rock', 
'Colorado': 'Denver', 
'California': 'Sacramento', 
'Georgia': 'Atlanta'
}
ca_capital = state_capitals['California']
for k in state_capitals.keys():
print('{} is the capital of {}'.format(state_capitals[k], k))
first_names = {'Adam', 'Beth', 'Charlie'}
Una tupla con un solo miembro debe definirse (tenga en cuenta la coma) de esta manera:
o
o simplemente usando la sintaxis de la tuple
Los diccionarios
Un dictionary en Python es una colección de pares clave-valor. El diccionario está rodeado de 
llaves. Cada par está separado por una coma y la clave y el valor están separados por dos 
puntos. Aquí hay un ejemplo:
Para obtener un valor, consúltelo por su clave:
También puede obtener todas las claves en un diccionario y luego repetirlas:
Los diccionarios se parecen mucho a la sintaxis JSON. El módulo json nativo en la biblioteca 
estándar de Python se puede usar para convertir entre JSON y diccionarios.
conjunto
Un setes una colección de elementos sin repeticiones y sin orden de inserción pero ordenado. Se 
usan en situaciones en las que solo es importante que algunas cosas se agrupen y no en qué 
ordenseincluyeron.Paragruposgrandesde datos,es mucho más rápidoverificar si unelemento 
está o no en un set que hacer lo mismo para una list.
Definirunsetesmuysimilaradefinirundictionary:
Opuedesconstruir unset usandounalistexistente:
    94/1068
    30
if name in first_names: 
print(name)
>>> state_capitals = { 
'Arkansas': 'Little Rock', 
'Colorado': 'Denver', 
'California': 'Sacramento', 
'Georgia': 'Atlanta'
}
>>> state_capitals['Alabama'] 
Traceback (most recent call last):
File "<ipython-input-61-236329695e6f>", line 1, in <module> 
state_capitals['Alabama']
KeyError: 'Alabama'
>>> from collections import defaultdict
>>> state_capitals = defaultdict(lambda: 'Boston')
>>> state_capitals['Arkansas'] = 'Little Rock'
>>> state_capitals['California'] = 'Sacramento'
Verifique la membresía del set usando in :
Puede iterar sobre un set exactamente como una lista, pero recuerde: los valores estarán en un 
orden arbitrario, definido por la implementación.
sentencia por defecto
Un defaultdict es un diccionario con un valor por defecto para las llaves, por lo que las claves 
para el que ha sido definida explícitamente ningún valor se puede acceder sin errores. defaultdict 
es especialmente útil cuando los valores del diccionario son colecciones (listas, dicts, etc.) en el 
sentido de que no es necesario inicializar cada vez que se usa una nueva clave.
Undefaultdict nuncagenerará unKeyError.Cualquier clavequeno existaobtiene el valor 
predeterminado devuelto.
Por ejemplo, considere el siguiente diccionario
Si intentamos acceder a una clave que no existe, Python nos devuelve un error de la siguiente 
manera
Probemos con un defaultdict . Se puede encontrar en el módulo de colecciones.
Lo que hicimos aquí es establecer un valor predeterminado ( Boston ) en caso de que la clave de 
asignación no exista. Ahora rellena el dict como antes:
my_list = [1,2,3] 
my_set = set(my_list)
    95/1068
    31
>>> state_capitals['Alabama'] 
'Boston'
>>> state_capitals['Arkansas'] 
'Little Rock'
>>> help()
>>> help(help)
help> help
Thisis a wrapper around pydoc.help that provides a helpful message 
when 'help' is typed at the Python interactive prompt.
Calling help() at the Python prompt starts an interactive help session. 
Calling help(thing) prints help for the python object 'thing'.
Methods defined here:
 call (self, *args, **kwds)
 repr (self)
----------------------------------------------------------------------
Data descriptors defined here:
dict
| Define the builtin'help'.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Help on _Helper in module _sitebuiltins object:
class _Helper(builtins.object)
Si intentamos acceder al dict con una clave que no existe, Python nos devolverá el valor 
predeterminado, es decir, Boston
y devuelve los valores creados para la clave existente al igual que un dictionary normal
Utilidad de ayuda
Python tiene varias funciones integradas en el intérprete. Si desea obtener información sobre 
palabras clave, funciones incorporadas, módulos o temas, abra una consola de Python e ingrese:
Recibirá información ingresando palabras clave directamente:
o dentro de la utilidad:
que mostrará una explicación:
= 'Denver'
>>> state_capitals['Georgia'] = 'Atlanta'
>>> state_capitals['Colorado']
    96/1068
    32
help(pymysql.connections)
>>> help(math)
>>> import math
>>> help(math)
$ python
>>> import hello
>>> hello.say_hello()
=> "Hello!"
# greet.py 
import hello
hello.say_hello()
También puedes solicitar subclases de módulos:
Puede usar la ayuda para acceder a las cadenas de documentación de los diferentes módulos 
que ha importado, por ejemplo, intente lo siguiente:
y obtendrás un error
Y ahora obtendrá una lista de los métodos disponibles en el módulo, pero solo DESPUÉS de 
haberlo importado.
Cerrar el ayudante con quit
Creando un modulo
Un módulo es un archivo importable que contiene definiciones y declaraciones. 
Se puede crear un módulo creando un archivo .py .
Las funciones en un módulo se pueden utilizar importando el módulo.
Para los módulos que haya creado, deberán estar en el mismo directorio que el archivo en el que 
los está importando. (Sin embargo, también puede colocarlos en el directorio lib de Python con los 
módulos pre-incluidos, pero debe evitarse si es posible).
Los módulos pueden ser importados por otros módulos.
# hello.py
def say_hello(): 
print("Hello!")
weakref
list of weak references to the object (if defined)
| dictionary for instance variables (if defined)
|
|
|
    97/1068
    33
# greet.py
from hello import say_hello 
say_hello()
# greet.py
import hello as ai 
ai.say_hello()
# run_hello.py
if name == ' main ':
from hello import say_hello 
say_hello()
$ python run_hello.py
=> "Hello!"
Se pueden importar funciones específicas de un módulo.
Los módulos pueden ser alias.
Un módulo puede ser un script ejecutable independiente.
¡Ejecutarlo!
Siel módulo estádentro de un directorio y necesita serdetectado por python,el directorio debe 
contener un archivo llamado init .py .
Función de cadena - str () y repr ()
Hay dos funciones que se pueden usar para obtener una representación legible de un objeto.
repr(x)llamaax. repr ():unarepresentacióndex. evalgeneral, evalconvertiráelresultado 
de esta función al objetooriginal.
str(x)llamaax. str ():unacadenalegibleporhumanosquedescribeelobjeto.Estopuede 
ocultar algunos detalles técnicos.
repr ()
Paramuchos tipos,esta funciónintentadevolverunacadenaqueproduciríaunobjetoconel 
mismo valor cuando se pasa a eval() . De lo contrario, la representación es una cadena 
encerrada entre paréntesis angulares que contiene el nombre del tipo del objeto junto con 
información adicional. Esto a menudo incluye el nombre y la dirección del objeto.
str ()
Para las cadenas, esto devuelve la cadena en sí. La diferencia entre esto y repr(object) es que
str(object) no siempre intenta devolver una cadena que sea aceptable para eval() . Más bien, su
    98/1068
    34
s = """w'o"w"""
repr(s) # Output: '\'w\\\'o"w\''
str(s) # Output: 'w\'o"w'
eval(str(s)) == s # Gives a SyntaxError 
eval(repr(s)) == s # Output: True
import datetime
today = datetime.datetime.now()
str(today) # Output: '2016-09-15 06:58:46.915000'
repr(today) # Output: 'datetime.datetime(2016, 9, 15, 6, 58, 46, 915000)'
class Represent(object):
def init (self, x, y): 
self.x, self.y = x, y
def repr (self):
return "Represent(x={},y=\"{}\")".format(self.x, self.y)
def str (self):
return "Representing x as {} and y as {}".format(self.x, self.y)
r = Represent(1, "Hopper") 
print(r) # prints str
print(r. repr ) # prints repr : '<bound methodRepresent. repr of 
Represent(x=1,y="Hopper")>'
rep = r. repr () # sets the execution of repr to a new variable 
print(rep) # prints 'Represent(x=1,y="Hopper")'
r2 = eval(rep) # evaluates rep
print(r2) # prints str from new object
print(r2 == r) # prints 'False' because they are different objects
objetivoesdevolverunacadena imprimible o "legiblepara humanos".Si no seda ningún 
argumento, esto devuelve la cadena vacía, ''.
Ejemplo 1:
Ejemplo 2:
Al escribir una clase, puede anular estos métodos para hacer lo que quiera:
Usando la clase anterior podemos ver los resultados:
Instalación de módulos externos utilizando pip
pip es tu amigo cuando necesitas instalar cualquier paquete de la gran cantidad de opciones 
disponibles en el índice del paquete python (PyPI). pip ya está instalado si estás usando Python 
2> = 2.7.9 o Python 3> = 3.4 descargado desde python.org. Para computadoras que ejecutan 
Linux u otro * nix con un administrador de paquetes nativo, pip debe instalarse manualmente.
En instancias con Python 2 y Python 3 instalados, pip menudo se refiere a Python 2 y pip3 a 
Python 3. El uso de pip solo instalará paquetes para Python 2 y pip3 solo instalará paquetes para
    99/1068
    35
$ pip search <query>
# Searches for packages whose name or summary contains <query>
$ pip install '[package_name]>=x.x.x' # minimum version of the package
$ pip install [package_name]==x.x.x # specific version of the package
$ pip install [package_name] # latest version of the package
$ pip --proxy http://<server address>:<port> install
$ pip list --outdated
$ pip install [package_name] --upgrade
Python 3.
Encontrar / instalar un paquete
La búsqueda de un paquete es tan simple como escribir
Instalar un paquete es tan simple como escribirlo (en un terminal / símbolo del sistema, no en el 
intérprete de Python)
donde xxx es el número de versión del paquete que desea instalar.
Cuando su servidor está detrás de proxy, puede instalar el paquete usando el siguiente comando:
Actualización de paquetes instalados
Cuando aparecen nuevas versiones de paquetes instalados, no se instalan automáticamente en 
su sistema. Para obtener una descripción general de cuáles de sus paquetes instalados están 
desactualizados, ejecute:
Para actualizar el uso de un paquete específico
Actualizar todos los paquetes obsoletos no es una funcionalidad estándar de pip .
Actualización de pip
Puede actualizar su instalación pip existente usando los siguientes comandos
• En Linux o macOS X:
    100/1068
    36
py -m pip install -U pip
python -m pip install -U pip
C:\Python27\
python --version
Es posible que necesite usar sudo con pip en algunos sistemas Linux
• En Windows:
o
Para más información sobre pip, lea aquí .
Instalación de Python 2.7.xy 3.x
Nota : las siguientes instrucciones están escritas para Python 2.7 (a menos que se 
especifique): las instrucciones para Python 3.x son similares.
VENTANAS
Primero, descargue la última versión de Python 2.7 del sitio web oficial ( 
https://www.python.org/downloads/) . La versión se proporciona como un paquete MSI. Para 
instalarlo manualmente, simplemente haga doble clic en el archivo.
Por defecto, Python se instala en un directorio:
Advertencia: la instalación no modifica automáticamente la variable de entorno PATH. 
Suponiendo que su instalación de Python está en C: \ Python27, agregue esto a su PATH:
Ahora para comprobar si la instalación de Python es válida, escriba en cmd:
Python 2.xy 3.x lado a lado
Para instalar y usar Python 2.xy 3.x lado a lado en una máquina con Windows:
1. Instale Python 2.x usando el instalador MSI.
• Asegúrese de que Python esté instalado para todos los usuarios.
• Opcional:agreguePython a PATH para hacer quePython 2.xse puedallamardesdela 
línea de comandos usando python .
C:\Python27\;C:\Python27\Scripts\
$ pip install -U pip
    101/1068
    37
P:\>py -3
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 bit (Intel)] on win32 
Type "help", "copyright", "credits" or "license" for more information.
>>>
C:\>py -2
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
C:\>py -3 -m pip -V
pip 9.0.1 from C:\Python36\lib\site-packages (python 3.6)
C:\>py -2 -m pip -V
pip 9.0.1 from C:\Python27\lib\site-packages (python 2.7)
wget --no-check-certificate https://www.python.org/ftp/python/2.7.X/Python-2.7.X.tgz
tar -xzf Python-2.7.X.tgz
cd Python-2.7.X
./configure 
make
sudo make install
python --version
2. Instala Python 3.x usando su respectivo instalador.
• Una vez más, asegúrese de que Python esté instalado para todos los usuarios.
• Opcional: agregue Python a PATH para que Python 3.x se pueda llamar desde la línea 
de comandos usando python . Esto puede anular la configuración de Python 2.x PATH , 
porlo tanto, vuelva a verificar su PATH y asegúrese de que esté configurado según sus 
preferencias.
• Asegúrate de instalar el py launcher para todos los usuarios.
Python 3 instalará el iniciador de Python que se puede usar para lanzar Python 2.xy Python 3.x 
indistintamente desde la línea de comandos:
Para usar la versión correspondiente de pip para una versión específica de Python, use:
LINUX
Las últimas versiones de CentOS, Fedora, Redhat Enterprise (RHEL) y Ubuntu vienen con Python 
2.7.
Para instalar Python 2.7 en linux manualmente, simplemente haga lo siguiente en la terminal:
También agregue la rutadel nuevo python en lavariable de entornoPATH.Si el nuevo python 
está en /root/python-2.7.X , ejecute export PATH = $PATH:/root/python-2.7.X
Ahora para comprobar si la instalación de Python es válida, escriba en el terminal:
Ubuntu (desde la fuente)
    102/1068
    38
sudo apt install build-essential checkinstall
sudo apt install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev 
libgdbm-dev libc6-dev libbz2-dev
wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tar.xz
tar xvf Python-3.6.1.tar.xz
cd Python-3.6.1/
./configure --enable-optimizations 
sudo make altinstall
/usr/bin/ruby -e "$(curl -fsSL 
https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install python
Si necesita Python 3.6, puede instalarlo desde la fuente como se muestra a continuación (Ubuntu 
y 17.04 tienen la versión 3.6 en el repositorio universal). Deben seguirse los siguientes 
pasos para Ubuntu 16.04 y versiones inferiores:
Mac OS
Mientras hablamos, macOS viene instalado con Python 2.7.10, pero esta versión está 
desactualizada y ligeramente modificada de Python regular.
La versión de Python que se incluye con OS X es excelente para el aprendizaje, pero 
no es buena para el desarrollo. La versión enviada con OS X puede estar 
desactualizada de la versión oficial actual de Python, que se considera la versión de 
producción estable. ( fuente )
Instalar Homebrew :
Instala Python 2.7:
Para Python 3.x, use el comando brew install python3 en brew install python3 lugar.
    103/1068
    39
def func(*args, **kwargs): 
print(args) 
print(kwargs)
def func(*a, **b): 
print(a) 
print(b)
def func(*args1, *args2): 
# File "<stdin>", line 1
# def test(*args1, *args2): 
# ^
# SyntaxError: invalid syntax
def test(**kwargs1, **kwargs2): 
# File "<stdin>", line 1
# def test(**kwargs1, **kwargs2): 
# ^
# SyntaxError: invalid syntax
def func(a, b, *args, x, y):
print(a, b, args, x, y)
func(1, 2, 3, 4, x=5, y=6)
#>>> 1, 2, (3, 4), 5, 6
def func(a, b, *, x, y):
Capítulo 2: * args y ** kwargs
Observaciones
Hay algunas cosas a tener en cuenta:
1. Los nombres args y kwargs se usan por convención, no forman parte de la especificación del 
lenguaje. Por lo tanto, estos sonequivalentes:
2. No puede tener más de un args o más de un parámetro de kwargs (sin embargo, no son 
necesarios)
3. Si algún argumento posicional sigue a *args , son argumentos de palabra clave que solo se 
pueden pasar por nombre. Se puede usar una sola estrella en lugar de *args para forzar que 
los valores sean argumentos de palabras clave sin proporcionar una lista de parámetros 
variadic. Las listas de parámetros de palabras clave solo están disponibles en Python 3.
    104/1068
    40
def test(**kwargs, *args): 
# File "<stdin>", line 1
# def test(**kwargs, *args): 
# ^
# SyntaxError: invalid syntax
def print_args(farg, *args): 
print("formal arg: %s" % farg) 
for arg in args:
print("another positional arg: %s" % arg)
print_args(1, "two", 3)
def print_kwargs(**kwargs): 
print(kwargs)
print_kwargs(a="two", b=3) 
# prints: "{a: "two", b=3}"
4. **kwargs deben estar en último lugar en la lista de parámetros.
Examples
Usando * args al escribir funciones
Puede usar la estrella * al escribir una función para recopilar todos los argumentos posicionales 
(es decir, sin nombre) en una tupla:
Método de llamada:
En esa llamada, farg se asignará como siempre, y los otros dos se introducirán en la tupla de 
args, en el orden en que se recibieron.
Usando ** kwargs al escribir funciones
Puede definir una función que tome un número arbitrario de argumentos de palabra clave 
(nombrados) usando la estrella doble ** antes del nombre de un parámetro:
Al llamar al método, Python construirá un diccionario de todos los argumentos de palabras clave y 
lo pondrá a disposición en el cuerpo de la función:
Tenga en cuenta que el parámetro ** kwargs en la definición de la función siempre debe ser el 
último parámetro, y solo coincidirá con los argumentos que se pasaron después de los anteriores.
print(a, b, x, y)
func(1, 2, x=5, y=6) 
#>>> 1, 2, 5, 6
    105/1068
    41
def print_kwargs(**kwargs): 
for key in kwargs:
print("key = {0}, value = {1}".format(key, kwargs[key]))
print_kwargs(a = "two", b = 1) 
key = a, value = "two"
key = b, value = 1
class A(object):
def init (self, b, c): 
self.y = b
self.z = c
class B(A):
def init (self, a, *args, **kwargs): 
super(B, self). init (*args, **kwargs) 
self.x = a
b = B(1, 2, 3)
# 1
# 2
# 3
Dentro del cuerpo de la función, los kwargs se manipulan de la misma manera que un diccionario; 
para acceder a elementos individuales en kwargs , solo tienes que recorrerlos como lo harías con 
un diccionario normal:
Ahora, al llamar a print_kwargs(a="two", b=1) muestra el siguiente resultado:
Usando * args al llamar a funciones
Un caso de uso común para *args en una definición de función es delegar el procesamiento a una 
función envuelta o heredada. Un ejemplo típico podría estar en el método init una clase
Aquí,el a parámetro es procesado porlaclase niño después de todos los otros argumentos 
(posicionales y de palabras clave) son pasados a - y procesados por -la clase base.
Por ejemplo:
Lo que sucede aquí es que la función de clase B init ve los argumentos 1, 2, 3 . Sabe que 
necesita tomar un argumento posicional ( a ), porlo que toma el primer argumento pasado en ( 1
), por lo que en el alcance de la función a == 1.
Acontinuación,vequenecesitatomarunnúmeroarbitrariodeargumentosposicionales(*args), 
porlo que toma el resto de los argumentos posicionales pasados en ( 1, 2 ) y los mete en *args. 
Ahora (en el ámbito de la función) args == [2, 3] .
def example(a, **kw): 
print kw
example(a=2, b=3, c=4) # => {'b': 3, 'c': 4}
    106/1068
    42
def test_func(arg1, arg2, arg3): # Usual function with three arguments 
print("arg1: %s" % arg1)
print("arg2: %s" % arg2) 
print("arg3: %s" % arg3)
# Note that dictionaries are unordered, so we can switch arg2 and arg3. Only the names matter. 
kwargs = {"arg3": 3, "arg2": "two"}
# Bind the first argument (ie. arg1) to 1, and use the kwargs dictionary to bind the others 
test_var_args_call(1, **kwargs)
def print_args(arg1, arg2): 
print(str(arg1) + str(arg2))
a = [1,2]
b = tuple([3,4])
print_args(*a) 
# 12
print_args(*b) 
# 34
a = [1,3,5,7,9]
b = [2,4,6,8,10]
zipped = zip(a,b)
# [(1,2), (3,4), (5,6), (7,8), (9,10)]
zip(*zipped)
Luego, llama a la función init clase A con *args . Python ve el * delante de args y 
"desempaqueta"lalistaenargumentos.En esteejemplo, cuandolaclase B's init llamadas 
de función de clase A ' s init función, será pasado los argumentos 2, 3 (es decir, A(2, 3)).
Finalmente, establece su propia propiedad x en el primer argumento posicional a , que es igual a 1
.
Usando ** kwargs al llamar a funciones
Puede usar un diccionario para asignar valores a los parámetros de la función; usando los 
parámetros nombre como claves en el diccionario y el valor de estos argumentos enlazados a 
cada clave:
Usando * args al llamar a funciones
El efecto de usar el operador * en un argumento al llamar a una función es el de desempaquetar 
la lista o un argumento de tupla
Tenga en cuenta que la longitud del argumento destacado debe ser igual al número de 
argumentos de la función.
Un lenguaje común en Python es usar el operador de desempaquetado * con la función zip para 
revertir sus efectos:
    107/1068
    43
def print_args(arg1, *args, keyword_required, keyword_only=True): 
print("first positional arg: {}".format(arg1))
for arg in args:
print("another positional arg: {}".format(arg)) 
print("keyword_required value: {}".format(keyword_required)) 
print("keyword_only value: {}".format(keyword_only))
print(1, 2, 3, 4) # TypeError: print_args() missing 1 required keyword-only argument: 
'keyword_required'
print(1, 2, 3, keyword_required=4)
def foobar(foo=None, bar=None): 
return "{}{}".format(foo, bar)
values = {"foo": "foo", "bar": "bar"} 
foobar(**values) # "foobar"
def fun(**kwargs):
print kwargs.get('value', 0)
fun()
# print 0 
fun(value=1) 
# print 1
Argumentos solo de palabra clave y requeridos de palabra clave
Python 3 le permite definir argumentos de función que solo pueden asignarse por palabra clave, 
incluso sin valores predeterminados. Esto se hace usando star * para consumir parámetros 
posicionales adicionales sin configurar los parámetros de palabras clave. Todos los argumentos 
después del * son argumentos de palabra clave solamente (es decir, no posicionales). Tenga en 
cuenta que si los argumentos de solo palabras clave no tienen un valor predeterminado, todavía 
son necesarios al llamar a la función.
# first positional arg: 1
# another positional arg: 2
# another positional arg: 3
# keyword_required value: 4
# keyword_only value: True
Poblando los valores kwarg con un diccionario
** kwargs y valores por defecto
Para usar los valores por defecto con ** kwargs
# (1,3,5,7,9), (2,4,6,8,10)
    108/1068
    44
Capítulo 3: Acceso a la base de datos
Observaciones
Python puede manejar muchos tipos diferentes de bases de datos. Para cada uno de estos tipos 
existe una API diferente. Así que fomente la similitud entre esas diferentes API, se haintroducido 
PEP 249.
Esta API se ha definido para fomentar la similitud entre los módulos de Python que se 
utilizan para acceder a las bases de datos. Al hacer esto, esperamos lograr una 
consistencia que conduzca a módulos más fáciles de entender, código que 
generalmente es más portátil en las bases de datos y un mayor alcance de la 
conectividad de base de datos de Python. PEP-249
Examples
Accediendo a la base de datos MySQL usando MySQLdb
Lo primero que debe hacer es crear una conexión a la base de datos utilizando el método de 
conexión. Después de eso, necesitará un cursor que operará con esa conexión.
Utilice el método de ejecución del cursor para interactuar con la base de datos y, de vez en 
cuando, confirme los cambios utilizando el método de confirmación del objeto de conexión.
Una vez hecho todo, no olvides cerrar el cursor y la conexión. 
Aquí hay una clase Dbconnect con todo lo que necesitas.
Interactuar con la base de datos es simple. Después de crear el objeto, simplemente use el 
método de ejecución.
import MySQLdb
class Dbconnect(object): 
def init (self):
self.dbconection = MySQLdb.connect(host='host_example',
port=int('port_example'), 
user='user_example', 
passwd='pass_example', 
db='schema_example')
self.dbcursor = self.dbconection.cursor()
def commit_db(self): 
self.dbconection.commit()
def close_db(self): 
self.dbcursor.close() 
self.dbconection.close()
    109/1068
    45
db = Dbconnect() 
db.callproc('stored_procedure_name', [parameters] )
results = db.dbcursor.fetchall() 
for individual_row in results:
first_field = individual_row[0]
for individual_row in db.dbcursor: 
first_field = individual_row[0]
db.commit_db()
db.close_db()
import sqlite3
conn = sqlite3.connect("users.db") 
c = conn.cursor()
c.execute("CREATE TABLE user (name text, age integer)")
c.execute("INSERTINTOuser VALUES('UserA',42)") 
c.execute("INSERTINTOuser VALUES('UserB',43)")
conn.commit()
c.execute("SELECT* FROMuser") 
print(c.fetchall())
conn.close()
Si desea llamar a un procedimiento almacenado, use la siguiente sintaxis. Tenga en cuenta que la 
lista de parámetros es opcional.
Una vez que se realiza la consulta, puede acceder a los resultados de varias maneras. El objeto 
del cursor es un generador que puede obtener todos los resultados o ser enlazado.
Si quieres un loop usando directamente el generador:
Si desea confirmar los cambios en la base de datos:
Si quieres cerrar el cursor y la conexión:
SQLite
SQLite es una base de datos ligera, basada en disco. Dado que no requiere un servidor de base 
de datos separado, a menudo se usa para hacer prototipos o para aplicaciones pequeñas que a 
menudo usan un solo usuario o un usuario en un momento dado.
db = Dbconnect()
db.dbcursor.execute('SELECT * FROM %s' % 'table_example')
    110/1068
    46
[(u'User A', 42), (u'User B', 43)]
>>> import sqlite3
>>> conn = sqlite3.connect('users.db')
>>> conn = sqlite3.connect(':memory:')
c = conn.cursor()
# Create table 
c.execute('''CREATETABLE stocks
(date text, trans text, symbol text, qty real, price real)''')
# Insert a row of data
c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)")
# Save (commit) the changes 
conn.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost. 
conn.close()
El código anterior se conecta a la base de datos almacenada en el archivo llamado users.db , 
creando primero el archivo si aún no existe. Puede interactuar con la base de datos a través de 
sentencias de SQL.
El resultado de este ejemplo debe ser:
La sintaxis de SQLite: un análisis en 
profundidad
Empezando
1. Importar el módulo sqlite usando
2. Para usar el módulo, primero debe crear un objeto de conexión que represente la base de 
datos. Aquí los datos se almacenarán en el archivo example.db:
Alternativamente, también puede proporcionar el nombre especial :memory: para crear una 
base de datos temporal en la RAM, de la siguiente manera:
3. Una vez que tenga una Connection , puede crear un objeto Cursor y llamar a su método
execute() para ejecutar comandos SQL:
    111/1068
    47
def dict_factory(cursor, row): 
d = {}
fori,colinenumerate(cursor.description): 
d[col[0]] = row[i]
return d
conn = sqlite3.connect(":memory:") 
conn.row_factory = dict_factory
Atributos importantes y funciones de Connection
1. isolation_level
Es un atributo utilizado para obtener o establecer el nivel de aislamiento actual. Ninguno 
para el modo de confirmación automática o uno de DEFERRED , IMMEDIATE o EXCLUSIVE .
2. cursor
El objeto del cursor se utiliza para ejecutar comandos y consultas SQL.
3. commit()
Confirma la transacción actual.
4. rollback()
Deshace los cambios realizados desde la llamada anterior a commit()
5. close()
Cierra la conexión de la base de datos. No llama a commit() automáticamente. Si se llama a
close() sin llamar primero a commit() (suponiendo que no esté en modo de commit()
automática), se perderán todos los cambios realizados.
6. total_changes
Un atributo que registra el número total de filas modificadas, eliminadas o insertadas desde 
que se abrió la base de datos.
7. execute , executemany y executescript
Estas funciones se realizan de la misma manera que las del objeto cursor. Este es un atajo 
ya que llamar a estas funciones a través del objeto de conexión da como resultado la 
creación de un objeto de cursor intermedio y llama al método correspondiente del objeto de 
cursor
8. row_factory
Puede cambiar este atributo a un llamable que acepte el cursor y la fila original como una 
tupla y devolverá la fila del resultado real.
Funciones importantes del Cursor
1. execute(sql[, parameters])
    112/1068
    48
import sqlite3
conn = sqlite3.connect(":memory:") 
cur = conn.cursor()
cur.execute("create table people (name, age)")
who = "Sophia" 
age = 37
# This is the qmark style:
cur.execute("insert into people values (?, ?)", 
(who, age))
# And this is the named style:
cur.execute("select * from people where name=:who and age=:age",
{"who": who, "age": age}) # the keys correspond to the placeholdersin SQL
print(cur.fetchone())
L = [(1, 'abcd', 'dfj', 300), #A list oftuplesto be inserted into the database 
(2, 'cfgd', 'dyfj', 400),
(3, 'sdd', 'dfjh', 300.50)]
conn = sqlite3.connect("test1.db")
conn.execute("create table if not exists book (id int, name text, author text, price 
real)")
conn.executemany("insert into book values (?, ?, ?, ?)", L)
for row in conn.execute("select * from book"): 
print(row)
import sqlite3
class IterChars: 
def init (self):
self.count = ord('a')
def iter (self):
Ejecuta unasolasentenciaSQL.LadeclaraciónSQLpuede estarparametrizada (es decir, 
marcadores de posiciónenlugarde literales deSQL).El módulosqlite3 admite dos tipos de 
marcadores de posición:¿signos de interrogación ? ("Estilo de qmark") y marcadores de 
posición con :name ("estilo con nombre").
Cuidado: no utilice %s para insertar cadenas en los comandos SQL, ya que puede 
hacer que su programa sea vulnerable a un ataque de inyección de SQL (consulte 
Inyección de SQL ).
2. executemany(sql, seq_of_parameters)
Ejecuta un comando SQL contra todas las secuencias de parámetros o asignaciones 
encontradas en la secuencia sql. El módulo sqlite3 también permite usar un iterador para 
producir parámetros en lugar de una secuencia.
También puede pasar objetos de iterador como un parámetro a muchos, y la función se 
repetirá sobre cada tupla de valores que devuelve el iterador. El iterador debe devolver una 
tupla de valores.
    113/1068
    49
import sqlite3
conn = sqlite3.connect(":memory:") 
cur = conn.cursor() 
cur.executescript("""
create table person( 
firstname, 
lastname,
age
);
create table book( 
title,
author, 
published
);
insert into book(title, author, published) 
values (
'Dirk Gently''s Holistic Detective Agency', 
'Douglas Adams',
1987
); 
""")
3. executescript(sql_script)
Este es un método de conveniencia no estándar para ejecutar varias declaraciones SQL a la 
vez. Primero emite una instrucción COMMIT , luego ejecuta el script SQL que obtiene como 
parámetro.
sql_script puede ser una instancia de str o bytes .
El siguiente conjunto de funciones se usa junto con las SELECT en SQL. Para recuperar datos 
después de ejecutar una instrucción SELECT , puede tratar el cursor como un iterador, llamar 
al método fetchone() del cursor para recuperar una sola fila coincidente, o llamar a
fetchall() para obtener una lista de las filas correspondientes. 
Ejemplo de la forma iterador:
return (chr(self.count - 1),)
conn = sqlite3.connect("abc.db") 
cur = conn.cursor()
cur.execute("create table characters(c)")
theIter = IterChars()
cur.executemany("insert into characters(c) values (?)", theIter)
rows = cur.execute("select c from characters") 
for row in rows:
print(row[0]),
# (use next(self) for Python 2)
return self
def next (self):
if self.count > ord('z'): 
raise StopIteration
self.count += 1
    114/1068
    50
cur.execute('SELECT * FROM stocks ORDER BY price') 
i = cur.fetchone()
while(i):
print(i)
i = cur.fetchone()
# Output:
# ('2006-01-05', 'BUY', 'RHAT', 100, 35.14)
# ('2006-03-28', 'BUY', 'IBM', 1000, 45.0)
# ('2006-04-06', 'SELL', 'IBM', 500, 53.0)
# ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)
cur.execute('SELECT * FROM stocks ORDER BY price') 
print(cur.fetchmany(2))
# Output:
# [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM', 1000, 45.0)]
cur.execute('SELECT * FROM stocks ORDER BY price') 
print(cur.fetchall())
4. fetchone()
Obtiene la siguiente fila de un conjunto de resultados de consulta, devolviendo una 
secuencia única o Ninguno cuando no hay más datos disponibles.
5. fetchmany(size=cursor.arraysize)
Obtiene el siguiente conjunto de filas de un resultado de consulta (especificado por tamaño), 
devolviendo una lista. Si se omite el tamaño, fetchmany devuelve una sola fila. Se devuelve 
una lista vacía cuando no hay más filas disponibles.
6. fetchall()
Obtiene todas las filas (restantes) de un resultado de consulta, devolviendo una lista.
import sqlite3
stocks = [('2006-01-05', 'BUY', 'RHAT', 100, 35.14),
('2006-03-28', 'BUY', 'IBM', 1000, 45.0),
('2006-04-06', 'SELL', 'IBM', 500, 53.0),
('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)]
conn = sqlite3.connect(":memory:")
conn.execute("create table stocks (date text, buysell text, symb text, amount int, price 
real)")
conn.executemany("insert into stocks values (?, ?, ?, ?, ?)", stocks) 
cur = conn.cursor()
for row in cur.execute('SELECT * FROM stocks ORDER BY price'): 
print(row)
# Output:
# ('2006-01-05', 'BUY', 'RHAT', 100, 35.14)
# ('2006-03-28', 'BUY', 'IBM', 1000, 45.0)
# ('2006-04-06', 'SELL', 'IBM', 500, 53.0)
# ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)
    115/1068
    51
import psycopg2
# Establish a connection to the database.
# Replace parameter values with database credentials. 
conn = psycopg2.connect(database="testpython",
user="postgres", 
host="localhost", 
password="abc123", 
port="5432")
# Create a cursor. The cursor allows you to execute database queries. 
cur = conn.cursor()
# Create a table. Initialise the table name, the column names and data type. 
cur.execute("""CREATE TABLE FRUITS (
id INT,
fruit_name TEXT, 
color TEXT,
price REAL
)""")
conn.commit() 
conn.close()
Tipos de datos SQLite y Python
SQLite admite de forma nativa los siguientes tipos: NULL, INTEGER, REAL, TEXT, BLOB. 
Así es como se convierten los tipos de datos al pasar de SQL a Python o viceversa.
None <-> NULL
int <-> INTEGER/INT
float <-> REAL/FLOAT
str <-> TEXT/VARCHAR(n)
bytes <-> BLOB
Acceso a la base de datos PostgreSQL usando psycopg2
psycopg2 es el adaptador de base de datos PostgreSQL más popular que es ligero y eficiente. 
Es la implementación actual del adaptador PostgreSQL.
Sus características principales son la implementación completa de la especificación 
Python DB API 2.0 y la seguridad de subprocesos (varios subprocesos pueden 
compartir la misma conexión)
Estableciendo una conexión a la base de datos y creando 
una tabla.
# Output:
# [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM', 1000, 45.0),
('2006-04-06', 'SELL', 'IBM', 500, 53.0), ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)]
    116/1068
    52
# After creating the table as shown above, insert values into it. 
cur.execute("""INSERT INTO FRUITS (id, fruit_name, color, price)
VALUES (1, 'Apples', 'green', 1.00)""")
cur.execute("""INSERT INTO FRUITS (id, fruit_name, color, price) 
VALUES (1, 'Bananas', 'yellow', 0.80)""")
# Set up a query and execute it 
cur.execute("""SELECT id, fruit_name, color, price
FROM fruits""")
# Fetch the data 
rows = cur.fetchall()
# Do stuff with the data 
for row in rows:
print "ID = {} ".format(row[0])
print"FRUITNAME={}".format(row[1]) 
print("COLOR = {}".format(row[2]))
print("PRICE = {}".format(row[3]))
ID = 1
NAME = Apples 
COLOR = green 
PRICE = 1.0
ID = 2
NAME = Bananas 
COLOR = yellow 
PRICE = 0.8
Insertando datos en la tabla:
Recuperando datos de la tabla:
La salida de lo anterior sería:
Y así, ahí tienes, ¡ahora sabes la mitad de todo lo que necesitas saber sobre psycopg2 ! :)
Base de datos Oracle
Pre-requisitos:
• Paquete cx_Oracle - Vea aquí para todas las versiones
• Cliente instantáneo de Oracle - Para Windows x64 , Linux x64
Preparar:
• Instala el paquete cx_Oracle como:
sudo rpm -i <YOUR_PACKAGE_FILENAME>
    117/1068
    53
ORACLE_HOME=<PATH_TO_INSTANTCLIENT> 
PATH=$ORACLE_HOME:$PATH 
LD_LIBRARY_PATH=<PATH_TO_INSTANTCLIENT>:$LD_LIBRARY_PATH
import cx_Oracle
class OraExec(object):
_db_connection = None
_db_cur = None
def init (self): 
self._db_connection =
cx_Oracle.connect('<USERNAME>/<PASSWORD>@<HOSTNAME>:<PORT>/<SERVICE_NAME>')
self._db_cur = self._db_connection.cursor()
ver = con.version.split(".") 
print ver
_db_cur.execute("select * from employees order by emp_id") 
for result in _db_cur:
print result
_db_cur.execute("insert into employees(emp_id, title, dept, grade) 
values (31, 'MTS', 'ENGINEERING', 7)
_db_connection.commit()
• Extraiga el cliente instantáneo de Oracle y establezca las variables de entorno como:
Creando una conexión:
Obtener la versión de la base de datos:
Salida de muestra: ['12', '1', '0', '2', '0']
Ejecutar consulta: SELECCIONAR
La salida será en tuplas de Python:
(10, 'SYSADMIN', 'IT-INFRA', 7)
(23, 'HR ASSOCIATE', 'RECURSOS HUMANOS', 6)
Ejecutar consulta: INSERTAR
Cuando realiza operaciones de inserción / actualización / eliminación en una base de datos 
Oracle, los cambios solo están disponibles dentro de su sesión hasta commit se emita la commit . 
Cuando los datos actualizados se confirman en la base de datos, están disponibles para otros 
usuarios y sesiones.
Ejecutar consulta: INSERTAR utilizando variables Bind
Referencia
    118/1068
    54
rows = [ (1, "First" ),
(2,"Second"),
(3, "Third" ) ]
_db_cur.bindarraysize = 3
_db_cur.setinputsizes(int, 10)
_db_cur.executemany("insert into mytab(id, data) values (:1, :2)", rows)
_db_connection.commit()
_db_connection.close()
import MyDBAPI
con = MyDBAPI.connect(*database_dependent_args)
con.close()
con.commit()
Las variables de vinculación le permiten volver a ejecutar sentencias con nuevos valores, sin la 
sobrecarga de volver a analizar la sentencia. Las variables de enlace mejoran la reutilización del 
código y pueden reducir el riesgo de ataques de inyección de SQL.
Conexión cercana:
El método close () cierra la conexión. Cualquier conexión no cerrada explícitamente se liberará 
automáticamente cuando finalice el script.
Conexión
Creando una conexión
Según PEP 249, la conexión a una base de datos debe establecerse mediante un constructor 
connect() , que devuelve un objeto Connection . Los argumentos para este constructor son 
dependientes de la base de datos. Consulte los temas específicos de la base de datos para los 
argumentos relevantes.
Este objeto de conexión tiene cuatro métodos:
1: cerrar
Cierralaconexión al instante.Tenga en cuentaquela conexiónse cierraautomáticamente sise 
llama al método Connection. del . Todas las transacciones pendientes se revertirán 
implícitamente.
2: cometer
Se compromete cualquier transacción pendiente a la base de datos.
3: retroceso
    119/1068
    55
cur = con.cursor()
from sqlalchemy import create_engine 
from sqlalchemy.engine.url import URL
url = URL(drivername='mysql',
username='user', 
password='passwd', 
host='host', 
database='db')
engine = create_engine(url) # sqlalchemy engine
import pandas as pd
con = engine.connect()
dataframe = pd.read_sql(sql=query, con=con)
Retrocede al inicio de cualquier transacción pendiente. En otras palabras: esto cancela cualquier 
transacción no confirmada a la base de datos.
4: cursor
Devuelve un objeto Cursor . Esto se utiliza para hacer transacciones en la base de datos.
Usando sqlalchemy
Para usar sqlalchemy para la base de datos:
Ahora se puede usar este motor: por ejemplo, con pandas para obtener marcos de datos 
directamente desde mysql
con.rollback()
    120/1068
    56
import dis
def fib(n):
if n <= 2: return 1
return fib(n-1) + fib(n-2)
# Display the disassembled bytecode of the function. 
dis.dis(fib)
def fib(n):
if n <= 2: return 1
return fib(n-1) + fib(n-2) 
dir(fib. code )
def fib(n):
if n <= 2: return 1
return fib(n-1) + fib(n-2) 
dir(fib. code )
Capítulo 4: Acceso al código fuente y código 
de bytes de Python
Examples
Mostrar el bytecode de una función
El intérprete de Python compila el código a bytecode antes de ejecutarlo en la máquina virtual de 
Python (consulte también ¿Qué es el bytecode de python?) .
Aquí es cómo ver el código de bytes de una función de Python
La función dis.dis en el módulo dis devolverá un bytecode descompilado de la función que se le 
pasó.
Explorando el código objeto de una función.
CPython permite el acceso al objeto de código para un objeto de función.
El objeto code contiene el bytecode en bruto ( co_code ) de la función, así como otra 
información como constantes y nombres de variables.
Mostrar el código fuente de un objeto. 
Objetos que no están incorporados
Para imprimir el código fuente de un objeto Python use inspect . Tenga en cuenta que esto no 
funcionará para los objetos incorporados ni para los objetos definidos de forma interactiva. Para 
estos necesitarás otros métodos explicados más adelante.
    121/1068
    57
return self.randrange(a, b+1)
def randint(self, a, b):
"""Return random integer in range [a, b], including both end points. 
"""
# 
# 
# 
# 
#
import random 
import inspect
print(inspect.getsource(random.randint)) 
# Output:
print(inspect.getdoc(random.randint)) 
# Output:
# Return random integer in range [a, b], including both end points.
print(inspect.getfile(random.randint)) 
# c:\Python35\lib\random.py
print(random.randint. code .co_filename) # equivalent to the above 
# c:\Python35\lib\random.py
# define a new function in the interactive shell 
def add(a, b):
return a + b
print(add. code .co_filename) # Output: <stdin>
import dill
print dill.source.getsource(add) 
# def add(a, b):
return a + b
print(inspect.getsource(sorted)) # raises a TypeError 
type(sorted) # <class 'builtin_function_or_method'>
Aquí le mostramos cómo imprimir el código fuente del método randint desde el módulo random :
Para simplemente imprimir la cadena de documentación
Imprima la ruta completa del archivo donde se define el método random.randint :
Objetos definidos interactivamente.
Siunobjetoestádefinidodeformainteractiva,inspect nopuedeproporcionarelcódigofuente, 
pero puede usar dill.source.getsource en dill.source.getsource lugar
Objetos incorporados
El código fuente de las funciones incorporadas de Python está escrito en c y solo se puede 
acceder a él consultando el código fuente de Python (alojado en Mercurial o descargable desde 
https://www.python.org/downloads/source/) .
    122/1068
    58
    123/1068
    59
class Book:
def init (self, title, author): 
self.title = title 
self.author = author
book1 = Book(title="Right Ho, Jeeves", author="P.G. Wodehouse")
>>> book1.title 
'P.G. Wodehouse'
>>> book1.series
Traceback (most recent call last):
File "<stdin>", line 1, in<module>
AttributeError: 'Book' object has no attribute 'series'
class Book:
def init (self, title, author): 
self.title = title 
self.author = author
Capítulo 5: Acceso de atributo
Sintaxis
• x.title # Accesses the title attribute using the dot notation
• x.title = "Hello World" # Sets the property of the title attribute using the dot notation
• @property # Used as a decorator before the getter method for properties
• @title.setter # Used as a decorator before the setter method for properties
Examples
Acceso a atributos básicos utilizando la notación de puntos
Tomemos una clase de muestra.
En Python, puede acceder al título del atributo de la clase usando la notación de puntos.
Si un atributo no existe, Python lanza un error:
Setters, Getters & Properties
Por el bien de la encapsulación de datos, a veces desea tener un atributo cuyo valor proviene de 
otros atributos o, en general, qué valor se computará en el momento. La forma estándar de lidiar 
con esta situación es crear un método, llamado getter o setter.
En el ejemplo anterior, es fácil ver qué sucede si creamos un nuevo libro que contiene un título y 
un autor. Si todos los libros que vamos a agregar a nuestra biblioteca tienen autores y títulos, 
podemos omitir a los captadores y definidores y usar la notación de puntos. Sin embargo,
    124/1068
    60
class P:
def init (self,title,author): 
self.title = title 
self.setAuthor(author)
def get_author(self): 
return self.author
def set_author(self, author): 
if not author:
self.author = "Unknown" 
else:
self.author = author
>>> book = Book(title="Ancient Manuscript", author="Some Guy")
>>> book.author = "" #Cos Some Guy didn't write this one!
class Book:
def init (self, title, author): 
self.title = title 
self.author = author
@property
def author(self): 
return self. author
@author.setter
def author(self, author): 
if not author:
self.author = "Unknown" 
else:
self.author = author
supongamos que tenemos algunos libros que no tienen un autor y queremos que el autor sea 
"Desconocido". O si tienen varios autores y planeamos devolver una lista de autores.
En este caso, podemos crear un getter y un setter para el atributo de autor .
Este esquema no es recomendable.
Una razón es que hay un problema: supongamos que hemos diseñado nuestra clase con el 
atributo público y sin métodos. La gente ya lo ha usado mucho y ha escrito un código como este:
Ahora tenemos un problema. ¡Porque el autor no es un atributo! Python ofrece una solución a 
este problema llamado propiedades. Un método para obtener propiedades está decorado con la 
propiedad @ antes de su encabezado. El método que queremos que funcione como configurador 
está decorado con @ attributeName.setter anterior.
Teniendo esto en cuenta, ahora tenemos nuestra nueva clase actualizada.
Tenga en cuenta que normalmente Python no le permite tener varios métodos con el mismo 
nombre y diferente número de parámetros. Sin embargo, en este caso Python lo permite debido a 
los decoradores utilizados.
    125/1068
    61
>>> book = Book(title="Ancient Manuscript", author="Some Guy")
>>> book.author = "" #Cos Some Guy didn't write this one!
>>> book.author 
Unknown
Si probamos el código:
    126/1068
    62
s = 'AAAABBBCCDAABBB'
s = 'AAAABBBCCDAABBB'
s_dict = {} 
for i in s:
if i not in s_dict.keys():
Capítulo 6: agrupar por()
Introducción
En Python, el método itertools.groupby() permite a los desarrolladores agrupar los valores de 
una clase iterable basándose en una propiedad específica en otro conjunto de valoresiterables.
Sintaxis
• itertools.groupby (iterable, key = None o alguna función)
Parámetros
Parámetro Detalles
iterable Cualquier pitón iterable
llave Función (criterios) sobre la cual agrupar lo iterable.
Observaciones
groupby () es complicado pero una regla general a tener en cuenta al usarlo es la siguiente:
Ordene siempre los elementos que desea agrupar con la misma clave que desea utilizar 
para agrupar
Se recomienda que el lector revise la documentación aquí y vea cómo se explica utilizando una 
definición de clase.
Examples
Ejemplo 1
Di que tienes la cuerda
y te gustaría dividirlo para que todas las 'A' estén en una lista y así con todas las 'B' y 'C', etc. 
Podrías hacer algo como esto
    127/1068
    63
{'A': ['A', 'A', 'A', 'A', 'A', 'A'],
'B': ['B', 'B', 'B', 'B', 'B', 'B'], 
'C': ['C', 'C'],
'D': ['D']}
# note that we get a {key : value} pair for iterating over the items just like in python 
dictionary
from itertools import groupby 
s ='AAAABBBCCDAABBB'
c = groupby(s)
dic = {}
for k, v in c: 
dic[k] = list(v)
dic
{'A': ['A', 'A'], 'B': ['B', 'B', 'B'], 'C': ['C', 'C'], 'D': ['D']}
c = groupby(sorted(s))
dic = {}
for k, v in c: 
dic[k] = list(v)
dic
{'A': ['A', 'A', 'A', 'A', 'A', 'A'], 'B': ['B', 'B', 'B', 'B', 'B', 'B'], 'C': ['C', 'C'], 
'D': ['D']}
Resultados en
Pero para un conjunto de datos de gran tamaño, estaría acumulando estos elementos en la 
memoria. Aquí es donde entra groupby ()
Podríamos obtener el mismo resultado de una manera más eficiente haciendo lo siguiente
Resultados en
Observe que el número de 'A's en el resultado cuando usamos group by es menor que el número 
real de' A's en la cadena original. Podemos evitar esa pérdida de información ordenando los 
elementos en s antes de pasarlos a c como se muestra a continuación
Resultados en
Ahora tenemos todas nuestras 'A's.
Ejemplo 2
s_dict[i] = [i] 
else:
s_dict[i].append(i)
s_dict
    128/1068
    64
c = groupby(['goat', 'dog', 'cow', 1, 1, 2, 3, 11, 10, ('persons', 'man', 'woman')]) 
dic = {}
for k, v in c: 
dic[k] = list(v)
dic
{1: [1, 1],
2: [2],
3: [3],
('persons', 'man', 'woman'): [('persons', 'man', 'woman')], 
'cow': ['cow'],
'dog': ['dog'], 
10: [10],
11: [11],
'goat': ['goat']}
list_things = ['goat', 'dog', 'donkey', 'mulato', 'cow', 'cat', ('persons', 'man', 'woman'), \
'wombat', 'mongoose', 'malloo', 'camel']
c = groupby(list_things, key=lambda x: x[0]) 
dic = {}
for k, v in c: 
dic[k] = list(v)
dic
{'c': ['camel'],
'd': ['dog', 'donkey'],
'g': ['goat'],
'm': ['mongoose', 'malloo'],
'persons': [('persons', 'man', 'woman')], 
'w': ['wombat']}
list_things = ['goat', 'dog', 'donkey', 'mulato', 'cow', 'cat', ('persons', 'man', 'woman'), \
'wombat', 'mongoose', 'malloo', 'camel']
sorted_list = sorted(list_things, key = lambda x: x[0]) 
print(sorted_list)
print()
Este ejemplo ilustra cómo se elige la clave predeterminada si no especificamos ninguna
Resultados en
Observe aquí que la tupla en su conjunto cuenta como una clave en esta lista
Ejemplo 3
Note en este ejemplo que mulato y camello no aparecen en nuestro resultado. Sólo se muestra el 
último elemento con la clave especificada. El último resultado para c en realidad borra dos 
resultados anteriores. Pero mira la nueva versión donde tengo los datos ordenados primero en la 
misma clave.
Resultados en
Versión ordenada
    129/1068
    65
['cow', 'cat', 'camel', 'dog', 'donkey', 'goat', 'mulato', 'mongoose', 'malloo', ('persons', 
'man', 'woman'), 'wombat']
{'c': ['cow', 'cat', 'camel'],
'd': ['dog', 'donkey'],
'g': ['goat'],
'm': ['mulato', 'mongoose', 'malloo'],
'persons': [('persons', 'man', 'woman')], 
'w': ['wombat']}
things = [("animal", "bear"), ("animal", "duck"), ("plant", "cactus"), ("vehicle", "harley"),
\
("vehicle", "speed boat"), ("vehicle", "school bus")]
dic = {}
f = lambda x: x[0]
for key, group in groupby(sorted(things, key=f), f): 
dic[key] = list(group)
dic
{'animal': [('animal', 'bear'), ('animal', 'duck')], 
'plant': [('plant', 'cactus')],
'vehicle': [('vehicle', 'harley'), 
('vehicle', 'speed boat'),
('vehicle', 'school bus')]}
things = [["animal", "bear"], ["animal", "duck"], ["vehicle", "harley"], ["plant", "cactus"],
\
["vehicle", "speed boat"], ["vehicle", "school bus"]]
dic = {}
f = lambda x: x[0]
for key, group in groupby(sorted(things, key=f), f): 
dic[key] = list(group)
dic
Resultados en
Ejemplo 4
En este ejemplo, vemos lo que sucede cuando usamos diferentes tipos de iterable.
Resultados en
Este ejemplo a continuación es esencialmente el mismo que el de arriba. La única diferencia es 
que he cambiado todas las tuplas a listas.
Resultados
c = groupby(sorted_list, key=lambda x: x[0]) 
dic = {}
for k, v in c: 
dic[k] = list(v)
dic
    130/1068
    66
{'animal': [['animal', 'bear'], ['animal', 'duck']], 
'plant': [['plant', 'cactus']],
'vehicle': [['vehicle', 'harley'], 
['vehicle', 'speed boat'],
['vehicle', 'school bus']]}
    131/1068
    67
read_x_local_fail() # UnboundLocalError: local variable 'x' referenced before assignment
def read_x_local_fail(): 
if False:
x = 'Hey' # x appears in an assignment, therefore it's local
print(x) # will look for the _local_ z, which is not assigned, and will not be found
read_y() # prints Hey
def read_y():
y = 'Hey' # y appears in an assignment, therefore it's local
print(y) # will find the local y
read_y() #NameError: global name 'y' is not defined
def read_y():
print(y) # here y is just referenced, therefore assumed global
read_x() # prints Hi
x = 'Hi'
def read_x():
print(x) # x is just referenced, therefore assumed global
Capítulo 7: Alcance variable y vinculante
Sintaxis
• global a, b, c
• no local a, b
• x = algo # se une a x
• (x, y) = algo # une x y y
• x + = algo # se une a x. Del mismo modo para todos los demás "op ="
• del x # se une a x
• para x en algo: # se une a x
• con algo como x: # une x
• excepto Excepción como ex: # binds ex inside block
Examples
Variables globales
En Python, las variables dentro de las funciones se consideran locales si y solo si aparecen en el 
lado izquierdo de una instrucción de asignación, o alguna otra ocurrencia de enlace; de lo 
contrario, tal enlace se busca en las funciones adjuntas, hasta el alcance global. Esto es cierto 
incluso si la instrucción de asignación nunca se ejecuta.
Normalmente, una asignación dentro de un ámbito sombreará las variables externas del mismo 
nombre:
    132/1068
    68
x = 'Hi'
def change_global_x(): 
global x
x = 'Bye' 
print(x)
change_global_x() # prints Bye 
print(x) # prints Bye
def foo():
a = 5 
print(a) # ok
print(a) # NameError: name 'a' is not defined
def foo():
if True:
a = 5
Declarar un nombre global significa que, para el resto del alcance, cualquier asignación al nombre 
ocurrirá en el nivel superior del módulo:
La palabra clave global significa que las asignaciones se realizarán en el nivel superior del 
módulo, no en el nivel superior del programa. Otros módulos seguirán necesitando el acceso 
puntual habitual a las variables dentro del módulo.
Para resumir: para saber si una variable x es local a una función, debe leer la función completa :
1. Si has encontrado global x , entonces x es una variable global
2. Si ha encontrado nonlocal x , entonces x pertenece a una función que lo encierra, y no es 
local ni global
3. Si ha encontrado x = 5 o for x in range(3) o algún otro enlace, entonces x es una variable
local
4. De lo contrario, x pertenece a algún ámbito adjunto (ámbito de función, ámbito global o 
elementos incorporados)
Variables locales
Si un nombre está enlazado dentro de una función, por defecto es accesible solo dentro de la 
función:
Las construcciones de flujo de control no tienen impacto en el alcance (con la excepción de except
), pero el acceso a la variable que aún no se asignó es un error:
x = 'Hi'
def change_local_x(): 
x = 'Bye' 
print(x)
change_local_x() # prints Bye 
print(x) # prints Hi
    133/1068
    69
def counter():
num = 0
def incrementer(): 
num += 1 
return num
return incrementer
def counter():
num = 0
def incrementer(): 
nonlocal num 
num += 1 
return num
return incrementer
c = counter() 
c() # = 1
c() # = 2
c() # = 3
Lasoperacionesdeenlacecomunes sonasignaciones, for bucles yasignacionesaumentadas, 
como a += 5
Variables no locales
Python 3.x 3.0
Python 3 agregó una nueva palabra clave llamada no local . La palabra clave no local agrega una 
anulación de ámbito al ámbito interno. Puedes leer todo sobre esto en PEP 3104 . Esto se ilustra 
mejor con un par de ejemplos de código. Uno de los ejemplos más comunes es crear una función 
que puede incrementar:
Si intenta ejecutar este código, recibirá un UnboundLocalError porque se hace referencia a la 
variable num antes de que se asigne en la función más interna. Añadamos nonlocal a la mezcla:
Básicamente, nonlocal le permitirá asignar variables en un ámbito externo, pero no global. Porlo 
tanto, no puede usar el modo no nonlocal en nuestra función de counter porque entonces 
intentaría asignarlo a un alcance global. SyntaxError y obtendrá rápidamente un SyntaxError . En 
su lugar, debe utilizar nonlocal en una función anidada.
(Tenga en cuenta que la funcionalidad que se presenta aquí se implementa mejor utilizando 
generadores).
Ocurrencia vinculante
print(a) # ok
b = 3
def bar():
ifFalse:
b = 5
print(b) # UnboundLocalError: local variable 'b' referenced before assignment
    134/1068
    70
a = 'global'
class Fred:
a = 'class' # class scope
b = (a for i in range(10)) # function scope 
c = [a for i in range(10)] # function scope 
d = a # classscope
e = lambda: a # function scope
f = lambda a=a: a # default argument uses class scope
@staticmethod # or @classmethod, or regular instance method 
def g(): # function scope
return a
print(Fred.a) # class 
print(next(Fred.b)) # global
print(Fred.c[0]) # class in Python 2, global in Python 3 
print(Fred.d) # class
print(Fred.e()) # global 
print(Fred.f()) # class 
print(Fred.g()) # global
Cada una de las afirmaciones anteriores es una ocurrencia de enlace : x se une al objeto 
denotado por 5 . Si esta declaración aparece dentro de una función, entonces x será función local 
de forma predeterminada. Consulte la sección "Sintaxis" para obtener una lista de declaraciones 
vinculantes.
Las funciones omiten el alcance de la clase al buscar nombres
Las clases tienen un alcance local durante la definición, pero las funciones dentro de la clase no 
usan ese alcance cuando buscan nombres. Debido a que las lambdas son funciones, y las 
comprensiones se implementan utilizando el alcance de la función, esto puede llevar a un 
comportamiento sorprendente.
Losusuarios quenoesténfamiliarizadoscon elfuncionamientodeeste ámbitopueden esperar 
que b , c y e impriman la class .
Desde PEP 227 :
Los nombres en el alcance de la clase no son accesibles. Los nombres se resuelven 
en el ámbito de la función de cierre más interno. Si una definición de clase se produce 
en una cadena de ámbitos anidados, el proceso de resolución omite las definiciones 
de clase.
De la documentación de Python sobre denominación y encuadernación :
El alcance de los nombres definidos en un bloque de clase se limita al bloque de 
clase; no se extiende a los bloques de código de los métodos; esto incluye
x = 5
x += 7
for x in iterable: pass
    135/1068
    71
class A:
a = 42
b = list(a + i for i in range(10))
x = 5
print(x) # out: 5 
del x
print(x) # NameError: name 'f' is not defined
class A:
pass
a = A()
a.x = 7
print(a.x) # out: 7 
del a.x
print(a.x) # error: AttributeError: 'A' object has no attribute 'x'
comprensiones y expresiones generadoras, ya que se implementan utilizando un 
ámbito de función. Esto significa que lo siguiente fallará:
Este ejemplo utiliza referencias de esta respuesta de Martijn Pieters, que contiene un análisis más 
profundo de este comportamiento.
El comando del
Este comando tiene varias formas relacionadas pero distintas.
del v
Si v es una variable, el comando del v elimina la variable de su alcance. Porejemplo:
Tenga en cuenta que del es una ocurrencia de enlace , lo que significa que a menos 
que se establezca explícitamente lo contrario (utilizando nonlocal o global ), del v hará 
que v local al alcance actual. Si pretende eliminar v en un ámbito externo, use nonlocal 
v o global v en el mismo ámbito de la declaración del v .
En todo lo siguiente, la intención de un comando es un comportamiento predeterminado, pero el 
idioma no lo impone. Una clase puede estar escrita de una manera que invalida esta intención.
del v.name
Este comando activa una llamada a v. delattr (name) .
La intención es hacer que el name del atributo no esté disponible. Por ejemplo:
del v[item]
Este comando activa una llamada a v. delitem (item) .
    136/1068
    72
x = {'a': 1, 'b': 2}
del x['a']
print(x) # out: {'b': 2}
print(x['a']) # error: KeyError: 'a'
x = [0, 1, 2, 3, 4]
del x[1:3]
print(x) # out: [0, 3, 4]
foo = 1 # global
def func():
bar = 2 # local
print(foo) # prints variable foo from global scope 
print(bar) # prints variable bar from local scope
foo = 1
def func():
bar = 2
print(globals().keys()) # prints all variable names in global scope 
print(locals().keys()) # prints all variable names in local scope
La intención es que el item no pertenezca a la asignación implementada por el objeto v .Por 
ejemplo:
del v[a:b]
Esto realmente llama v. delslice (a, b) .
La intención es similar a la descrita anteriormente, pero con cortes: rangos de elementos en lugar 
de un solo elemento. Por ejemplo:
Véase también Recolección de basura # El comando del .
Ámbito local vs global
¿Cuáles son el alcance local y global?
Todos los variabes de Python a los que se puede acceder en algún punto del código se 
encuentran en el ámbito local o global .
La explicación es que el alcance local incluye todas las variables definidas en la función actual y 
el alcance global incluye variables definidas fuera de la función actual.
Uno puede inspeccionar qué variables están en qué alcance. Las funciones integradas locals() y
globals() devuelven todos los ámbitos como diccionarios.
    137/1068
    73
foo = 1
def func():
foo = 2 # creates a new variable foo in local scope, global foo is not affected 
print(foo) # prints 2
# global variable foo still exists, unchanged: 
print(globals()['foo']) # prints 1 
print(locals()['foo']) # prints 2
foo = 1
def func():
global foo
foo = 2 # this modifies the global foo, rather than creating a local variable
foo = 1
def func():
# This function has a local variable foo, because it is defined down below. 
# So, foo is local from this point. Global foo is hidden.
print(foo) # raises UnboundLocalError, because local foo is not yet initialized 
foo = 7
print(foo)
foo = 1
def func():
# In this function, foo is a global variable from the begining 
foo = 7 # global foo is modified
print(foo) # 7
print(globals()['foo']) # 7
global foo # this could be anywhere within the function 
print(foo) # 7
¿Qué pasa con los choques de nombre?
Para modificar una variable global, use la palabra clave global :
El alcance se define para todo el cuerpo de la función!
Lo que significa es que una variable nunca será global para la mitad de la función y local después, 
o viceversa.
Asimismo, el opuesto:
Funciones dentro de funciones
    138/1068
    74
foo = 1
def f1():
bar = 1
def f2():
baz = 2
# here, foo is a global variable, baz is a local variable 
# bar is not in either scope
print(locals().keys()) # ['baz'] 
print('bar' in locals())# False 
print('bar' in globals()) # False
def f3():
baz = 3
print(bar) # bar from f1 is referenced so it enters local scope of f3 (closure) 
print(locals().keys()) # ['bar', 'baz']
print('bar' in locals()) # True 
print('bar' in globals()) # False
def f4():
bar = 4 # a new local bar which hides bar from local scope of f1 
baz = 4
print(bar)
print(locals().keys()) # ['bar', 'baz'] 
print('bar' in locals()) # True 
print('bar' in globals()) # False
foo = 0 # global foo
def f1():
foo = 1 # a new foo local in f1
def f2():
foo = 2 # a new foo local in f2
def f3():
foo = 3 # a new foo local in f3 
print(foo) # 3
foo = 30 # modifies local foo in f3 only
def f4():
global foo 
print(foo) # 0
foo = 100 # modifies global foo
Puede haber muchos niveles de funciones anidadas dentro de las funciones, pero dentro de una 
función solo hay un ámbito local para esa función y el ámbito global. No hay ámbitos intermedios.
global vs nonlocal (solo Python 3)
Estas dos palabras clave se utilizan para obtener acceso de escritura a variables que no son 
locales a las funciones actuales.
La palabra clave global declara que un nombre debe tratarse como una variable global.
    139/1068
    75
def f1():
def f2():
foo = 2 # a new foo local in f2
def f3():
nonlocal foo # foo from f2, which is the nearest enclosing scope 
print(foo) # 2
foo = 20 # modifies foo from f2!
Por otro lado, nonlocal (consulte Variables no locales ), disponible en Python 3, toma una variable
local de un ámbito de inclusión en el ámbito local de la función actual. 
De la documentación de Python en nonlocal :
La declaración no local hace que los identificadores enumerados se refieran a 
variables previamente vinculadas en el ámbito envolvente más cercano, excluyendo 
las globales.
Python 3.x 3.0
    140/1068
    76
from PIL import Image
im = Image.open("Image.bmp")
from future import print_function 
import os, sys
from PIL import Image
for infile in sys.argv[1:]:
f, e = os.path.splitext(infile) 
outfile = f + ".jpg"
if infile != outfile: 
try:
Image.open(infile).save(outfile) 
except IOError:
print("cannot convert", infile)
Capítulo 8: Almohada
Examples
Leer archivo de imagen
Convertir archivos a JPEG
    141/1068
    77
def switch(value): 
if value == 1:
return "one" 
if value == 2:
return "two" 
if value == 42:
return "the answer to the question about life, the universe and everything" 
raise Exception("No case found!")
>>> switch(1) 
one
>>> switch(2) 
two
>>> switch(3)
…
Exception: No case found!
>>> switch(42)
the answer to the question about life the universe and everything
Capítulo 9: Alternativas para cambiar la 
declaración de otros idiomas
Observaciones
No hay ninguna instrucción de cambio en python como opción de diseño de idioma. Ha habido un 
PEP ( PEP-3103 ) que cubre el tema que ha sido rechazado.
Puede encontrar muchas listas de recetas sobre cómo hacer sus propias declaraciones de 
cambio en python, y aquí estoy tratando de sugerir las opciones más sensatas. Aquí hay algunos 
lugares para comprobar:
• http://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python
• http://code.activestate.com/recipes/269708-some-python-style-switches/
• http://code.activestate.com/recipes/410692-readable-switch-construction-without-lambdasor-di/
• ...
Examples
Usa lo que el lenguaje ofrece: la construcción if / else.
Bueno,siquieresunconstructodeswitch /case,laformamásdirectadehacerloesusarelviejoy 
bueno if / else construye:
Puede parecer redundante, y no siempre bonito, pero esa es, con diferencia, la forma más 
eficiente de hacerlo, y hace el trabajo:
    142/1068
    78
switch = {
1: lambda: 'one',
2: lambda: 'two',
42: lambda: 'the answer of life the universe and everything',
}
def default_case():
raise Exception('No case found!')
>>> switch.get(1, default_case)() 
one
>>> switch.get(2, default_case)() 
two
>>> switch.get(3, default_case)()
…
Exception: No case found!
>>> switch.get(42, default_case)()
the answer of life the universe and everything
def run_switch(value):
return switch.get(value, default_case)()
>>> run_switch(1) 
one
class SwitchBase:
def switch(self, case):
m = getattr(self, 'case_{}'.format(case), None) 
if not m:
return self.default 
return m
Usa un dictado de funciones.
Otra forma directa de hacerlo es crear un diccionario de funciones:
a continuación, agrega una función predeterminada:
yutilizael método get del diccionario para obtenerla función dado el valor para verificarlo y 
ejecutarlo. Si el valor no existe en el diccionario, entonces se ejecuta default_case .
También puedes hacer un poco de azúcar sintáctico para que el interruptor se vea mejor:
Usa la introspección de clase.
Puedes usar una clase para imitar la estructura del conmutador / caso. Lo siguiente es usar la 
introspección de una clase (usar la función getattr() que resuelve una cadena en un método 
enlazado en una instancia) para resolver la parte del "caso".
Luego,esemétododeintrospecciónse call método call para sobrecargar al operador ()
.
    143/1068
    79
class CustomSwitcher:
def case_1(self):
return 'one'
def case_2(self): 
return 'two'
def case_42(self):
return 'the answer of life, the universe and everything!'
def default(self):
raise Exception('Not a case!')
>>> switch = CustomSwitcher()
>>>print(switch(1)) 
one
>>> print(switch(2)) 
two
>>> print(switch(3))
…
Exception: Not a case!
>>> print(switch(42))
the answer of life, the universe and everything!
class Switch:
def init (self, value): 
self._val = value
def enter (self): 
return self
def exit (self, type, value, traceback): 
return False # Allows traceback to occur
def call (self, cond, *mconds): 
return self._val in (cond,)+mconds
def run_switch(value):
with Switch(value) as case:
Luego, para que se vea mejor, subclasificamos la clase SwitchBase (pero podría hacerse en una 
clase), y ahí definimos todos los case como métodos:
así que finalmente podemos usarlo:
Usando un administrador de contexto
Otra forma, que es muy legible y elegante, pero mucho menos eficiente que una estructura if / 
else, es construir una clase como la siguiente, que leerá y almacenará el valor para comparar, 
exponerse dentro del contexto como un reclamo que devolverá verdadero si coincide con el valor 
almacenado:
luego, definir los casos es casi una coincidencia con el constructo de switch / case real (expuesto 
dentro de una función a continuación, para que sea más fácil presumir):
 call = switch
    144/1068
    80
>>> run_switch(1) 
one
>>> run_switch(2) 
two
>>> run_switch(3)
…
Exception: Not a case!
>>> run_switch(42)
the answer to the question about life, the universe and everything
Entonces la ejecución sería:
Nota Bene :
• Esta solución se ofrece como el módulo de conmutación disponible en pypi .
if case(1):
return 'one' 
if case(2):
return 'two' 
if case(3):
return 'the answer to the question about life, the universe and everything' 
# default
raise Exception('Not a case!')
    145/1068
    81
pip install virtualenv
apt-get install python-virtualenv
$ cd test_proj
$ virtualenv test_proj
$ source test_project/bin/activate
$ deactivate
Capítulo 10: Ambiente Virtual Python -
virtualenv
Introducción
Un entorno virtual ("virtualenv") es una herramienta para crear entornos aislados de Python. 
Mantiene las dependencias requeridas por los diferentes proyectos en lugares separados, 
mediante la creación de env de Python virtual para ellos. Resuelve el "proyecto A depende de la 
versión 2.xxx pero, el proyecto B necesita 2.xxx" dilema, y mantiene el directorio de paquetes de 
sitio global limpio y manejable.
"virtualenv" crea una carpeta que contiene todas las librerías y contenedores necesarios para 
usar los paquetes que un proyecto de Python necesitaría.
Examples
Instalación
Instale virtualenv a través de pip / (apt-get):
O
Nota: En caso de que tengas problemas con los permisos, usa sudo.
Uso
Crear entorno virtual:
Para comenzar a utilizar el entorno virtual, debe activarse:
Para salir de su virtualenv simplemente escriba "desactivar":
    146/1068
    82
$ source test_project/bin/activate
$ pip install flask
Instala un paquete en tu Virtualenv
Si observa el directorio bin en su virtualenv, verá que easy_install se ha modificado para poner 
huevos y paquetes en el directorio depaquetes de sitio virtualenv. Para instalar una aplicación en 
su entorno virtual:
En este momento, no tiene que usar sudo ya que todos los archivos se instalarán en el directorio 
local de virtualenv site-packages. Esto fue creado como su propia cuenta de usuario.
Otros comandos virtuales útiles
lsvirtualenv : Listar todos los entornos.
cdvirtualenv : navegue en el directorio del entorno virtual actualmente activado, para que pueda 
navegar por sus paquetes de sitios, por ejemplo.
cdsitepackages : como el anterior, pero directamente en el directorio de paquetes de sitio.
lssitepackages : muestra los contenidos del directorio site-packages.
    147/1068
    83
import argparse
parser = argparse.ArgumentParser() 
parser.add_argument('name',
help='name of user'
)
parser.add_argument('-g', '--greeting', 
default='Hello',
help='optional alternate greeting'
)
args = parser.parse_args() 
print("{greeting}, {name}!".format(
greeting=args.greeting, 
name=args.name)
)
-g GREETING, --greeting GREETING
optional alternate greeting
show this help message and exit
optional arguments:
-h, --help
$ python hello.py --help
usage: hello.py [-h] [-g GREETING] name
positional arguments:
name name of user
Capítulo 11: Análisis de argumentos de línea 
de comandos
Introducción
La mayoría de las herramientas de línea de comandos se basan en argumentos pasados al 
programa en su ejecución. En lugar de solicitar una entrada, estos programas esperan que se 
establezcan datos o indicadores específicos (que se convierten en valores booleanos). Esto 
permite que tanto el usuario como otros programas ejecuten el archivo Python pasándole los 
datos a medida que se inician. Esta sección explica y demuestra la implementación y el uso de 
los argumentos de la línea de comandos en Python.
Examples
Hola mundo en argparse
El siguiente programa dice hola al usuario. Toma un argumento posicional, el nombre del usuario, 
y también se le puede decir el saludo.
    148/1068
    84
if name == " main ": 
args= docopt( doc )
import pprint; pprint.pprint(args)
from docopt import docopt
Print all the things.
Get more bees into the path.
Options:
-a
-b
"""
"""
Usage:
script_name.py [-a][-b] <path>
$ python script_name.py 
Usage:
script_name.py [-a] [-b] <path>
$ python script_name.py something
{'-a': False,
'-b': False,
'<path>': 'something'}
$ python script_name.py something -a
{'-a': True,
'-b': False,
'<path>': 'something'}
$ python script_name.py -b something -a
{'-a': True,
'-b':True,
'<path>': 'something'}
import argparse
Para más detalles por favor lea la documentación argparse .
Ejemplo básico con docopt.
docopt convierte el argumento de la línea de comando analizando en su cabeza. En lugar de 
analizar los argumentos, simplemente escriba la cadena de uso para su programa, y docopt 
analiza la cadena de uso y la utiliza para extraer los argumentos de la línea de comandos.
Ejecuciones de muestra:
Estableciendo argumentos mutuamente excluyentes con argparse
Siquieresquedoso másargumentos seanmutuamenteexcluyentes.Puedeutilizarlafunción 
argparse.ArgumentParser.add_mutually_exclusive_group() . En el siguiente ejemplo, pueden existir 
foo o bar, pero no ambos al mismotiempo.
$ python hello.py world 
Hello, world!
$ python hello.py John -g Howdy 
Howdy, John!
    149/1068
    85
# cli.py 
import sys
print(sys.argv)
$ python cli.py
=> ['cli.py']
$ python cli.py fizz
=> ['cli.py', 'fizz']
$ python cli.py fizz buzz
=> ['cli.py', 'fizz', 'buzz']
import getpass 
import sys
words = sys.argv[1:] 
sentence = " ".join(words)
print("[%s] %s" % (getpass.getuser(), sentence))
Si intenta ejecutar el script especificando los argumentos --foo y --bar , el script se quejará con el 
mensaje a continuación.
error: argument -b/--bar: not allowed with argument -f/--foo
Usando argumentos de línea de comando con argv
Cada vez que se invoca un script de Python desde la línea de comandos, el usuario puede 
proporcionar argumentos de línea de comandos adicionales que se pasarán al script. Estos 
argumentos estarán disponibles para el programador de la variable del sistema sys.argv ( "argv" 
es un nombre tradicional utilizado en la mayoría de los lenguajes de programación, y significa 
"arg ument v ector").
Por convención, el primer elemento de la lista sys.argv es el nombre de la secuencia de 
comandos de Python, mientras que el resto de los elementos son los tokens que el usuariopasa 
al invocar la secuencia de comandos.
Aquí hay otro ejemplo de cómo usar argv . Primero eliminamos el elemento inicial de sys.argv 
porque contiene el nombre del script. Luego combinamos el resto de los argumentos en una sola 
oración,y finalmenteimprimimosesaoración antesdel nombredel usuarioquehainiciado sesión 
(para que emule un programa de chat).
El algoritmo comúnmente utilizado cuando se analiza "manualmente" un número de argumentos 
no posicionales es iterar sobre la lista sys.argv . Una forma es repasar la lista y resaltar cada 
elemento de la misma:
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group() 
group.add_argument("-f", "--foo")
group.add_argument("-b", "--bar") 
args = parser.parse_args()
print "foo = ", args.foo 
print "bar = ", args.bar
    150/1068
    86
import argparse
parser = argparse.ArgumentParser() 
parser.add_argument("-f", "--foo")
parser.add_argument("-b", "--bar") 
args = parser.parse_args()
if args.foo and args.bar is None:
parser.error("--foo requires --bar. You did not specify bar.")
print "foo =", args.foo 
print "bar =", args.bar
usage: sample.py [-h] [-f FOO] [-b BAR]
sample.py: error: --foo requires --bar. You did not specify bar.
import argparse
Mensaje de error del analizador personalizado con argparse
Puede crear mensajes deerror del analizadorde acuerdo con las necesidades de su script.Esto 
es a través de la función argparse.ArgumentParser.error . El siguiente ejemplo muestra la 
secuencia de comandosimprimiendo unusoyunmensaje de error astderr cuandose --foo pero 
no --bar .
Asumiendoqueelnombredesuscriptessample.py,yejecutamos: python sample.py --foo 
ds_in_fridge
El guión se quejará con lo siguiente:
Agrupación conceptual de argumentos con argparse.add_argument_group ()
Cuandocrea un argparseArgumentParser() yejecuta su programa con'-h',recibe un mensajede 
uso automático que explica con qué argumentos puede ejecutar su software. De forma 
predeterminada, los argumentos posicionales y los argumentos condicionales están separados en 
doscategorías, porejemplo, aquíhay un pequeñoscript (example.py) y el resultado cuando 
ejecuta python example.py -h .
# reverse and copy sys.argv 
argv = reversed(sys.argv)
# extract the first element 
arg = argv.pop()
# stop iterating when there's no more args to pop() 
while len(argv) > 0:
if arg in ('-f', '--foo'): 
print('seen foo!')
elif arg in ('-b', '--bar'): 
print('seen bar!')
elif arg in ('-a', '--with-arg'): 
arg = arg.pop()
print('seen value: {}'.format(arg)) 
# get the next value
arg = argv.pop()
    151/1068
    87
usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
[--foo_this FOO_THIS] [--foo_that FOO_THAT] 
name
Simple example 
positional arguments:
name Who to greet
optional arguments:
-h, --help show this help message and exit
--bar_this BAR_THIS
--bar_that BAR_THAT
--foo_this FOO_THIS
--foo_that FOO_THAT
import argparse
parser = argparse.ArgumentParser(description='Simple example') 
parser.add_argument('name', help='Who to greet', default='World') 
# Create two argument groups
foo_group = parser.add_argument_group(title='Foo options') 
bar_group = parser.add_argument_group(title='Bar options') 
# Add arguments to those groups
foo_group.add_argument('--bar_this') 
foo_group.add_argument('--bar_that') 
bar_group.add_argument('--foo_this') 
bar_group.add_argument('--foo_that') 
args = parser.parse_args()
show this help message and exit
optional arguments:
-h, --help
usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
[--foo_this FOO_THIS] [--foo_thatFOO_THAT] 
name
Simple example 
positional arguments:
name Who to greet
Hay algunas situaciones en las que desea separar sus argumentos en secciones conceptuales 
adicionales para ayudar a su usuario. Por ejemplo, es posible que desee tener todas las opciones 
de entrada en un grupo y todas las opciones de formato de salida en otro. El ejemplo anterior se 
puede ajustar para separar los --foo_* de los --bar_* así.
Que produce esta salida cuando se ejecuta python example.py -h :
parser = argparse.ArgumentParser(description='Simple example') 
parser.add_argument('name', help='Who to greet', default='World') 
parser.add_argument('--bar_this')
parser.add_argument('--bar_that') 
parser.add_argument('--foo_this') 
parser.add_argument('--foo_that') 
args = parser.parse_args()
    152/1068
    88
"""Run something in development or production mode.
Usage: run.py --development <host> <port> 
run.py --production <host> <port> 
run.py items add <item>
run.py items delete <item>
"""
from docopt_dispatch import dispatch
@dispatch.on('--development')
def development(host, port, **kwargs): 
print('in *development* mode')
@dispatch.on('--production')
def development(host, port, **kwargs): 
print('in *production* mode')
@dispatch.on('items', 'add') 
def items_add(item, **kwargs):
print('adding item...')
@dispatch.on('items', 'delete') 
def items_delete(item, **kwargs):
print('deleting item...')
if name == ' main': 
dispatch( doc )
Ejemplo avanzado con docopt y docopt_dispatch
Al igual que con docopt, con [docopt_dispatch] creas tu --help en la variable doc de tu módulo 
de punto de entrada. Allí, se llama dispatch con la cadena doc como argumento, para que pueda 
ejecutar el analizador sobre él.
Una vez hecho esto, en lugar de manejar manualmente los argumentos (que por lo general 
terminan en una estructura ciclomática alta de / else), lo dejas para enviar, dando solo la forma en 
que quieres manejar el conjunto de argumentos.
Esto es para lo que es el decorador dispatch.on : le da el argumento o la secuencia de 
argumentos que deberían desencadenar la función, y esa función se ejecutará con los valores 
coincidentes como parámetros.
Foo options:
--bar_this BAR_THIS
--bar_that BAR_THAT
Bar options:
--foo_this FOO_THIS
--foo_that FOO_THAT
    153/1068
    89
<div>
<label>Name:</label> 
John Smith
</div>
from bs4 import BeautifulSoup
data = """
<div>
<label>Name:</label> 
John Smith
</div> 
"""
soup = BeautifulSoup(data, "html.parser")
label = soup.find("label", text="Name:") 
print(label.next_sibling.strip())
from bs4 import BeautifulSoup
data = """
<ul>
<li class="item">item1</li>
<li class="item">item2</li>
<li class="item">item3</li>
</ul> 
"""
Capítulo 12: Análisis de HTML
Examples
Localiza un texto después de un elemento en BeautifulSoup.
Imagina que tienes el siguiente HTML:
Y necesitas ubicar el texto "John Smith" después del elemento de label .
En este caso, puede ubicar el elemento de label por texto y luego usar la propiedad .next_sibling
:
Imprime John Smith .
Usando selectores de CSS en BeautifulSoup
BeautifulSoup tiene un soporte limitado para los selectores de CSS , pero cubre los más 
utilizados. Use el método select() para encontrar múltiples elementos y select_one() para 
encontrar un solo elemento.
Ejemplo básico:
    154/1068
    90
item1 
item2 
item3
from pyquery import PyQuery
html = """
<h1>Sales</h1>
<table id="table">
<tr>
<td>Lorem</td>
<td>46</td>
</tr>
<tr>
<td>Ipsum</td>
<td>12</td>
</tr>
<tr>
<td>Dolor</td>
<td>27</td>
</tr>
<tr>
<td>Sit</td>
<td>90</td>
</tr>
</table> 
"""
doc = PyQuery(html) 
title = doc('h1').text() 
print title
table_data = []
rows = doc('#table > tr') 
for row in rows:
name = PyQuery(row).find('td').eq(0).text()
value = PyQuery(row).find('td').eq(1).text()
print "%s\t %s" % (name, value)
Huellas dactilares:
PyQuery
pyquery es una biblioteca tipo jquery para python. Tiene muy buen soporte para selectores css.
soup = BeautifulSoup(data, "html.parser") 
for item in soup.select("li.item"):
print(item.get_text())
    155/1068
    91
try:
res = get_result() 
res = res[0]
log('got result: %r' % res) 
except:
if not res:
res = '' 
print('got exception')
import traceback
try:
res = get_result() 
except Exception:
log_exception(traceback.format_exc()) 
raise
try:
res = res[0] 
except IndexError:
res = ''
log('got result: %r' % res)
Capítulo 13: Anti-patrones de Python
Examples
Con exceso de celo excepto la cláusula
Las excepciones son poderosas, pero una sola cláusula exagerada puede quitarlo todo en una 
sola línea.
Este ejemplo demuestra 3 síntomas del antipattern:
1. El tipo de excepción except sin excepción (línea 5) detectará incluso las excepciones 
correctas, incluido KeyboardInterrupt . Eso evitará que el programa salga en algunos casos.
2. El bloque de excepción novuelve a generar el error, lo que significa que no podremos saber 
si la excepción provino de get_result o porque res era una listavacía.
3. Lopeordetodo,sinospreocupabaqueelresultadoestuvieravacío,hemoscausadoalgo 
mucho peor. Si get_result falla, la res permanecerá completamente sin configurar, y la 
referencia a la resen el bloque de excepción, generará NameError, NameErrorcompletamente 
el error original.
Siempre piensa en el tipo de excepción que estás tratando de manejar. Dale una lectura a la
página de excepciones y comprueba qué excepciones básicas existen.
Aquí hay una versión fija del ejemplo anterior:
Capturamos excepciones más específicas, volviendo a subir cuando sea necesario. Unas líneas 
más, pero infinitamente más correctas.
    156/1068
    92
def intensive_f(value): # int -> Optional[int] 
# complex, and time-consuming code
if process_has_failed: 
return None
return integer_output
x = 5
ifintensive_f(x)isnot None: 
print(intensive_f(x) /2)
else:
print(x, "could not be processed")
print(x)
x = 5
result = intensive_f(x) 
if result is not None:
print(result / 2) 
else:
print(x, "could not be processed")
x = 5 
try:
print(intensive_f(x) / 2)
except TypeError: # The exception raised if None + 1 is attempted 
print(x, "could not be processed")
Mirando antes de saltar con la función de procesador intensivo
Un programa puede fácilmente perder tiempo llamando a una función intensiva en el procesador 
varias veces.
Por ejemplo, tome una función que se parece a esto: devuelve un entero si el value entrada puede 
producir uno, de lo contrario, None :
Y podría ser utilizado de la siguiente manera:
Si bien esto funcionará, tiene el problema de llamar intensive_f , que duplica el tiempo de 
ejecución del código. Una mejor solución sería obtener el valor de retorno de la función de 
antemano.
Sin embargo, una forma más clara y posiblemente más pirónica es usar excepciones, por 
ejemplo:
Aquí no se necesita una variable temporal. Puede ser a menudo preferible utilizar una assert
declaración, y para coger el AssertionError lugar.
Claves del diccionario
Un ejemplo común de dónde se puede encontrar esto es acceder a las claves del diccionario. Por 
ejemplo comparar:
    157/1068
    93
bird_speeds = get_very_long_dictionary()
try:
speed = bird_speeds["european swallow"] 
except KeyError:
speed = input("What is the air-speed velocity of an unladen swallow?")
print(speed)
con:
El primer ejemplo tiene que mirar el diccionario dos veces, y como este es un diccionario largo, 
puede llevar mucho tiempo hacerlo cada vez. El segundo solo requiere una búsqueda en el 
diccionario y, por lo tanto, ahorra mucho tiempo de procesador.
Una alternativa a esto es usar dict.get(key, default), sin embargo, muchas circunstancias 
pueden requerir operaciones más complejas en el caso de que la clave no esté presente
bird_speeds = get_very_long_dictionary()
if "european swallow" in bird_speeds: 
speed = bird_speeds["european swallow"]
else:
speed = input("What is the air-speed velocity of an unladen swallow?")
print(speed)
    158/1068
    94
Capítulo 14: Apilar
Introducción
Una pila es un contenedor de objetos que se insertan y eliminan de acuerdo con el principio de 
último en entrar, primero en salir (LIFO). En las pilas de pushdown solo se permiten dos 
operaciones: empujar el elemento en la pila y sacar el elemento de la pila . Una pila es una 
estructura de datos de acceso limitado: los elementos se pueden agregar y eliminar de la pila 
solo en la parte superior . Aquí hay una definición estructural de una pila: una pila está vacía o 
consiste en una parte superior y el resto que es una pila.
Sintaxis
• stack = [] # Crea la pila
• stack.append (objeto) # Agregar objeto a la parte superior de la pila
• stack.pop () -> object # Devuelve el objeto más superior de la pila y también lo elimina
• list [-1] -> object # Mira el objeto más superior sin quitarlo
Observaciones
De Wikipedia :
En informática, una pila es un tipo de datos abstracto que sirve como una colección de 
elementos, con dos operaciones principales: push , que agrega un elemento a la 
colección, y pop , que elimina el elemento agregado más reciente que aún no se 
eliminó.
Debido a la forma en que se accede a sus elementos, las pilas son también conocidos como
último en entrar, primero en salir (LIFO) apila.
En Python se pueden usar listas como pilas con append() como push y pop() como operaciones 
emergentes. Ambas operaciones se ejecutan en tiempo constante O (1).
La estructura de datos deque de Python también se puede utilizar como una pila.En comparación 
con las listas, los deque permiten operaciones de inserción y pop con una complejidad de tiempo 
constante desde ambos extremos.
Examples
Creación de una clase de pila con un objeto de lista
Usandounobjetodelist,puedecrearunapilagenéricacompletamentefuncionalconmétodos 
auxiliares, como mirar y comprobar si la pila está vacía.Echa un vistazo a los documentos 
oficiales de Python para utilizar la list como Stack aquí.
    159/1068
    95
stack = Stack()
print('Current stack:', stack.fullStack()) 
print('Stack empty?:', stack.isEmpty()) 
print('Pushing integer 1')
stack.push(1)
print('Pushing string "Told you, I am generic stack!"') 
stack.push('Told you, I am generic stack!') 
print('Pushing integer 3')
stack.push(3)
print('Current stack:', stack.fullStack()) 
print('Popped item:', stack.pop()) 
print('Current stack:', stack.fullStack()) 
print('Stack empty?:', stack.isEmpty())
Current stack: [] 
Stack empty?: True 
Pushing integer 1
Pushing string "Told you, I am generic stack!" 
Pushing integer 3
Currentstack: [1, 'Told you,I am generic stack!', 3] 
Popped item: 3
Current stack: [1, 'Told you, I am generic stack!'] 
Stack empty?: False
Un ejemplo de ejecución:
Salida:
#define a stack class 
class Stack:
def init (self): 
self.items = []
#method to check the stack is empty or not 
def isEmpty(self):
return self.items == []
#method for pushing an item 
def push(self, item):
self.items.append(item)
#method for popping an item 
def pop(self):
return self.items.pop()
#check what item is on top of the stack without removing it 
def peek(self):
return self.items[-1]
#method to get the size 
def size(self):
return len(self.items)
#to view the entire stack 
def fullStack(self):
return self.items
    160/1068
    96
def checkParenth(str): 
stack = Stack()
pushChars, popChars = "<({[", ">)}]" 
for c in str:
if c in pushChars:
stack.push(c)
elif c in popChars:
if stack.isEmpty(): 
return False
else:
stackTop = stack.pop()
# Checks to see whether the opening bracket matches the closing one 
balancingBracket = pushChars[popChars.index(c)]
if stackTop != balancingBracket: 
return False
else:
return False
return not stack.isEmpty()
Paréntesis de paréntesis
Las pilas se utilizan a menudo para el análisis. Una tarea de análisis simple es verificar si una 
cadena de paréntesis coincide.
Porejemplo,lacadena([])coincide,porqueloscorchetesexterioreinteriorformanpares.()<>) 
nocoincide,porqueelúltimo)notienepareja.([)]tampococoincide,porquelosparesdeben 
estar completamente dentro o fuera deotrospares.
    161/1068
    97
Capítulo 15: Árbol de sintaxis abstracta
Examples
Analizar funciones en un script de python
Esto analiza un script de Python y, para cada función definida, informa el número de línea donde 
comenzó la función, donde termina la firma, donde termina la cadena de documentos y donde 
termina la definición de la función.
#!/usr/local/bin/python3 
import ast
import sys
""" The datawe collect. Each key is a function name; each value is a dict 
with keys: firstline, sigend, docend, and lastline and values of line numbers 
where that happens. """
functions = {}
def process(functions):
""" Handle the function data stored in functions. """ 
for funcname,data in functions.items():
print("function:",funcname) 
print("\tstarts at line:",data['firstline'])
print("\tsignature ends at line:",data['sigend']) 
if ( data['sigend'] < data['docend'] ):
print("\tdocstring ends at line:",data['docend']) 
else:
print("\tno docstring")
print("\tfunction ends at line:",data['lastline']) 
print()
class FuncLister(ast.NodeVisitor): 
def visit_FunctionDef(self, node):
""" Recursively visit all functions, determining where each function 
starts, where its signature ends, where the docstring ends, and where 
the function ends. """
functions[node.name] = {'firstline':node.lineno} 
sigend = max(node.lineno,lastline(node.args)) 
functions[node.name]['sigend'] = sigend 
docstring = ast.get_docstring(node)
docstringlength = len(docstring.split('\n')) if docstring else -1 
functions[node.name]['docend'] = sigend+docstringlength 
functions[node.name]['lastline'] = lastline(node) 
self.generic_visit(node)
def lastline(node):
""" Recursively find the last line of a node """
return max( [ node.lineno if hasattr(node,'lineno') else -1 , ]
+[lastline(child) for child in ast.iter_child_nodes(node)] )
def readin(pythonfilename):
""" Read the file name and store the function data into functions. """ 
with open(pythonfilename) as f:
code = f.read()
    162/1068
    98
FuncLister().visit(ast.parse(code))
def analyze(file,process):
""" Read the file and process the function data. """ 
readin(file)
process(functions)
if name == ' main ': if 
len(sys.argv)>1:
for file in sys.argv[1:]: 
analyze(file,process)
else:
analyze(sys.argv[0],process)
    163/1068
    99
import sys 
sys.getdefaultencoding()
Capítulo 16: Archivos y carpetas I / O
Introducción
Cuando se trata de almacenar, leer o comunicar datos, trabajar con los archivos de un sistema 
operativo es tanto necesario como fácil con Python. A diferencia de otros idiomas en los que la 
entrada y salida de archivos requiere objetos complejos de lectura y escritura, Python simplifica el 
proceso, ya que solo necesita comandos para abrir, leer / escribir y cerrar el archivo. Este tema 
explica cómo Python puede interactuar con archivos en el sistema operativo.
Sintaxis
• file_object = open (filename [, access_mode] [, buffering])
Parámetros
Parámetro Detalles
nombre del 
archivo
la ruta a su archivo o, si el archivo está en el directorio de trabajo, el 
nombre de archivo de su archivo
modo de acceso un valor de cadena que determina cómo se abre el archivo
amortiguación un valor entero utilizado para el búfer de línea opcional
Observaciones
Evitar el infierno de codificación 
multiplataforma
Cuando se utiliza el open() incorporado de Python, es una buena práctica pasar siempre el 
argumento de encoding , si pretende que su código se ejecute en varias plataformas. El motivo de 
esto es que la codificación predeterminada de un sistema difiere de una plataforma a otra.
Si bien los sistemas linux sí usan utf-8 como predeterminado, esto no es necesariamente cierto 
para MAC y Windows.
Para verificar la codificación predeterminada de un sistema, intente esto:
    164/1068
    100
withopen('somefile.txt', 'r', encoding='UTF-8') asf: 
for line in f:
print(line)
de cualquier intérprete de python.
Por lo tanto, es aconsejable siempre sepcificar una codificación, para asegurarse de que las 
cadenas con las que está trabajando estén codificadas como lo que cree que son, lo que 
garantiza la compatibilidad entre plataformas.
Examples
Modos de archivo
Hay diferentes modos con los que puede abrir un archivo, especificados por el parámetro de mode
. Éstos incluyen:
• 'r'-mododelectura.Elvalorpordefecto.Lepermitesololeerelarchivo,nomodificarlo.Al 
usar este modo el archivo debe existir.
• 'w' - modo de escritura. Creará un nuevo archivo si no existe, de lo contrario borrará el 
archivo y le permitirá escribir en él.
• 'a'-mododeañadir.Escribirálosdatosalfinaldelarchivo.Noborraelarchivo,yelarchivo 
debe existir para este modo.
• 'rb'-mododelectura enbinario.Estoessimilararexceptoquelalecturasefuerzaen 
modo binario. Esta es también una opción por defecto.
• 'r+'-mododelecturamásmododeescrituraalmismotiempo.Estolepermiteleery 
escribir en archivos al mismo tiempo sin tener que usar r y w .
• 'rb+'-mododelecturayescritura enbinario. Lomismo quer+ exceptoquelosdatosestán 
en binario
• 'wb' - modo de escritura en binario. Lo mismo que w excepto que los datos están en binario.
• 'w+' - modo de escritura y lectura. Exactamente igual que r+ pero si el archivo no existe, se 
crea uno nuevo. De lo contrario, el archivo se sobrescribe.
• 'wb+' - modo de escritura y lectura en modo binario. Lo mismo que w+ pero los datos están 
en binario.
• 'ab'- añadiendo en modo binario. Similar a a excepto que los datos están en binario.
• 'a+' - modo de añadir y leer. Similar a w+ ya que creará un nuevo archivo si el archivo no 
existe. De lo contrario, el puntero del archivo se encuentra al final del archivo, si existe.
• 'ab+' - modo de añadir y leer en binario. Lo mismo que a+ excepto que los datos están en
    165/1068
    101
with open(filename, 'r') asf: 
f.read()
with open(filename, 'w') as f: 
f.write(filedata)
with open(filename, 'a') as f: 
f.write('\n' + newdata)
binario.
r r + w w + una a +
Leer ✔ ✔ ✘ ✔ ✘ ✔
Escribir ✘ ✔ ✔ ✔ ✔ ✔
Crea archivo ✘ ✘ ✔ ✔ ✔ ✔
Borrar archivo ✘ ✘ ✔ ✔ ✘ ✘
Posición inicial comienzo comienzo comienzo comienzo Fin Fin
Python 3 agregó un nuevo modo para la exclusive creation para que no truncas o sobrescribas 
accidentalmente un archivo existente.
• 'x'-abiertoparacreaciónexclusiva,generaráFileExistsError sielarchivoyaexiste
• 'xb'- abierto para el modo de escritura de creación exclusiva en binario. Lo mismo que x
excepto que los datos están en binario.
• 'x+'-mododelecturayescritura.Similara w+ yaquecrearáunnuevo archivosielarchivo 
no existe. De lo contrario, se levantará FileExistsError.
• 'xb+'-mododeescrituraylectura.Exactamentelomismoquex+ perolosdatos son 
binarios.
X x +
Leer ✘ ✔
Escribir ✔ ✔
Crea archivo ✔ ✔
Borrar archivo ✘ ✘
Posición inicial comienzo comienzo
Permita que uno escriba su código de archivo abierto de una manera más pitónica: 
Python 3.x 3.3
    166/1068
    102
import os.path
if os.path.isfile(fname):
with open("fname", "w") as fout: 
# Work with your open file
else:
# Your error handling goes here
with open('myfile.txt', 'r') as fp: 
for line in fp:
print(line)
with open('myfile.txt', 'r') as fp: 
while True:
cur_line = fp.readline()
# If the result is an empty string 
if cur_line == '':
# We have reached the end of the file 
break
print(cur_line)
with open("myfile.txt", "r") as fp: 
lines = fp.readlines()
for i in range(len(lines)): 
print("Line " + str(i) + ": " + line)
En Python 2 habrías hecho algo como 
Python 2.x 2.0
Leyendo un archivo línea por línea
La forma más sencilla de iterar sobre un archivo línea por línea:
readline() permite un control más granular sobre la iteración línea por línea. El siguiente ejemplo 
es equivalente al de arriba:
Usar el iterador de bucle for y readline () juntos se considera una mala práctica.
Más comúnmente, el método readlines() se usa para almacenar una colección iterable de las 
líneas del archivo:
Esto imprimiría lo siguiente: 
Línea 0: hola
Línea 1: mundo
try:
with open("fname", "r") as fout: 
# Work with your open file
except FileExistsError:
# Your error handling goes here
    167/1068
    103
with open('myfile.txt') as in_file: 
content = in_file.read()
print(content)
in_file = open('myfile.txt', 'r') 
content = in_file.read() 
print(content)
in_file.close()
in_file = open('myfile.txt', 'r') 
raise Exception("oops")
in_file.close() # This will never be called
with open('myfile.txt', 'w') as f: 
f.write("Line 1")
f.write("Line 2")
f.write("Line 3")
f.write("Line 4")
with open('myfile.txt', 'w') as f: 
f.write("Line 1\n") 
f.write("Line 2\n") 
f.write("Line 3\n") 
f.write("Line 4\n")
Obtener el contenido completo de un archivo
El método preferido para el archivo i / o es usarla palabra clave with . Esto asegurará que el 
identificador de archivo se cierre una vez que se haya completado la lectura o escritura.
o,para manejar el cierre del archivo de forma manual, se puede renunciar with y simplemente 
llamar a close a sí mismo:
Tenga en cuenta que sin utilizar una instrucción with , puede mantener el archivo abierto por 
accidente en caso de que surja una excepción inesperada:
Escribiendo en un archivo
Si abres myfile.txt , verás que su contenido es: 
Línea 1Línea 2Línea 3Línea 4
Python no agrega automáticamente saltos de línea, debe hacerlo manualmente:
Línea 1
Línea 2
Línea 3
Linea 4
    168/1068
    104
outfile = open('fred.txt', 'w') 
s = "I'm Not Dead Yet!"
print s # writes to stdout
print >> outfile, s # writes to outfile
with open('my_file.txt', 'w', encoding='utf-8') as f: 
f.write('utf-8 text')
with open('fred.txt', 'w') as outfile: 
s = "I'm Not Dead Yet!"
print(s) # writes to stdout
print(s, file = outfile) # writes to outfile
#Note: it is possible to specify the file parameter AND write to the screen 
#by making sure file ends up with a None value either directly or via a variable 
myfile = None
print(s, file = myfile) # writes to stdout 
print(s, file = None) # writes to stdout
with open(input_file, 'r') asin_file, open(output_file, 'w') as out_file: 
for line in in_file:
out_file.write(line)
import shutil 
shutil.copyfile(src, dst)
No use os.linesep como terminador de línea al escribir archivos abiertos en modo de texto (el 
valor predeterminado); use \n lugar.
Si desea especificar una codificación, simplemente agregue el parámetro de encoding a la función 
de open :
También es posible utilizar la declaración de impresión para escribir en un archivo. La mecánica 
es diferente en Python 2 vs Python 3, pero el concepto es el mismo en que puedes tomar la salida 
que habría ido a la pantalla y enviarla a un archivo.
Python 3.x 3.0
En Python 2 habrías hecho algo como 
Python 2.x 2.0
A diferencia de usar la función de escritura, la función de impresión agrega automáticamente 
saltos de línea.
Copiando los contenidos de un archivo a un archivo diferente
• Usando el módulo de shutil:
Compruebe si existe un archivo o ruta
    169/1068
    105
import errno
try:
with open(path) as f: 
# File exists
except IOError as e:
# Raise the exception if it is not ENOENT (No such file or directory) 
if e.errno != errno.ENOENT:
raise
# No such file or directory
import os 
os.path.isfile('/path/to/some/file.txt')
import pathlib
path = pathlib.Path('/path/to/some/file.txt') 
if path.is_file():
...
import os
path = "/home/myFiles/directory1"
if os.path.exists(path): 
## Do stuff
import shutil 
source='//192.168.1.2/Daily Reports' 
destination='D:\\Reports\\Today' 
shutil.copytree(source, destination)
Emplea el estilo de codificación EAFP e try abrirlo.
Esto también evitará condiciones de carrera si otro proceso eliminó el archivo entre la verificación 
y cuando se utiliza. Esta condición de carrera podría ocurrir en los siguientes casos:
• Usando el módulo os :
Python 3.x 3.4
• Utilizando pathlib :
Para verificar si existe una ruta determinada o no, puede seguir el procedimiento anterior de 
EAFP o verificar explícitamente la ruta:
Copiar un árbol de directorios
El directorio de destino no debe existir ya.
Iterar archivos (recursivamente)
Para iterar todos los archivos, incluidos los subdirectorios, use os.walk:
    170/1068
    106
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file(): 
print(entry.name)
import mmap
with open('filename.ext', 'r') as fd: 
# 0: map the whole file
mm = mmap.mmap(fd.fileno(), 0)
# print characters at indices 5 through 10
root_dir puede ser "." para comenzar desde el directorio actual, o cualquier otra ruta desde la que
comenzar.
Python 3.x 3.5
Si también desea obtener información sobre el archivo, puede usar el método más eficiente 
os.scandir así:
Leer un archivo entre un rango de líneas.
Supongamosquedeseaiterarsoloentrealgunaslíneasespecíficasdeunarchivo 
Puedes hacer uso de itertools para eso.
Esto leerá las líneas 13 a 20, ya que la indexación de Python comienza desde 0. Por lo tanto, la 
línea número 1 se indexa como 0
Como también puede leer algunas líneas adicionales haciendo uso de la next() palabra clave
next() aquí.
Y cuando esté utilizando el objeto de archivo como un iterable, no use la instrucción readline()
aquí ya que las dos técnicas para atravesar un archivo no deben mezclarse
Acceso aleatorio a archivos usando mmap
El uso del módulo mmap permite al usuario acceder aleatoriamente a las ubicaciones de un archivo 
asignando el archivo a la memoria. Esta es una alternativa al uso de operaciones de archivos 
normales.
import itertools
with open('myfile.txt', 'r') as f:
for line in itertools.islice(f, 12, 30): 
# do something here
import os
for root, folders, files in os.walk(root_dir): 
for filename in files:
print root, filename
    171/1068
    107
import fileinput
replacements = {'Search1': 'Replace1',
'Search2': 'Replace2'}
for line in fileinput.input('filename.txt', inplace=True): 
for search_for in replacements:
replace_with = replacements[search_for]
line = line.replace(search_for, replace_with) 
print(line, end='')
>>> import os
>>> os.stat(path_to_file).st_size == 0
>>> import os
>>> os.path.getsize(path_to_file) > 0
import os
def is_empty_file(fpath):
return os.path.isfile(fpath) and os.path.getsize(fpath) > 0
Reemplazo de texto en un archivo
Comprobando si un archivo está vacío
o
Sin embargo, ambos lanzarán una excepción si el archivo no existe. Para evitar tener que atrapar 
tal error, haga esto:
que devolverá un valor bool .
print mm[5:10]
# print the line starting from mm's current position 
print mm.readline()
# write a character to the 5th index 
mm[5] = 'a'
# return mm's position to the beginning of the file 
mm.seek(0)
# close the mmap object 
mm.close()
    172/1068
    108
with arcpy.da.SearchCursor(r"C:\Temp\Test.gdb\TestFC",["TestField"]) as cursor: 
for row in cursor:
print row[0]
def createDissolvedGDB(workspace, gdbName): 
gdb_name = workspace + "/" + gdbName + ".gdb"
if(arcpy.Exists(gdb_name): 
arcpy.Delete_management(gdb_name) 
arcpy.CreateFileGDB_management(workspace, gdbName, "")
else:
arcpy.CreateFileGDB_management(workspace, gdbName, "")
return gdb_name
Capítulo 17: ArcPy
Observaciones
Este ejemplo utiliza un cursor de búsqueda del módulo de acceso a datos (da) de ArcPy.
No confunda la sintaxis de arcpy.da.SearchCursor con la arcpy.SearchCursor () anterior y más 
lenta.
El módulo de acceso a datos (arcpy.da) solo ha estado disponible desde ArcGIS 10.1 para 
escritorio.
Examples
Impresión del valor de un campo para todas las filas de la clase de entidad en 
la geodatabase de archivos usando el cursor de búsqueda
Para imprimir un campo de prueba (TestField) desde una clase de entidad de prueba (TestFC) en 
una geodatabase de archivos de prueba (Test.gdb) ubicada en una carpeta temporal (C: \ Temp):
createDissolvedGDB para crear un archivo gdb en el área de trabajo
    173/1068
    109
Capítulo 18: Arrays
Introducción
Las "matrices" en Python no son las matrices en lenguajes de programación convencionales 
como C y Java, sino que están más cerca de las listas. Una lista puede ser una colección de 
elementos homogéneos o heterogéneos, y puede contener ints, cadenas u otras listas.
Parámetros
Parámetro Detalles
b Representa un entero con signo de tamaño 1 byte
B Representa un entero sin signo de tamaño 1 byte
c Representa el carácter de 1 byte de tamaño.
u Representa caracteres unicode de tamaño 2 bytes.
h Representa un entero con signo de tamaño 2 bytes
H Representa un entero sin signo de tamaño 2 bytes
i Representa un entero con signo de tamaño 2 bytes
I Representa un entero sin signo de tamaño 2 bytes
w Representa caracteres unicode de tamaño 4 bytes.
l Representa un entero con signo de tamaño 4 bytes
L Representa un entero sin signo de tamaño 4 bytes
f Representa punto flotante de tamaño 4 bytes.
d Representa punto flotante de tamaño 8 bytes.
Examples
Introducción básica a las matrices
Una matriz es una estructura de datos que almacena valores del mismo tipo de datos. En Python, 
esta es la principal diferencia entre matrices y listas.
Mientras que las listas de python pueden contener valores correspondientes a diferentes tipos de
    174/1068
    https://riptutorial.com/es/home 110
from array import *
arrayIdentifierName = array(typecode, [Initializers])
my_array = array('i',[1,2,3,4])
from array import *
my_array =array('i', [1,2,3,4,5]) 
for i in my_array:
print(i)
# 1
# 2
# 3
# 4
# 5
my_array = array('i', [1,2,3,4,5]) 
print(my_array[1])
# 2
datos, las matrices en python solo pueden contener valores correspondientes al mismo tipo de 
datos. En este tutorial, entenderemos las matrices de Python con algunos ejemplos.
Si eres nuevo en Python, comienza con el artículo de Introducción a Python.
Para usar arrays en lenguaje python, necesita importar el módulo de array estándar.Esto se debe 
a que la matriz no es un tipo de datos fundamental como cadenas, números enteros, etc.Aquí se 
explica cómo puede importar array módulo de array en Python:
Una vez que haya importado el módulo de array , puede declarar una matriz. Así es como lo 
haces:
En ladeclaración anterior, arrayIdentifierName eselnombredelamatriz, typecode permitea 
pythonsabereltipodematrizylosInitializerssonlosvaloresconlosqueseinicializalamatriz.
Los códigos de tipo son los códigos que se utilizan para definir el tipo de valores de matriz o el 
tipo de matriz. La tabla en la sección de parámetros muestra los valores posibles que puede usar 
al declarar una matriz y su tipo.
Aquí hay un ejemplo del mundo real de declaración de matriz de python:
Enelejemploanterior,elcódigodecódigoutilizadoesi.Estecódigodecódigorepresentaun 
entero con signo cuyo tamaño es de 2 bytes.
Aquí hay un ejemplo simple de una matriz que contiene 5 enteros
Accede a elementos individuales a través de índices.
Se puede acceder a elementos individuales a través de índices. Las matrices de Python están 
indexadas a cero. Aquí hay un ejemplo :
    175/1068
    111
my_array = array('i', [1,2,3,4,5]) 
my_array.append(6)
# array('i', [1, 2, 3, 4, 5, 6])
my_array = array('i', [1,2,3,4,5]) 
my_array.insert(0,0)
#array('i', [0, 1, 2, 3, 4, 5])
my_array = array('i', [1,2,3,4,5]) 
my_extnd_array = array('i', [7,8,9,10]) 
my_array.extend(my_extnd_array)
# array('i', [1, 2, 3, 4, 5, 7, 8, 9, 10])
Agregue cualquier valor a la matriz usando el método append ()
Tenga en cuenta que el valor 6 se agregó a los valores de matriz existentes.
Insertar valor en una matriz usando el método insert ()
Podemos usar el método insert() para insertar un valor en cualquier índice de la matriz. Aquí hay 
un ejemplo :
En el ejemplo anterior, el valor 0 se insertó en el índice 0. Tenga en cuenta que el primer 
argumento es el índice, mientras que el segundo argumento es el valor.
Extiende la matriz de python usando el método extend ()
Una matriz de python se puede ampliar con más de un valor utilizando extend() método extend() . 
Aquí hay un ejemplo :
Vemos que la matriz my_array se extendió con los valores de my_extnd_array .
Agregue elementos de la lista a la matriz usando el método fromlist () 
Aquí hay un ejemplo:
Entonces vemos que los valores 11,12 y 13 se agregaron de la lista c a my_array .
Elimine cualquier elemento del arreglo usando el método remove ()
print(my_array[2]) 
# 3
print(my_array[0]) 
# 1
my_array = array('i', [1,2,3,4,5]) 
c=[11,12,13]
my_array.fromlist(c)
# array('i', [1, 2, 3, 4, 5, 11, 12, 13])
    176/1068
    112
my_array = array('i', [1,2,3,4,5]) 
my_array.remove(4)
# array('i', [1, 2, 3, 5])
my_array = array('i', [1,2,3,4,5]) 
my_array.pop()
# array('i', [1, 2, 3, 4])
my_array = array('i', [1,2,3,4,5]) 
print(my_array.index(5))
# 5
my_array = array('i', [1,2,3,3,5]) 
print(my_array.index(3))
# 3
my_array = array('i', [1,2,3,4,5]) 
my_array.reverse()
# array('i', [5, 4, 3, 2, 1])
my_array = array('i', [1,2,3,4,5]) 
my_array.buffer_info() 
(33881712, 5)
Aquí hay un ejemplo :
Vemos que el elemento 4 fue eliminado de la matriz.
Eliminar el último elemento de la matriz utilizando el método pop ()
pop elimina el último elemento de la matriz. Aquí hay un ejemplo :
Así que vemos que el último elemento ( 5 ) se extrajo de la matriz.
Obtenga cualquier elemento a través de su índice usando el método index ()
index() devuelve el primer índice del valor coincidente. Recuerde que las matrices están 
indexadas a cero.
Tenga en cuenta en ese segundo ejemplo que solo se devolvió un índice, aunque el valor existe 
dos veces en la matriz
Invertir una matriz de python usando el método reverse ()
El método reverse() hace lo que el nombre dice que hará: invierte la matriz. Aquí hay un ejemplo :
Obtener información de búfer de matriz a través del método buffer_info ()
Este método le proporciona la dirección de inicio del búfer de matriz en la memoria y la cantidad 
de elementos en la matriz. Aquí hay un ejemplo:
    177/1068
    113
my_array = array('i', [1,2,3,3,5]) 
my_array.count(3)
# 2
my_char_array = array('c', ['g','e','e','k']) 
# array('c', 'geek') 
print(my_char_array.tostring())
# geek
my_array = array('i', [1,2,3,4,5]) 
c = my_array.tolist()
# [1, 2, 3, 4, 5]
my_char_array = array('c', ['g','e','e','k']) 
my_char_array.fromstring("stuff") 
print(my_char_array)
#array('c', 'geekstuff')
Compruebe el número de apariciones de un elemento utilizando el método 
count ()
count() devolverá el número de veces y el elemento aparecerá en una matriz. En el siguiente 
ejemplo vemos que el valor 3 aparece dos veces.
Convierte una matriz en una cadena usando el método tostring ()
tostring() convierte la matriz en una cadena.
Convierta la matriz a una lista de python con los mismos elementos utilizando 
el método tolist ()
Cuandonecesiteunobjetodelist Python,puedeutilizarel métodotolist() paraconvertirsu 
matriz en una lista.
Agregue una cadena a la matriz de caracteres utilizando el método fromstring 
()
Puede agregar una cadena a una matriz de caracteres usando fromstring()
    178/1068
    114
import pyglet
audio = pyglet.media.load("audio.wav") 
audio.play()
import winsound
winsound.PlaySound("path_to_wav_file.wav", winsound.SND_FILENAME)
assert len(frames) == sample_width * n_frames
# Duplicate to a new WAV file.
with wave.open("path_to_new_wav_file.wav", "wb") as wav_file: # Open WAV file in write-only 
mode.
# Write audio data.
params = (n_channels, sample_width, framerate, n_frames, comp_type, comp_name) 
wav_file.setparams(params)
wav_file.writeframes(frames)
# Read n_frames new frames.
# Read audio data.
frames = wav_file.readframes(n_frames)
n_channels = wav_file.getnchannels() # Number of channels. (1=Mono, 2=Stereo). 
sample_width = wav_file.getsampwidth() # Sample width in bytes.
framerate = wav_file.getframerate() # Frame rate. 
n_frames = wav_file.getnframes() # Number of frames.
comp_type = wav_file.getcomptype() # Compression type (only supports "NONE").
comp_name = wav_file.getcompname() # Compression name.
#Open WAVfile in read-only
import wave
with wave.open("path_to_wav_file.wav", "rb") as wav_file: 
mode.
# Get basic information.
Capítulo 19: Audio
Examples
Audio con pyglet
Para más información, ver pyglet.
Trabajando con archivos WAV
WinSound
• Entorno de Windows
ola
• Soporte mono / estéreo
• No soporta compresión / descompresión
    179/1068
    115
from subprocess import check_call
ok = check_call(['ffmpeg','-i','input.mp3','output.wav']) 
if ok:
with open('output.wav', 'rb') as f: 
wav_file = f.read()
import winsound
freq = 2500 # Set frequency To 2500 Hertz
dur = 1000 # Set duration To 1000 ms == 1 second 
winsound.Beep(freq, dur)
Convierte cualquier archivo de sonido con python y ffmpeg
Nota:
• http://superuser.com/questions/507386/why-would-i-choose-libav-over-ffmpeg-or-is-thereeven-a-difference
• ¿Cuáles son las diferencias y similitudes entre ffmpeg, libav y avconv?
Tocando los pitidos de Windows
Windows proporciona una interfaz explícita a través de la cual el módulo winsound permite 
reproducir sonidos brutos en una frecuencia y duración determinadas.
    180/1068
    116
class CustomError(Exception): 
pass
x = 1
if x == 1:
raise CustomError('This is custom error')
Traceback (most recent call last):
File "error_custom.py", line 8, in <module> 
raise CustomError('This is custom error')
 main .CustomError: This is custom error
class CustomError(Exception): 
pass
try:
raise CustomError('Can you catch me ?')
Capítulo 20: Aumentar errores / excepciones 
personalizados
Introducción
Python tiene muchas excepciones integradas que obligan a su programa a generar un error 
cuando algo falla.
Sin embargo, a veces es posible que necesite crear excepciones personalizadas que sirvan a su 
propósito.
En Python, los usuarios pueden definir dichas excepciones creando una nueva clase. Esta clase 
de excepción debe derivarse, directa o indirectamente, de la clase de excepción. La mayoría de 
las excepciones incorporadas también se derivan de esta clase.
Examples
Excepción personalizada
Aquí, hemos creado una excepción definida por el usuario llamada CustomError que se deriva de 
la clase Exception. Esta nueva excepción se puede generar, como otras excepciones, usando la 
declaración de aumento con un mensaje de error opcional.
Salida:
Atrapar Excepción personalizada
Este ejemplo muestra cómo capturar Excepciones personalizadas
    181/1068
    117
Catched CustomError :Can you catch me ?
Salida:
except CustomError as e:
print ('Catched CustomError :{}'.format(e)) 
except Exception as e:
print ('Generic exception: {}'.format(e))
    182/1068
    118
subprocess.call([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
subprocess.call('echo "Hello, world"', shell=True)
Capítulo 21: Biblioteca de subproceso
Sintaxis
• subprocess.call (args, *, stdin = None, stdout = None, stderr = None, shell = False, timeout = 
None)
• subprocess.Popen (args, bufsize = -1, executable = None, stdin = None, stdout = None, 
stderr = None, preexec_fn = None, close_fds = True, shell = False, cwd = None, env = 
None, universal_newlines = False , startupinfo = Ninguna, creationflags = 0, restore_signals
= True, start_new_session = False, pass_fds = ())
Parámetros
Parámetro Detalles
args
Un soloejecutable, osecuenciadeejecutables yargumentos -'ls',['ls', 
la']
'-
shell Ejecutar bajo una cáscara? El shell predeterminado para /bin/sh en POSIX.
cwd Directorio de trabajo del proceso hijo.
Examples
Llamando Comandos Externos
El caso de uso más simple es usar la función subprocess.call . Acepta una lista como primer 
argumento. El primer elemento de la lista debe ser la aplicación externa a la que desea llamar. 
Los otros elementos de la lista son argumentos que se pasarán a esa aplicación.
Para los comandos de shell, establezca shell=True y proporcione el comando como una cadena 
en lugar de una lista.
Tenga en cuenta que los dos comandos anteriores solo devuelven el exitstatus de exitstatus 
delsubproceso.Además,presteatencióncuandouseshell=Trueyaqueproporcionaproblemas 
de seguridad (consulte aquí ).
Si desea poder obtener la salida estándar del subproceso, sustituya el subprocess.call con
subprocess.check_output . Para un uso más avanzado, refiérase a esto .
    183/1068
    119
process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg']) 
process.wait()
process = subprocess.Popen([r'C:\path\to\app.exe'], stdout=subprocess.PIPE, 
stderr=subprocess.PIPE)
# This will block until process completes 
stdout, stderr = process.communicate() 
print stdout
print stderr
process = subprocess.Popen([r'C:\path\to\app.exe'], stdout = subprocess.PIPE, stdin = 
subprocess.PIPE)
process.stdin.write('line of input\n') # Write input
line = process.stdout.readline() # Read a line fromstdout
Más flexibilidad con Popen
El uso de subprocess.Popen proporciona un control más preciso sobre los procesos iniciados que
subprocess.call .
Lanzar un subproceso
La firma para Popen es muy similar a la función de call ; sin embargo, Popen regresará de 
inmediato en lugar de esperar a que se complete el subproceso como lo hace la call .
Esperando en un subproceso para completar
Salida de lectura de un subproceso
Acceso interactivo a subprocesos en 
ejecución.
Puede leer y escribir en stdin y stdout incluso cuando el subproceso no se haya completado. Esto 
podría ser útil al automatizar la funcionalidad en otro programa.
Escribiendo a un subproceso
    184/1068
    https://riptutorial.com/es/home 120
process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE) 
while process.poll() is None:
output_line = process.stdout.readline()
process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE) 
while process.poll() is None:
output_line = process.stdout.read(1)
import shlex
cmd_to_subprocess = shlex.split(command_used_in_the_shell)
import shlex
Sinembargo, si solonecesitaun conjunto de entrada y salida, en lugar de una interacción 
dinámica, debe usar communicate() lugar de acceder directamente a stdin y stdout .
Leyendo un stream desde un subproceso
En caso de que quiera ver la salida de un subproceso línea por línea, puede usar el siguiente 
fragmento de código:
en el caso de que la salida del subcomando no tenga un carácter EOL, el fragmento de código 
anterior no funciona. A continuación, puede leer el carácter de salida por carácter de la siguiente 
manera:
El 1 especificado como argumento a la read método se indica a leer a leer 1 carácter cada vez. 
Puede especificar leer tantos caracteres como desee utilizando un número diferente. El número 
negativo o 0 indica que se read para leer como una sola cadena hasta que se encuentre el EOF ( 
consulte aquí ).
En los dos fragmentos de código anteriores, process.poll() es None hasta que finalice el 
subproceso. Esto se usa para salir del bucle una vez que no hay más salida para leer.
El mismo procedimiento podría aplicarse al stderr del subproceso.
Cómo crear el argumento de la lista de comandos
Elmétodo de subprocesoque permite ejecutarcomandosnecesitaelcomandoen formadeuna 
lista (al menos usando shell_mode=True ).
Las reglas para crear la lista no siempre son sencillas de seguir, especialmente con comandos 
complejos. Afortunadamente, hay una herramienta muy útil que permite hacer eso: shlex . La 
forma más fácil de crear la lista que se utilizará como comando es la siguiente:
Un ejemplo simple:
# Do logic on line read.
    185/1068
    121
shlex.split('ls --color -l -t -r')
out: ['ls', '--color', '-l', '-t', '-r']
    186/1068
    122
Capítulo 22: Bloques de código, marcos de 
ejecución y espacios de nombres.
Introducción
Un bloque de código es una parte del texto del programa Python que se puede ejecutar como una 
unidad, como un módulo, una definición de clase o un cuerpo de función. Algunos bloques de 
código (como módulos) normalmente se ejecutan solo una vez, otros (como cuerpos de función) 
pueden ejecutarse muchas veces. Los bloques de código pueden contener textualmente otros 
bloques de código. Los bloques de código pueden invocar otros bloques de código (que pueden o 
no estar contenidos textualmente en ellos) como parte de su ejecución, por ejemplo, invocando 
(llamando) una función.
Examples
Espacios de nombres de bloque de código
Tipo de bloque de 
código
Espacio de nombres 
global Espacio de nombres local
Módulo ns para el modulo igual que global
Script (archivo o 
comando) ns para main igual que global
Comando interactivo ns para main igual que global
Definición de clase ns globales del bloque 
que contiene nuevo espacio de nombres
Cuerpo de funcion ns globales del bloque 
que contiene nuevo espacio de nombres
Cadenapasada ala 
sentencia exec
ns globales del bloque 
que contiene
espacio de nombres local del 
bloque que contiene
Cadena pasada a eval()
ns global de la persona 
que llama ns locales de la persona que llama
Archivo leído por
execfile()
ns global de la persona 
que llama ns locales de la persona que llama
Expresión leída por
input()
ns global de la persona
que llama ns locales de la persona que llama
    187/1068
    123
    188/1068
    124
for x in ['one', 'two', 'three', 'four']: 
print(x)
one 
two
Capítulo 23: Bucles
Introducción
Como una de las funciones más básicas de la programación, los bucles son una pieza importante 
para casi todos los lenguajes de programación. Los bucles permiten a los desarrolladores 
configurar ciertas partes de su código para que se repitan a través de una serie de bucles que se 
conocen como iteraciones. Este tema cubre el uso de múltiples tipos de bucles y aplicaciones de 
bucles en Python.
Sintaxis
• mientras que <expresión booleana>:
• para <variable> en <iterable>:
• para <variable> en rango (<número>):
• para <variable> en el rango (<start_number>, <end_number>):
• para <variable> en el rango (<start_number>, <end_number>, <step_size>):
• para i, <variable> in enumerate (<iterable>): # con índice i
• para <variable1>, <variable2> en zip (<iterable1>, <iterable2>):
Parámetros
Parámetro Detalles
expresión 
booleana
Expresión que se puede evaluar en un contexto booleano, por ejemplo,
x < 10
variable Nombre de variable para el elemento actual del iterable
iterable cualquier cosa que implemente iteraciones
Examples
Iterando sobre listas
Para recorrer una lista puedes usar for :
Esto imprimirá los elementos de la lista:
    189/1068
    125
for x in range(1, 6): 
print(x)
1
2
3
4
5
forindex,iteminenumerate(['one','two','three','four']): 
print(index, '::', item)
x = map(lambda e : e.upper(), ['one', 'two', 'three', 'four']) 
print(x)
['ONE', 'TWO', 'THREE', 'FOUR'] # Python 2.x
La función de range genera números que también se utilizan a menudo en un bucle for.
El resultado será un tipo de secuencia de rango especial en python> = 3 y una lista en python <=
2. Ambos se pueden pasar usando el bucle for.
Si desea recorrer los elementos de una lista y también tener un índice para los elementos, puede 
usar la función de enumerate de Python:
enumerate generará tuplas, que se desempaquetan en index (un entero) y item (el valorreal de la 
lista). El bucle de arriba se imprimirá
(0, '::', 'one')
(1, '::', 'two')
(2, '::', 'three')
(3, '::', 'four')
Iterar sobre una lista con manipulación de valores usando map y lambda , es decir, aplicar la función 
lambda en cada elemento de la lista:
Salida:
NB: en Python 3.x map devuelve un iterador en lugar de una lista, por lo que, en caso de que 
necesite una lista, debe emitir la print(list(x)) del resultado print(list(x)) (consulte 
http://www.levcode.com/python/ example / 8186 / map-- en 
http://www.levcode.com/python/topic/809/incompatibilities-moving-from-python-2-to-python-3 ).
Para bucles
forbucles,repita una colección de elementos, como list o dict , y ejecute un bloque de código
three 
four
    190/1068
    126
for i in [0, 1, 2, 3, 4]: 
print(i)
0
1
2
3
4
for i in range(5): 
print(i)
i = 0
while i < 7:
print(i) 
if i == 4:
print("Breaking from loop") 
break
i += 1
con cada elemento de la colección.
Lo anterior for bucle se repite sobre una lista de números.
Cada iteración establece el valor de i en el siguiente elemento de la lista. Entonces primero será
0 , luego 1 , luego 2 , etc. La salida será la siguiente:
range es una función que devuelve una serie de números bajo una forma iterable, porlo que se 
puede utilizar en for bucles:
da exactamente el mismo resultado que el primer bucle for . Tenga en cuenta que 5 no se 
imprime, ya que el rango aquí corresponde a los primeros cinco números que cuentan desde 0 .
Objetos iterables e iteradores.
for loop puede iterar en cualquier objeto iterable que sea un objeto que defina una función
 getitem o iter . Lafunción iter devuelve uniterador, que es unobjeto con una 
función next que se utiliza para acceder al siguiente elemento delaiterable.
Romper y continuar en bucles
declaración de break
Cuando una instrucción de break ejecuta dentro de un bucle, el flujo de control se "interrumpe" 
inmediatamente:
El condicional de bucle no se evaluará después de que se ejecute la instrucción break . Tenga en
    191/1068
    127
0
1
2
3
4
Breaking from loop
for i in (0, 1, 2, 3, 4): 
print(i)
if i == 2:
break
0
1
2
for i in (0, 1, 2, 3, 4, 5): 
if i == 2 or i == 4:
continue 
print(i)
0
1
3
5
cuenta que las declaraciones de break solo se permiten dentro de los bucles , sintácticamente. No 
se puede usar una declaración de break dentro de una función para terminar los bucles que 
llamaron a esa función.
La ejecución de lo siguiente imprime cada dígito hasta el número 4 cuando se cumple la 
instrucción break y el bucle se detiene:
break declaraciones de break también se pueden usar dentro for bucles, la otra construcción de 
bucle proporcionada por Python:
La ejecución de este bucle ahora imprime:
Tenga en cuenta que 3 y 4 no se imprimen ya que el bucle ha finalizado.
Si un bucle tiene una cláusula else , no se ejecuta cuando el bucle termina a través de una 
instrucción de break .
continue declaración
Una instrucción de continue pasará a la siguiente iteración del bucle, omitiendo el resto del bloque 
actual pero continuando el bucle. Al igual que con break , continue solo puede aparecer dentro de 
los bucles:
Tenga en cuenta que 2 y 4 no se imprimen, esto se debe a que continue va a la siguiente iteración
    192/1068
    128
break # Will only break out of the inner loop!
while True:
for i inrange(1,5): 
if i == 2:
def break_loop():
for i in range(1, 5): 
if (i == 2):
return(i) 
print(i)
return(5)
def break_all():
for j in range(1, 5): 
for i inrange(1,4):
if i*j == 6:
return(i) 
print(i*j)
1 # 1*1
2 # 1*2
3 # 1*3
4 # 1*4
2 # 2*1
4 # 2*2
# return because 2*3 = 6, the remaining iterations of both loops are not executed
en lugar de continuar print(i) cuando i == 2 o i == 4 .
Bucles anidados
break y continue solo funciona en un solo nivel de bucle. El siguiente ejemplo solo saldrá del bucle
for interno, no del bucle while externo:
Python no tiene la capacidad de romper múltiples niveles de bucles a la vez; si se desea este 
comportamiento, refactorizar uno o más bucles en una función y reemplazar la break con el return 
puede ser la forma de hacerlo.
Usa el return desde dentro de una función como un break
La declaración de return sale de una función, sin ejecutar el código que viene después de ella.
Si tiene un bucle dentro de una función, usar el return desde dentro de ese bucle es equivalente a 
tener una break ya que el resto del código del bucle no se ejecuta ( tenga en cuenta que cualquier 
código después del bucle tampoco se ejecuta):
Si tiene bucles anidados, la instrucción de return romperá todos los bucles:
saldrá:
    193/1068
    129
for i in range(3): 
print(i)
else:
print('done')
i = 0
while i < 3:
print(i) 
i += 1
else:
print('done')
0
1
2
done
for i in range(2): 
print(i)
if i == 1:
break
else:
print('done')
0
1
Bucles con una cláusula "else"
Las declaraciones for y while (loops) pueden tener opcionalmente una cláusula else (en la 
práctica, este uso es bastante raro).
El else cláusula sólo se ejecuta después de un for bucle termina por iteración a la terminación, o 
después de un while bucle termina por su expresión condicional convertirse en falsa.
salida:
La cláusula else no se ejecuta si el bucle termina de alguna otra manera (a través de una 
declaración de break o al generar una excepción):
salida:
La mayoría de los otros lenguajes de programación carecen de esta cláusula else opcional de 
bucles. El uso de la palabra clave else en particular a menudo se considera confuso.
Elconceptooriginal para dicha cláusulase remonta aDonaldKnuth y el significado de la palabra 
claveelsequedaclarosireescribimosunbucleentérminosdedeclaracionesifygotodedías 
anterioresalaprogramaciónestructuradaodeunlenguajeensambladordenivel inferior.
Por ejemplo:
    194/1068
    130
# pseudocode
<<start>>:
if loop_condition():
...
if break_condition(): 
goto <<end>>
...
goto <<start>>
<<end>>:
# pseudocode
<<start>>:
if loop_condition():
...
if break_condition(): 
goto <<end>>
...
goto <<start>> 
else:
print('done')
<<end>>:
es equivalente a:
Estos siguen siendo equivalentes si adjuntamos una cláusula else a cada uno de ellos. 
Por ejemplo:
es equivalente a:
Un bucle for con una cláusula else puede entenderse de la misma manera. Conceptualmente, 
hayuna condición debucleque permanece verdadera mientrasel objetoolasecuenciaiterable 
aún tenga algunos elementos restantes.
¿Por qué uno usaría esta construcción extraña?
while loop_condition():
...
if break_condition(): 
break
...
else:
print('done')
while loop_condition():
...
if break_condition(): 
break
...
    195/1068
    131
a = [1, 2, 3, 4]
for i in a:
if type(i) is not int: 
print(i)
break
else:
print("no exception")
d = {"a": 1, "b": 2, "c": 3}
for key in d:
print(key)
"a"
"b"
"c"
for key in d.keys(): 
print(key)
for key in d.iterkeys(): 
print(key)
for value in d.values():
El caso de uso principal para la construcción for...else es una implementación concisa de 
búsqueda como por ejemplo:
Para hacer que la else de este constructo sea menos confuso, uno puede pensar en él como " si 
no se rompe " o " si no se encuentra ".
Algunas discusiones sobre esto se pueden encontrar en [Python-ideas] Resumen de los hilos de
for ... else , ¿Por qué python usa 'else' después de los bucles for y while? , y otras cláusulas en
declaraciones de bucle
Iterando sobre los diccionarios
Teniendo en cuenta el siguiente diccionario:
Para iterar a través de sus claves, puede utilizar:
Salida:
Esto es equivalente a:
o en Python 2:
Para iterar a través de sus valores, use:
    196/1068
    132
1
2
3
for key, value in d.items(): 
print(key, "::", value)
a :: 1
b ::2
c :: 3
i = 0
while i < 4:
#loop statements 
i = i + 1
myObject = anObject()
while myObject.isNotReady(): 
myObject.tryToGetReady()
Salida:
Para iterar a través de sus claves y valores, use:
Salida:
TengaencuentaqueenPython2,.keys(),.values()y.items()devuelvenunobjetodelist.Si 
simplementenecesitaiterarelresultado,puedeusarel.iterkeys(),.itervalues()y.iteritems().
La diferencia entre .keys() y .iterkeys() , .values() y .itervalues() , .items() y .iteritems() es 
quelosmétodos iter* songeneradores. Porlotanto, loselementosdentrodeldiccionario se 
producenunoporunoamedidaqueseevalúan. Cuandosedevuelveunobjeto delist ,todos 
loselementos se empaquetanenunalistay luegosedevuelvenparaunaevaluaciónadicional.
Tenga en cuenta también que en Python 3, el orden de los elementos impresos de la 
manera anterior no sigue ningún orden.
Mientras bucle
A while bucle hará que las sentencias de bucle que se ejecutarán hasta que la condición de bucle 
es Falsey . El siguiente código ejecutará las instrucciones de bucle un total de 4 veces.
Mientras que el bucle de arriba fácilmente se puede traducir en una más elegante for bucle, while 
los bucles son útiles para comprobar si alguna condición se ha cumplido. El siguiente bucle 
continuará ejecutándose hasta que myObject esté listo.
print(value)
    197/1068
    133
# Prints 1j forever
while complex_num: # You can also replace complex_num with any number, True or a value of
any type
print(complex_num)
import cmath
complex_num = cmath.sqrt(-1)
while True:
print "Infinite loop" 
# Infinite loop
# Infinite loop 
# Infinite loop 
# ...
for x in range(10):
pass #we don't want to do anything, or are not ready to do anything here, so we'll pass
while x == y: 
pass
while bucles también pueden ejecutarse sin unacondición usandonúmeros (complejos o reales) 
o True :
Si la condición es siempre cierta, el bucle while se ejecutará para siempre (bucle infinito) si no se 
termina con una instrucción break o return o una excepción.
La Declaración de Pase
pass es una declaración nulo para cuando una instrucción se requiere por la sintaxis Python (tal 
como dentro del cuerpo de un for o while bucle), pero se requiere ninguna acción o se desee por 
el programador. Esto puede ser útil como un marcador de posición para el código que aúnno se 
ha escrito.
En este ejemplo, nada pasará. El bucle for se completará sin error, pero no se ejecutará ningún 
comando o código. pass nos permite ejecutar nuestro código con éxito sin tener todos los 
comandos y acciones completamente implementados.
Del mismo modo, pass puede ser utilizado en while bucles, así como en las selecciones y 
definiciones de función, etc.
Iterando diferentes partes de una lista con diferentes tamaños de paso
Supongamos que tiene una larga lista de elementos y solo está interesado en todos los demás 
elementos de la lista. Quizás solo desee examinar los primeros o últimos elementos, o un rango 
específico de entradas en su lista. Python tiene capacidades integradas de indexación fuertes. 
Aquí hay algunos ejemplos de cómo lograr estos escenarios.
Aquí hay una lista simple que se utilizará a lo largo de los ejemplos:
    198/1068
    134
for s in lst:
print s[:1] # print the first letter
a 
b 
c 
d 
e
for idx, s in enumerate(lst):
print("%s has an index of %d" % (s, idx))
alpha has an index of 0 
bravo has an index of 1 
charlie has an index of 2 
delta has an index of 3 
echo has an index of 4
for i in range(2,4):
print("lst at %d contains %s" % (i, lst[i]))
lst at 2 contains charlie 
lst at 3 contains delta
Iteración sobre toda la lista.
Para iterar sobre cada elemento de la lista, se puede usar un bucle for como abajo:
El bucle for asigna s para cada elemento de lst . Esto imprimirá:
A menudo necesitas tanto el elemento como el índice de ese elemento. La palabra clave
enumerate realiza esa tarea.
El índice idx comenzará con cero e incrementará para cada iteración, mientras que la s contendrá 
el elemento que se está procesando. El fragmento anterior se mostrará:
Iterar sobre la sub-lista
Si queremos iterar sobre un rango (recordando que Python usa indexación de base cero), use la 
palabra clave de range .
Esto daría como resultado:
La lista también puede ser cortada. La siguiente notación de segmento va desde el elemento en
lst = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
    199/1068
    135
for s in lst[1::2]: 
print(s)
for i in range(1, len(lst), 2): 
print(lst[i])
bravo 
delta
a = 10
while True:
a = a-1 
print(a) 
if a<7:
break 
print('Done.')
9
8
7
6
Done.
collection = [('a', 'b', 'c'), ('x', 'y', 'z'), ('1', '2', '3')]
for item in collection: 
i1 = item[0]
i2 = item[1] 
i3 = item[2] 
# logic
el índice 1 hasta el final con un paso de 2. Los dos bucles for dan el mismo resultado.
Las salidas de fragmento de código anteriores:
La indexación y el corte es un tema propio.
El "half loop" do-while
A diferencia de otros idiomas, Python no tiene una construcción do-until o do-while (esto permitirá 
que el código se ejecute una vez antes de que se pruebe la condición). Sin embargo, puede 
combinar un while True con una break para lograr el mismo propósito.
Esto imprimirá:
Bucle y desembalaje
Si quieres recorrer una lista de tuplas por ejemplo:
En lugar de hacer algo como esto:
    200/1068
    136
for item in collection: 
i1, i2, i3 = item
# logic
for i1, i2, i3 in collection: 
# logic
o algo como esto:
Simplemente puede hacer esto:
Esto también funcionará para la mayoría de los tipos de iterables, no solo para tuplas.
    201/1068
    137
# 4
# 20
astring.find('o')
astring.rfind('o')
astring = 'Hello on StackOverflow' 
astring.index('o') # 4
astring.rindex('o') # 20
astring.index('q') # ValueError: substring not found 
astring.find('q') # -1
astring.index('o', 5) # 6
astring.index('o', 6) # 6 - start is inclusive 
astring.index('o', 5, 7) # 6
astring.index('o', 5, 6) # - end is not inclusive
astring.rindex('o', 20) # 20
astring.rindex('o', 19) # 20 - still from left to right
astring.rindex('o', 4, 7) # 6
Capítulo 24: buscando
Observaciones
Todos los algoritmos de búsqueda en iterablesque contienen n elementos tienen complejidad 
O(n) . Solo los algoritmos especializados como bisect.bisect_left() pueden ser más rápidos con 
complejidad O(log(n)) .
Examples
Obtención del índice para cadenas: str.index (), str.rindex () y str.find (), 
str.rfind ()
String también tiene un método de index , pero también opciones más avanzadas y la función
str.find adicional. Para ambos hay un método inverso complementario.
Ladiferenciaentreindex / rindex y find /rfindesloquesucedesi lasubcadena noseencuentra 
en la cadena:
Todos estos métodos permiten un índice de inicio y finalización:
ValueError: subcadena no encontrada
Buscando un elemento
Todaslas colecciones integradasenPythonimplementanunaformadeverificarlapertenenciaal 
elemento usando in .
    202/1068
    138
alist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5 in alist # True 
10 in alist # False
atuple = ('0', '1', '2', '3', '4')
4 in atuple # False 
'4' in atuple # True
astring = 'i am a string' 
'a' in astring # True 
'am' in astring # True 
'I' in astring #False
aset = {(10, 10), (20, 20), (30, 30)}
(10, 10) in aset # True 
10 in aset # False
- explicitly searches in keys
- explicitly searches in values
- explicitly searches key/value pairs
# True - implicitly searches in keys
# False 
# True 
# True 
# True
1 in adict 
'a' in adict
2 in adict.keys()
'a' in adict.values() 
(0, 'a') inadict.items()
adict = {0: 'a', 1: 'b', 2: 'c', 3: 'd'}
alist = [10, 16, 26, 5, 2, 19, 105, 26]
# search for 16 in the list 
alist.index(16) # 1
alist[1] # 16
alist.index(15)
Lista
Tupla
Cuerda
Conjunto
Dictado
dict es un poco especial: lo normal in sólo comprueba las teclas. Si desea buscar en valores
necesita especificarlo. Lo mismo si quieres buscar pares clave-valor .
Obtención de la lista de índice y las tuplas: list.index (), tuple.index ()
list y tuple tienen un método de index para obtener la posición del elemento:
ValueError: 15 no está en la lista
    203/1068
    139
atuple = (10, 16, 26, 5, 2, 19, 105, 26)
atuple.index(26) # 2
atuple[2] # 26
atuple[7] # 26 - is also 26!
def getKeysForValue(dictionary, value): 
foundkeys = []
for keys in dictionary:
if dictionary[key] == value: 
foundkeys.append(key)
return foundkeys
def getKeysForValueComp(dictionary, value):
return [key for key in dictionary if dictionary[key] == value]
def getOneKeyForValue(dictionary, value):
return next(key for key in dictionary if dictionary[key] == value)
getKeysForValueComp(adict, 10) # ['c', 'a'] - dito 
getKeysForValueComp(adict, 20) # ['b']
getKeysForValueComp(adict, 25) # []
getKeysForValue(adict, 10) # ['c', 'a'] - order is random could as well be ['a', 'c']
adict = {'a': 10, 'b': 20, 'c': 10}
getOneKeyForValue(adict, 10) # 'c' - depending on the circumstances this could also be 'a' 
getOneKeyForValue(adict, 20) # 'b'
getOneKeyForValue(adict, 25)
Pero solo devuelve la posición del primer elemento encontrado:
Buscando clave (s) para un valor en dict
dict no tiene un método incorporado para buscar un valor o clave porque los diccionarios no 
están ordenados. Puede crear una función que obtenga la clave (o claves) para un valor 
específico:
Esto también podría escribirse como una lista de comprensión equivalente:
Si solo te importa una clave encontrada:
Lasprimeras dosfunciones devolverán unalist de todaslaskeys quetienen el valor 
especificado:
El otro solo devolverá una clave:
y levante un StopIteration - Exception si el valor no está en el dict :
StopIteration
    204/1068
    140
import bisect
def index_sorted(sorted_seq, value):
"""Locate the leftmost value exactly equal to x or raise a ValueError""" 
i = bisect.bisect_left(sorted_seq, value)
ifi!=len(sorted_seq)andsorted_seq[i]==value: 
return i
raise ValueError
alist = [i for i in range(1, 100000, 3)] # Sorted list from 1 to 100000 with step 3 
index_sorted(alist, 97285) # 32428
index_sorted(alist, 4) # 1
index_sorted(alist, 97286)
%timeit index_sorted(alist, 97285)
# 100000 loops, best of 3: 3 µs per loop
%timeit alist.index(97285)
# 1000 loops, best of 3: 1.58 ms per loop
%timeit index_sorted(alist, 4)
# 100000 loops, best of 3: 2.98 µs per loop
%timeit alist.index(4)
# 1000000 loops, best of 3: 580 ns per loop
def outer_index(nested_sequence, value):
return next(index for index, inner in enumerate(nested_sequence) 
for item in inner
if item == value)
alist_of_tuples = [(4, 5, 6), (3, 1, 'a'), (7, 0, 4.3)] 
outer_index(alist_of_tuples, 'a') # 1 
outer_index(alist_of_tuples, 4.3) # 2
Obtención del índice para secuencias ordenadas: bisect.bisect_left ()
Las secuencias ordenadas permiten el uso de algoritmos de búsqueda más rápidos:
bisect.bisect_left() 1 :
ValueError
Para secuencias clasificadas muy grandes , la ganancia de velocidad puede ser bastante alta. 
En caso de que la primera búsqueda sea aproximadamente 500 veces más rápida:
Si bien es un poco más lento si el elemento es uno de los primeros:
Buscando secuencias anidadas
Labúsqueda ensecuencias anidadas comounalist detuple requiere unenfoquecomola 
búsqueda de valores en dict pero necesita funciones personalizadas.
El índice de la secuencia más externa si el valor se encontró en la secuencia:
o el índice de la secuencia externa e interna:
    205/1068
    141
class ListList:
def init (self, value): 
self.value = value
# Create a set of all values for fast access
self.setofvalues = set(item for sublist in self.value for item in sublist)
def iter (self): 
print('Using iter .')
# A generator over all sublist elements
return (item for sublist in self.value for item in sublist)
def contains (self, value): 
print('Usingcontains.')
# Just lookup if the value is in the set 
return value in self.setofvalues
# Even without the set you could use the iter method for the contains-check: 
# return any(item == value for item in iter(self))
a = ListList([[1,1,1],[0,1,1],[1,5,1]])
10 in a # False
# Prints: Using contains . 
5 in a # True
# Prints: Using contains .
del ListList. contains
5 in a # True
# Prints: Using iter .
En general ( no siempre ) el uso del next y una expresión generadora con condiciones para 
encontrar la primera aparición del valor buscado es el enfoque más eficiente.
Búsqueda en clases personalizadas: contains y iter
Para permitirel uso de in para clases personalizadas, la clase debe proporcionar el método 
mágico contains o, en su defecto, un método iter .
Supongamos que tiene una clase que contiene una list de list s:
Usarla prueba de membresía es posible usando in :
Incluso después de eliminar el método contains :
def outer_inner_index(nested_sequence, value):
return next((oindex, iindex) for oindex, inner in enumerate(nested_sequence)
for iindex, item in enumerate(inner) 
if item == value)
outer_inner_index(alist_of_tuples, 'a') # (1, 2) 
alist_of_tuples[1][2] # 'a'
outer_inner_index(alist_of_tuples, 7) # (2, 0)
alist_of_tuples[2][0] # 7
    206/1068
    142
Nota:El buclein (como enfor i in a ) siempre usará iter inclusosi laclaseimplementaun 
método contains .
    207/1068
    143
class Vector(object): 
def init (self, x, y):
self.x = x 
self.y = y
def add (self, v):
# Addition with another vector.
return Vector(self.x + v.x, self.y + v.y)
def sub (self, v):
# Subtraction with another vector.
return Vector(self.x - v.x, self.y - v.y)
def mul (self, s):
# Multiplication with a scalar. 
return Vector(self.x * s, self.y * s)
def div (self, s):
# Division with a scalar. 
float_s = float(s)
return Vector(self.x / float_s, self.y / float_s)
def floordiv (self, s):
# Divisionwith a scalar (value floored). 
return Vector(self.x // s, self.y // s)
def repr (self):
# Print friendly representation of Vector class. Else, it would 
# show up like, < main .Vector instance at 0x01DDDDC8>. 
return '<Vector (%f, %f)>' % (self.x, self.y, )
a = Vector(3, 5) 
b = Vector(2, 7)
print a + b # Output: <Vector (5.000000, 12.000000)> 
print b - a # Output: <Vector (-1.000000, 2.000000)> 
print b * 1.3 # Output: <Vector (2.600000, 9.100000)>
print a // 17 # Output: <Vector (0.000000, 0.000000)>
Capítulo 25: Características ocultas
Examples
Sobrecarga del operador
Todo en Python es un objeto. Cada objeto tiene algunos métodos internos especiales que utiliza 
para interactuar con otros objetos. En general, estos métodos siguen la convención de 
denominación action . En conjunto, esto se denomina como el modelo de datos de Python .
Puedesobrecargar cualquieradeestosmétodos.Estoseusacomúnmenteenlasobrecargade 
operadoresenPython.A continuación se muestra un ejemplo de sobrecarga de operadores 
utilizando el modelo de datos de Python. La clase Vector crea un vector simple de dos variables. 
Agregaremoselsoporteadecuadoparaoperacionesmatemáticasdedosvectoresutilizandola 
sobrecarga de operadores.
    208/1068
    144
El ejemplo anterior demuestra la sobrecarga de operadores numéricos básicos. Una lista 
completa se puede encontrar aquí .
print a / 17 # Output: <Vector (0.176471, 0.294118)>
    209/1068
    145
from chempy import Substance
ferricyanide = Substance.from_formula('Fe(CN)6-3') 
ferricyanide.composition == {0: -3, 26: 1, 6: 6, 7: 6}
True 
print(ferricyanide.unicode_name)
Fe(CN)₆ ³⁻
print(ferricyanide.latex_name + ", " + ferricyanide.html_name) 
Fe(CN)_{6}^{3-}, Fe(CN)<sub>6</sub><sup>3-</sup>
print('%.3f' % ferricyanide.mass) 
211.955
from chempy import balance_stoichiometry # Main reaction in NASA's booster rockets: 
reac, prod = balance_stoichiometry({'NH4ClO4', 'Al'}, {'Al2O3', 'HCl', 'H2O', 'N2'}) 
from pprint import pprint
pprint(reac)
{'Al': 10, 'NH4ClO4': 6}
pprint(prod)
{'Al2O3': 5, 'H2O': 9, 'HCl': 6, 'N2': 3}
from chempy import mass_fractions
for fractions in map(mass_fractions, [reac, prod]):
... pprint({k: '{0:.3g} wt%'.format(v*100) for k, v in fractions.items()})
...
{'Al': '27.7 wt%', 'NH4ClO4': '72.3 wt%'}
{'Al2O3': '52.3 wt%', 'H2O': '16.6 wt%', 'HCl': '22.4 wt%', 'N2': '8.62 wt%'}
from chempy import Equilibrium 
from sympy import symbols
K1, K2, Kw = symbols('K1 K2 Kw')
e1 = Equilibrium({'MnO4-': 1, 'H+': 8, 'e-': 5}, {'Mn+2': 1, 'H2O': 4}, K1)
e2 = Equilibrium({'O2': 1, 'H2O': 2, 'e-': 4}, {'OH-': 4}, K2)
coeff = Equilibrium.eliminate([e1, e2], 'e-')
Capítulo 26: ChemPy - paquete de python
Introducción
ChemPy es un paquete de Python diseñado principalmente para resolver y abordar problemas en 
Química física, analítica e inorgánica. Es un conjunto de herramientas gratuito de código abierto 
de Python para aplicaciones de química, ingeniería química y ciencia de materiales.
Examples
Fórmulas de análisis
En composición, los números atómicos (y 0 para carga) se usan como claves y el recuento de 
cada tipo se convirtió en valor respectivo.
Equilibrio de la estequiometría de una reacción química.
Reacciones de equilibrio
    210/1068
    146
from collections import defaultdict
init_conc = defaultdict(float, {'H2O': 1, 'NH3': 0.1}) 
x, sol, sane = eqsys.root(init_conc)
assert sol['success'] and sane
print(sorted(sol.keys())) # see package "pyneqsys" for more info
['fun', 'intermediate_info', 'internal_x_vecs', 'nfev', 'njev', 'success', 'x', 'x_vecs'] 
print(', '.join('%.2g' % v for v in x))
1, 0.0013, 7.6e-12, 0.099, 0.0013
print('\n'.join(map(str, eqsys.rxns))) # "rxns" short for "reactions"
H2O = H+ + OH-; 1e-14
NH4+ = H+ + NH3; 5.75e-10
from chempy import Equilibrium
from chempy.chemistry import Species
water_autop = Equilibrium({'H2O'}, {'H+', 'OH-'}, 10**-14) # unit "molar" assumed 
ammonia_prot = Equilibrium({'NH4+'}, {'NH3', 'H+'}, 10**-9.24) # same here
from chempy.equilibria import EqSystem
substances = map(Species.from_formula, 'H2O OH- H+ NH3 NH4+'.split()) 
eqsys = EqSystem([water_autop, ammonia_prot], substances)
from chempy.electrolytes import ionic_strength 
ionic_strength({'Fe+3': 0.050, 'ClO4-': 0.150}) == .3
True
from chempy import ReactionSystem # The rate constants below are arbitrary 
rsys = ReactionSystem.from_string("""2 Fe+2 + H2O2 -> 2 Fe+3 + 2 OH-; 42
2 Fe+3 + H2O2 -> 2 Fe+2 + O2 + 2 H+; 17 
H+ + OH- -> H2O; 1e10
H2O -> H+ + OH-; 1e-4
Fe+3 + 2 H2O -> FeOOH(s) + 3 H+; 1
FeOOH(s) + 3 H+ -> Fe+3 + 2 H2O; 2.5""") # "[H2O]" = 1.0 (actually 55.4 at RT)
from chempy.kinetics.ode import get_odesys 
odesys, extra = get_odesys(rsys)
from collections import defaultdict 
import numpy as np
tout = sorted(np.concatenate((np.linspace(0, 23), np.logspace(-8, 1))))
c0 = defaultdict(float, {'Fe+2': 0.05, 'H2O2': 0.1, 'H2O': 1.0, 'H+': 1e-7, 'OH-': 1e-7})
result = odesys.integrate(tout, c0, atol=1e-12, rtol=1e-14)
Equilibrios quimicos
Fuerza iónica
Cinética química (sistema de ecuaciones diferenciales ordinarias)
coeff 
[4, -5]
redox = e1*coeff[0] + e2*coeff[1] 
print(redox)
20 OH- + 32 H+ + 4 MnO4- = 26 H2O + 4 Mn+2 + 5 O2; K1**4/K2**5
autoprot = Equilibrium({'H2O': 1}, {'H+': 1, 'OH-': 1}, Kw) 
n = redox.cancel(autoprot)
n 
20
redox2 = redox + n*autoprot 
print(redox2)
12 H+ + 4 MnO4- = 4 Mn+2 + 5 O2 + 6 H2O; K1**4*Kw**20/K2**5
    211/1068
    147
import matplotlib.pyplot as plt
_ = plt.subplot(1, 2, 1)
_ = result.plot(names=[k for k in rsys.substances if k != 'H2O'])
_ = plt.legend(loc='best', prop={'size': 9}); _ = plt.xlabel('Time'); _ = 
plt.ylabel('Concentration')
_ = plt.subplot(1, 2, 2)
_ = result.plot(names=[k for k in rsys.substances if k != 'H2O'], xscale='log', yscale='log')
_ = plt.legend(loc='best', prop={'size': 9}); _ = plt.xlabel('Time'); _ = 
plt.ylabel('Concentration')
_ = plt.tight_layout() 
plt.show()
    212/1068
    148
class Fruit:
def check_ripeness(self):
raise NotImplementedError("check_ripeness method not implemented!")
class Apple(Fruit): 
pass
a = Apple()
a.check_ripeness() # raises NotImplementedError
from abc import ABCMeta
class AbstractClass(object):
# the metaclass attribute must always be set as a class variable
 metaclass = ABCMeta
# the abstractmethod decorator registers this method as undefined 
@abstractmethod
def virtual_method_subclasses_must_define(self):
# Can be left completely blank, or a base implementation can be provided 
# Note that ordinarily a blank interpretation implicitly returns `None`, 
# but by registering, this behaviour is no longer enforced.
Capítulo 27: Clases base abstractas (abc)
Examples
Configuración de la metaclase ABCMeta
Las clases abstractas son clases que están destinadas a ser heredadas pero evitan la 
implementación de métodos específicos, dejando atrás solo las firmas de métodos que las 
subclases deben implementar.
Las clases abstractas son útiles para definir y hacer cumplir las abstracciones de clase a un alto 
nivel, similar al concepto de interfaces en lenguajes escritos, sin la necesidad de implementar 
métodos.
Un enfoque conceptual para definir una clase abstracta es eliminar los métodos de la clase y, a 
continuación, generar un error NotImplemented si se accede. Esto evita que las clases de niños 
accedan a los métodos de los padres sin anularlos primero. Al igual que:
La creación de una clase abstracta de esta manera evita el uso incorrecto de métodos que no se 
anulan, y ciertamente alienta a los métodos a ser definidos en clases secundarias, pero no 
impone su definición. Con el módulo abc podemos evitar que las clases secundarias se instalen 
cuando no pueden anular los métodos de clase abstracta de sus padres y ancestros:
Ahora es posible simplemente subclasificar y anular:
    213/1068
    149
class MontyPython: 
def joke(self):
raise NotImplementedError()
def punchline(self):
raise NotImplementedError()
class ArgumentClinic(MontyPython): 
def joke(self):
return "Hahahahahah"
>>> sketch = ArgumentClinic()
>>> sketch.punchline() 
NotImplementedError
from abc import ABCMeta, abstractmethod
class MontyPython(metaclass=ABCMeta): 
@abstractmethod
def joke(self): 
pass
@abstractmethod
def punchline(self): 
pass
class ArgumentClinic(MontyPython): 
def joke(self):
return "Hahahahahah"
Por qué / Cómo usar ABCMeta y @abstractmethod
Las clases base abstractas (ABC) imponen qué clases derivadas implementan métodos 
particulares de la clase base.
Para entender cómo funciona esto y por qué debemos usarlo, echemos un vistazo a un ejemplo 
que Van Rossum disfrutaría. Digamos que tenemos una clase base "MontyPython" con dos 
métodos (broma y línea de remate) que deben ser implementados por todas las clases derivadas.
Cuando creamos una instancia de un objeto y llamamos a sus dos métodos, obtendremos un 
error (como se esperaba) con el método punchline() .
Sin embargo, esto todavía nos permite crear una instancia de un objeto de la clase 
ArgumentClinic sin obtener un error. De hecho, no recibimos un error hasta que buscamos el 
punchline ().
Esto se evita utilizando el módulo de clase base abstracta (ABC). Veamos cómo funciona esto 
con el mismo ejemplo:
class Subclass(AbstractClass):
def virtual_method_subclasses_must_define(self): 
return
    214/1068
    150
>>> c = ArgumentClinic() 
TypeError:
"Can't instantiate abstract class ArgumentClinic with abstract methods punchline"
class ArgumentClinic(MontyPython): 
def joke(self):
return "Hahahahahah"
def punchline(self):
return "Send in the constable!"
Esta vez, cuando intentamos crear una instancia de un objeto de la clase incompleta,
¡inmediatamente obtenemos un TypeError!
En este caso, es fácil completar la clase para evitar cualquier TypeErrors:
¡Esta vez cuando creas un objeto, funciona!
    215/1068
    151
min(7,2,1,5)
# Output: 1
max(7,2,1,5)
# Output: 7
list_of_tuples = [(0, 10), (1, 15), (2, 8)] 
min(list_of_tuples)
# Output: (0, 10)
import operator
# The operator module contains efficient alternatives to the lambda function 
max(list_of_tuples, key=operator.itemgetter(0)) # Sorting by first element 
# Output: (2, 8)
max(list_of_tuples, key=operator.itemgetter(1)) # Sorting by second element 
# Output: (1, 15)
sorted(list_of_tuples, key=operator.itemgetter(0), reverse=True) #Reversed (decreasing) 
# Output: [(2, 8), (1, 15), (0, 10)]
sorted(list_of_tuples, key=operator.itemgetter(1), reverse=True) # Reversed(decreasing) 
# Output: [(1, 15), (0, 10), (2, 8)]
sorted(list_of_tuples, key=lambda x: x[1]) # Sorting by first element
# Output: [(2, 8), (0, 10), (1, 15)]
sorted(list_of_tuples, key=lambda x: x[0]) # Sorting byfirst element (increasing)
# Output: [(0, 10), (1, 15), (2, 8)]
min(list_of_tuples, key=lambda x: x[1]) # Sorting by second element
# Output: (2, 8)
min(list_of_tuples, key=lambda x: x[0]) # Sorting by first element
# Output: (0, 10)
Capítulo 28: Clasificación, mínimo y máximo
Examples
Obteniendo el mínimo o máximo de varios valores.
Usando el argumento clave
Encontrar el mínimo / máximo de una secuencia de secuencias es posible:
pero si desea ordenar por un elemento específico en cada secuencia, use la key -argumento:
Argumento predeterminado a max, min
No puedes pasar una secuencia vacía a max o min :
    216/1068
    152
max([], default=42) 
# Output: 42 
max([], default=0) 
# Output: 0
adict = {'a': 3, 'b': 5, 'c': 1} 
min(adict)
# Output:'a' 
max(adict)
# Output: 'c' 
sorted(adict)
# Output: ['a', 'b', 'c']
min(adict.items()) 
# Output: ('a', 3) 
max(adict.items()) 
# Output: ('c', 1)
sorted(adict.items())
# Output: [('a', 3), ('b', 5), ('c', 1)]
from collections import OrderedDict 
OrderedDict(sorted(adict.items()))
# Output: OrderedDict([('a', 3), ('b', 5), ('c', 1)]) 
res = OrderedDict(sorted(adict.items()))
res['a']
# Output: 3
min(adict.items(), key=lambda x: x[1])
# Output: ('c', 1)
ValueError: min () arg es una secuencia vacía
Sin embargo, con Python 3, puede pasar el default argumento de palabra clave con un valor que 
se devolverá si la secuencia está vacía, en lugar de generar una excepción:
Caso especial: diccionarios
Obtener el mínimo o el máximo o usar sorted depende de las iteraciones sobre el objeto. En el 
caso de dict , la iteración es solo sobre las teclas:
Para mantener la estructura del diccionario, debe iterar sobre .items() :
Para sorted , puede crear un OrderedDict para mantenerla clasificación mientras tiene una 
estructura similar a un dict :
Por valor
De nuevo, esto es posible usando el argumento key :
min([])
    217/1068
    153
sorted('bdca') # string
# Output: ['a','b','c','d']
sorted({'11': 5, '3': 2, '10': 15}) # dict
# Output: ['10', '11', '3'] # only iterates over the keys
sorted({11, 8, 1}) # set
# Output: [1, 8, 11]
sorted(['c', 'A', 'b']) # list
# Output: ['A', 'b', 'c']
sorted((7, 2, 1, 5)) # tuple
# Output: [1, 2, 5, 7]
min([2, 7, 5])
# Output: 2
sorted([2, 7, 5])[0]
# Output: 2
max([2, 7, 5])
# Output: 7
sorted([2, 7, 5])[-1]
# Output: 7
class MyClass(object):
def init (self, value, name): 
self.value = value 
self.name =name
def lt (self, other):
Obteniendo una secuencia ordenada
Usando una secuencia:
El resultado es siempre una nueva list ; Los datos originales se mantienen sin cambios.
Mínimo y máximo de una secuencia.
Obtener el mínimo de una secuencia (iterable) es equivalente a acceder al primer elemento de 
una secuencia sorted :
El máximo es un poco más complicado, porque sorted mantiene el orden y max devuelve el primer 
valor encontrado. En caso de que no haya duplicados, el máximo es el mismo que el último 
elemento de la declaración ordenada:
Pero no si hay varios elementos que se evalúan como teniendo el valor máximo:
max(adict.items(), key=operator.itemgetter(1)) 
# Output: ('b', 5)
sorted(adict.items(), key=operator.itemgetter(1), reverse=True) 
# Output: [('b', 5), ('a', 3), ('c', 1)]
    218/1068
    154
class IntegerContainer(object): 
def init (self, value):
self.value = value
def repr (self):
return "{}({})".format(self. class . name , self.value)
def lt (self, other):
print('{!r} - Test less than {!r}'.format(self, other)) 
return self.value < other.value
def le (self, other):
print('{!r} - Test less than or equal to {!r}'.format(self, other)) 
return self.value <= other.value
def gt (self, other):
print('{!r} - Test greater than {!r}'.format(self, other)) 
return self.value > other.value
def ge (self, other):
print('{!r} - Test greater than or equal to {!r}'.format(self, other)) 
return self.value >= other.value
def eq (self, other):
print('{!r} - Test equal to {!r}'.format(self, other)) 
return self.value == other.value
def ne (self, other):
print('{!r} - Test not equal to {!r}'.format(self, other)) 
return self.value != other.value
alist = [IntegerContainer(5), IntegerContainer(3), 
IntegerContainer(10), IntegerContainer(7)
Se permite cualquier elemento que contenga iterable que admita < o > operaciones.
Hacer clases personalizables ordenable
min,maxysorted todosnecesitanquelosobjetossepuedanordenar.Paraserordenados 
adecuadamente,laclasenecesitadefinirtodoslos6métodos lt , gt , ge , le ,
 ne y eq :
Aunque implementar todos estos métodos parece innecesario, omitir algunos de ellos hará que su
código sea propenso a errores .
Ejemplos:
return self.value < other.value
def repr (self): 
return str(self.name)
sorted([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')]) 
# Output: [second, first, third]
max([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')]) 
# Output: first
    219/1068
    155
res = sorted(alist, reverse=True)
# Out: IntegerContainer(10) - Test less than IntegerContainer(7) 
# IntegerContainer(3) - Test less than IntegerContainer(10) 
# IntegerContainer(3) - Test less than IntegerContainer(10) 
# IntegerContainer(3) - Test less than IntegerContainer(7) 
# IntegerContainer(5) - Test less than IntegerContainer(7) 
# IntegerContainer(5) - Test less than IntegerContainer(3) 
print(res)
# Out: [IntegerContainer(10), IntegerContainer(7), IntegerContainer(5), IntegerContainer(3)]
del IntegerContainer. lt # The IntegerContainer no longer implements "less than"
res = min(alist)
# Out: IntegerContainer(5) - Test greater than IntegerContainer(3) 
# IntegerContainer(3) - Test greater than IntegerContainer(10) 
# IntegerContainer(3) - Test greater than IntegerContainer(7) 
print(res)
# Out: IntegerContainer(3)
del IntegerContainer. gt # The IntegerContainer no longer implements "greater then"
res = min(alist)
sorted con reverse=True también usa lt :
Pero sorted puede usar gt cambio si el valor predeterminado no está implementado:
Losmétodosdeclasificación generaránunTypeErrorsinoseimplementan lt ni gt :
TypeError: tipos no ordenados: IntegerContainer () <IntegerContainer ()
]
res = max(alist)
# Out: IntegerContainer(3) - Test greater than IntegerContainer(5) 
# IntegerContainer(10) - Test greater than IntegerContainer(5) 
# IntegerContainer(7) - Test greater than IntegerContainer(10) 
print(res)
# Out: IntegerContainer(10)
res = min(alist)
# Out: IntegerContainer(3) - Test less than IntegerContainer(5) 
# IntegerContainer(10) - Test less than IntegerContainer(3) 
# IntegerContainer(7) - Test less than IntegerContainer(3) 
print(res)
# Out: IntegerContainer(3)
res = sorted(alist)
# Out: IntegerContainer(3) - Test less than IntegerContainer(5) 
# IntegerContainer(10) - Test less than IntegerContainer(3) 
# IntegerContainer(10) - Test less than IntegerContainer(5) 
# IntegerContainer(7) - Test less than IntegerContainer(5) 
# IntegerContainer(7) - Test less than IntegerContainer(10) 
print(res)
# Out: [IntegerContainer(3), IntegerContainer(5), IntegerContainer(7), IntegerContainer(10)]
    220/1068
    156
import functools
@functools.total_ordering
class IntegerContainer(object): 
def init (self, value):
self.value = value
def repr (self):
return "{}({})".format(self. class . name , self.value)
def lt (self, other):
print('{!r} - Test less than {!r}'.format(self, other)) 
return self.value < other.value
def eq (self, other):
print('{!r} - Test equal to {!r}'.format(self, other)) 
return self.value == other.value
def ne (self, other):
print('{!r} - Test not equal to {!r}'.format(self, other)) 
return self.value != other.value
IntegerContainer(5) > IntegerContainer(6)
# Output: IntegerContainer(5) - Test less than IntegerContainer(6) 
# Returns: False
IntegerContainer(6) > IntegerContainer(5)
# Output: IntegerContainer(6) - Test less than IntegerContainer(5) 
# Output: IntegerContainer(6) - Test equal to IntegerContainer(5) 
# Returns True
import heapq
# get 5 largest items from the range 
heapq.nlargest(5, range(10))
# Output: [9, 8, 7, 6, 5]
heapq.nsmallest(5, range(10)) 
# Output: [0, 1, 2, 3, 4]
functools.total_orderingdecoradorfunctools.total_ordering sepuedeutilizarparasimplificarel 
esfuerzodeescribirestosmétodosdecomparaciónricos.Sitotal_orderingtuclasecon 
total_ordering , necesitasimplementar eq , ne ysolo uno delos lt , le , ge o
 gt , y el decorador completará el resto:
Observe cómo el > ( mayor que ) ahora llama al método menos que , y en algunos casos incluso 
el método eq . Esto también significa que si la velocidad es de gran importancia, debe 
implementar cada método de comparación enriquecida.
Extraer N artículos más grandes o N más pequeños de un iterable
Para encontrar un número (más de uno)delos valores más grandes o más pequeños de un 
iterable, puede usar el nlargest y nsmallest del módulo heapq :
    221/1068
    157
longest_lines = sorted(f, key=len)[1000:]
import heapq
with open(filename) as f:
longest_lines = heapq.nlargest(1000, f, key=len)
Esto es mucho más eficiente que clasificar todo el material y luego cortarlo desde el final o el 
principio. Internamente, estas funciones utilizan la estructura de datos de la cola de prioridad del
montón binario , que es muy eficiente para este caso de uso.
Al igual que min , max y sorted , estas funciones aceptan el argumento de palabra key clave 
opcional,quedebe serunafunciónque,dado unelemento,devuelvesu clavedeclasificación.
Aquí hay un programa que extrae 1000 líneas más largas de un archivo:
Aquí abrimos el archivo y pasamos el identificador de archivo f a nlargest . La iteración del 
archivoproducecadalíneadelarchivocomounacadenaseparada; nlargestluegopasacada 
elemento(olínea)quepasaalafunciónlenparadeterminarsuclavedeclasificación.len,dada 
una cadena, devuelve la longitud de la línea en caracteres.
Esto solo necesita almacenamiento para una lista de 1000 líneas más grandes hasta el momento, 
que se puede contrastar con
que tendrá que mantener todo el archivo en la memoria .
    222/1068
    158
# This is a single line comment in Python
print("Hello World") # This line prints "HelloWorld"
"""
This type of comment spans multiple lines.
These are mostly used for documentation of functions, classes and modules. 
"""
Capítulo 29: Comentarios y Documentación
Sintaxis
• # Este es un comentario de una sola línea.
• imprimir ("") # Este es un comentario en línea
• ""
Esto es
un comentario multilínea 
""
Observaciones
Los desarrolladores deben seguir las pautas PEP257 - Docstring Convenciones . En algunos 
casos, las guías de estilo (como las de la Guía de estilo de Google ) o la documentación que 
muestra a terceros (como Sphinx ) pueden detallar convenciones adicionales para las cadenas de 
documentación.
Examples
Comentarios de línea única, en línea y multilínea.
Los comentarios se utilizan para explicar el código cuando el código básico en sí no está claro.
Python ignora los comentarios, por lo que no ejecutará el código allí, ni generará errores de 
sintaxis para las oraciones simples en inglés.
Los comentarios de una sola línea comienzan con el carácter de hash ( # ) y terminan al final de la 
línea.
• Comentario de una sola línea:
• Comentario en línea:
• Loscomentarios queabarcan variaslíneas tienen """o''' en cualquieradelosextremos. 
Eslomismoqueunacadenamultilínea,perosepuedenusarcomocomentarios:
    223/1068
    159
def func():
"""This is a function that does nothing at all""" 
return
print(func. doc )
help(func)
def greet(name, greeting="Hello"): 
"""Print a greeting to the user `name`
Optional parameter `greeting` can change what they're greeted with.""" 
print("{} {}".format(greeting, name))
help(greet)
Accediendo programáticamente a las cadenas de documentación
Las cadenas de documentos son, a diferencia de los comentarios regulares, almacenados como 
un atributo de la función que documentan, lo que significa que puede acceder a ellos mediante 
programación.
Una función de ejemplo
Se puede acceder a la doc utilizando el atributo doc :
Esta es una función que no hace nada en absoluto.
Ayuda en la función de func en el módulo main :
func()
Esta es una función que no hace nada en absoluto.
Otra función de ejemplo
function. doc es sololacadena de documentos real como unacadena, mientras que la función 
dehelpproporcionainformacióngeneralsobreunafunción,incluidalacadenadedocumentos. 
Aquí hay un ejemplo másútil:
Ayuda en función greet en el módulo main :
greet(name, greeting='Hello')
Imprime un saludo al name usuario
El parámetro de greeting opcional puede cambiar lo que se saluda con.
    224/1068
    160
def greet(name, greeting="Hello"):
# Print a greeting to the user `name`
# Optional parameter `greeting` can change what they're greeted with.
print("{} {}".format(greeting, name))
print(greet. doc )
help(greet)
def hello(name): 
"""Greet someone.
Print a greeting ("Hello") for the person with the given name. 
"""
print("Hello "+name)
class Greeter:
"""An object used to greet people.
It contains multiple greeting functions for several languages 
and times of the day.
"""
Ventajas de docstrings sobre comentarios regulares
El solo hecho de no poner una cadena de documentos o un comentario regular en una función 
hace que sea mucho menos útil.
Ninguna
Ayuda en función saludar en módulo principal :
greet(name, greeting='Hello')
Escribir documentación utilizando cadenas de documentación.
Una cadena de documentación es un comentario de varias líneas que se utiliza para documentar 
módulos, clases, funciones y métodos. Tiene que ser la primera declaración del componente que 
describe.
Se puede acceder al valor de la cadena de documentos dentro del programa y, por ejemplo, el 
comando de help utiliza.
Convenciones de sintaxis
PEP 257
    225/1068
    161
def hello():
"""Say hello to your friends.""" 
print("Hello my friends!")
def hello(name, language="en"): 
"""Say hello to a person.
Arguments:
name: the name of the person
language: the language in which the person should be greeted 
"""
print(greeting[language]+" "+name)
def hello(name, language="en"):
PEP 257 define un estándar de sintaxis para comentarios de cadena de documentación. 
Básicamente permite dos tipos:
• Docstrings de una línea:
Según PEP 257, deben usarse con funciones cortas y simples. Todo se coloca en una línea, por 
ejemplo:
La cadena de documentos debe terminar con un punto, el verbo debe estar en la forma 
imperativa.
• Docstrings multilínea:
La cadena de documentos multilínea se debe utilizar para funciones, módulos o clases más 
largas y complejas.
Comienzan con un breve resumen (equivalente al contenido de una cadena de documentación de 
una línea) que puede estar en la misma línea que las comillas o en la siguiente línea, dan detalles 
adicionales y enumeran parámetros y valores de retorno.
La nota PEP 257 define qué información se debe dar dentro de una cadena de documentación, 
no define en qué formato se debe dar. Esta fue la razón para que otras partes y herramientas de 
análisis de documentación especifiquen sus propios estándares para la documentación, algunos 
de los cuales se enumeran a continuación y en esta pregunta .
Esfinge
Sphinx es una herramienta para generar documentación basada en HTML para proyectos de 
Python basados en cadenas de documentación. Su lenguaje de marcado utilizado es 
reStructuredText . Definen sus propios estándares para la documentación, pythonhosted.org 
alberga una muy buena descripción de ellos . El formato Sphinx es, por ejemplo, utilizado por el 
IDE de pyCharm .
Una función se documentaría así utilizando el formato Sphinx / reStructuredText:
    226/1068
    162
def hello(name, language="en"): 
"""Say hello to a person.
Args:
name: the name of the person as string 
language: the language code string
Returns:
A number.
"""
print(greeting[language]+" "+name) 
return 4
Guía de estilo de Google Python
Google ha publicado la Guía de estilo de Google Python que define las convenciones de 
codificación para Python, incluidos los comentarios de la documentación. En comparación con 
Sphinx / reST, muchas personas dicen que la documentación de acuerdo con las directrices de 
Google es mejor legible para los humanos.
La página pythonhosted.org mencionada anteriormente también proporciona algunos ejemplos de 
buena documentación de acuerdo con la Guía de estilo de Google.
Al usar el complemento de Napoleón , Sphinx también puede analizar la documentación en el 
formato compatible con la Guía de estilo de Google.
Una función se documentaría así utilizando el formato de la Guía de estilo de Google:
"""Say hello to a person.
:param name: the name of the person
:type name: str
:param language: the language in which the person should be greeted
:type language: str
:return: a number
:rtype: int 
"""
print(greeting[language]+" "+name) 
return 4
    227/1068
    163
x > y 
x < y
12 > 4
# True 
12 < 4
# False 
1 < 4
# True
Capítulo 30: Comparaciones
Sintaxis
• ! = - No es igual a
• == - es igual a
• > - mayor que
• < - menos que
• >= - mayor que o igual a
• <= - menor o igual que
• is - prueba si los objetos son exactamente el mismo objeto
• no es = prueba si los objetos no son exactamente el mismo objeto
Parámetros
Parámetro Detalles
X Primer artículo a comparar
y Segundo elemento a comparar
Examples
Mayor o menor que
Estos operadores comparan dos tipos de valores, son menos que y mayores que los operadores. 
Para los números, esto simplemente compara los valores numéricos para ver cuál es más grande:
Para las cuerdas, se compararán lexicográficamente, lo cual es similar al orden alfabético pero no
    228/1068
    164
"alpha" < "beta" 
# True
"gamma" > "beta" 
# True
"gamma" < "OMEGA" 
# False
"GAMMA" < "OMEGA"
# True
x != y
12 != 1
# True
12 != '12'
# True
'12' != '12'
# False
x == y
12 == 12
# True 
12 == 1
# False 
'12' == '12'
# True
'spam' == 'spam' 
# True
'spam' == 'spam' 
# False
'12' == 12
es exactamente el mismo.
En estas comparaciones, las letras minúsculas se consideran "mayores que" en mayúsculas, por 
lo que "gamma" < "OMEGA" es falso. Si todos estuvieran en mayúsculas, devolvería el resultado de 
orden alfabético esperado:
Cada tipo define su cálculo con los operadores < y > diferente, por lo que debe investigar qué 
significan los operadores con un tipo dado antes de usarlo.
No igual a
Esto devuelve True si x e y no son iguales y, de lo contrario, devuelve False .
Igual a
Esta expresión se evalúa si x y y son del mismo valor y devuelve el resultado como un valor 
booleano.En general, tanto el tipo como el valor deben coincidir, porlo que el int 12 no es lo 
mismo que la cadena '12' .
    229/1068
    165
x > y > z
x > y and y > z
1 > -1 < 2 > 0.5 < 100 != 24
1 > x > -4 > y != 8
Tenga en cuenta que cada tipo debe definir una función que se utilizará para evaluar si dos 
valores soniguales.Paralos tipos incorporados,estas funcionessecomportancomocabría 
esperar y solo evalúan las cosas basándose en el mismo valor. Sin embargo, los tipos 
personalizadospuedendefinirlaspruebasde igualdadcomolodeseen,incluyendodevolver 
siempre True o siempre False .
Comparaciones de cadena
Puede comparar varios elementos con múltiples operadores de comparación con comparación de 
cadena. Por ejemplo
Es sólo una forma corta de:
Esto se evaluará como True solo si ambas comparaciones son True . 
La forma general es
Donde OP representa una de las múltiples operaciones de comparación que puede usar, y las 
letras representan expresiones válidas arbitrarias.
Tenga en cuenta que 0 != 1 != 0 evalúa como True , aunque 0 != 0 sea False . A
diferencia de la notación matemática común en la que x != y != z significa que x , y , z 
tienenvaloresdiferentes.Lasoperacionesdeencadenamiento == tienenelsignificado 
naturalenlamayoríadeloscasos, yaquelaigualdadesgeneralmentetransitiva.
Estilo
No hay un límite teórico sobre la cantidad de elementos y operaciones de comparación que 
utiliza, siempre que tenga la sintaxis adecuada:
Lo anterior devuelve True si cada comparación devuelve True . Sin embargo, el uso de 
encadenamiento enrevesado no es un buen estilo. Un buen encadenamiento será "direccional", 
no más complicado que
a OP b OP c OP d ...
# False
    230/1068
    166
a > exp and exp > b
a = 'short' 
b = 'short' 
c = 5
d = 5
a is b # True 
c is d # True
Efectos secundarios
Tan pronto como una comparación devuelve False , la expresión se evalúa inmediatamente en
False , omitiendo todas las comparaciones restantes.
Tenga en cuenta que la expresión exp en a > exp > b seevaluará solo unavez, mientras queen el 
caso de
exp se calculará dos veces si a > exp es verdadero.
Comparación por `is` vs` == `
Un error común es confundir a los operadores de comparación de igualdad is y == .
a == b compara el valor de a y b .
a is b comparará las identidades de a y b . 
Para ilustrar:
Básicamente, is puede considerar como una abreviatura para id(a) == id(b) .
Más alláde esto,hay peculiaridades del entornodel tiempo de ejecución que complican aúnmás 
las cosas. Las cadenas cortas y los enteros pequeños devolverán True cuando se compara con is
, debido a que la máquina Python intenta usar menos memoria para objetos idénticos.
Pero las cadenas más largas y los enteros más grandes se almacenarán por separado.
a = 'Python is fun!' 
b = 'Python is fun!' 
a == b # returns True 
a is b # returns False
a = [1, 2, 3, 4, 5]
b = a # b references a
a == b # True
a is b #True
b = a[:] # b now references a copy of a 
a == b # True
a is b # False [!!]
    231/1068
    167
if myvar is not None: 
# not None
pass
if myvar is None: 
# None
pass
sentinel = object()
def myfunc(var=sentinel): 
if var is sentinel:
# value wasn’t provided 
pass
else:
# value was provided 
pass
class Foo(object):
def init (self, item): 
self.my_item = item
def eq (self, other):
return self.my_item == other.my_item
a = Foo(5) 
b = Foo(5)
a == b # True
a != b # False
a is b # False
class Bar(object):
def init (self, item): 
self.other_item = item
def eq (self, other):
return self.other_item == other.other_item
Usted debe usar is para probar para None :
Un uso de is es probar un "centinela" (es decir, un objeto único).
Comparando objetos
Paracompararlaigualdaddeclases personalizadas,puedeanular== y!= ne métodos eq
y ne . También puede anular lt ( < ), le ( <= ), gt ( > )y ge ( > ). Tenga en 
cuentaquesolonecesita anulardos métodos decomparación, yPythonpuede manejarel resto (
== es lo mismo que not < y not > , etc.)
Tenga en cuenta que esta comparación simple supone que other (el objeto que se está 
comparando) es el mismo tipo de objeto. Comparando con otro tipo lanzará un error:
a = 'not so short' 
b = 'not so short' 
c = 1000
d = 1000
a is b # False 
c is d # False
    232/1068
    168
if("asgdsrf" == 0) {
//do stuff
}
myVariable = "1"
if 1 == myVariable: 
#do stuff
Verificar isinstance() o similar ayudará a prevenir esto (si se desea).
Common Gotcha: Python no impone la escritura
En muchos otros idiomas, si ejecuta lo siguiente (ejemplo de Java)
... obtendrá un error. No puedes ir comparando cadenas con enteros como ese. En Python, esta 
es una declaración perfectamente legal, solo se resolverá en False .
Un gotcha común es el siguiente
Esta comparación evaluará a False sin un error, cada vez, ocultando un error o rompiendo un 
condicional.
def ne (self, other):
return self.other_item != other.other_item
c = Bar(5)
a == c # throws AttributeError: 'Foo' object has no attribute 'other_item'
    233/1068
    169
class Mixin1(object): 
def test(self):
print "Mixin1"
class Mixin2(object): 
def test(self):
print "Mixin2"
class MyClass(Mixin1, Mixin2): 
pass
>>> obj = MyClass()
>>> obj.test() 
Mixin1
class MyClass(Mixin2, Mixin1): 
pass
>>> obj = MyClass()
Capítulo 31: Complementos y clases de 
extensión
Examples
Mixins
En el lenguaje de programación orientado a objetos, una mezcla es una clase que contiene 
métodos para el uso de otras clases sin tener que ser la clase principal de esas otras clases. 
Cómo esas otras clases obtienen acceso a los métodos de la mezcla depende del idioma.
Proporciona un mecanismo para la herencia múltiple al permitir que varias clases usen la 
funcionalidad común, pero sin la semántica compleja de la herencia múltiple. Los mixins son útiles 
cuando un programador quiere compartir funcionalidad entre diferentes clases. En lugar de repetir 
el mismo código una y otra vez, la funcionalidad común puede simplemente agruparse en una 
mezcla y luego heredarse en cada clase que lo requiera.
Cuando usamos más de un mixins, el orden de los mixins es importante. Aquí hay un ejemplo 
simple:
En este ejemplo llamamos MyClass y método de test ,
El resultado debe ser Mixin1 porque el orden es de izquierda a derecha. Esto podría mostrar 
resultados inesperados cuando las súper clases lo agreguen. Así que el orden inverso es más 
bueno así:
El resultado será:
    234/1068
    170
class Base(object): 
def test(self):
print("Base.")
class PluginA(object): 
def test(self):
super().test() 
print("Plugin A.")
class PluginB(object): 
def test(self):
super().test() 
print("Plugin B.")
plugins = PluginA, PluginB
class PluginSystemA(PluginA, Base): 
pass
class PluginSystemB(PluginB, Base): 
pass
PluginSystemA().test() 
# Base.
# Plugin A.
PluginSystemB().test() 
# Base.
# Plugin B.
class Base:
plugins = []
def init_subclass (cls, **kwargs): 
super(). init_subclass (**kwargs) 
cls.plugins.append(cls)
def test(self): 
print("Base.")
class PluginA(Base):
Los mixins se pueden utilizar para definir complementos personalizados. 
Python 3.x 3.0
Plugins con clases personalizadas
En Python 3.6, PEP 487 agregó el método especial init_subclass , que simplifica y amplía la 
personalización de la clase sin usar metaclases . En consecuencia, esta característica permite 
crear complementos simples . Aquí demostramos esta característica modificando un ejemplo
anterior :
Python 3.x 3.6
>>> obj.test() 
Mixin2
    235/1068
    171
PluginA().test() 
# Base.
# Plugin A.
PluginB().test() 
# Base.
# Plugin B.
Base.plugins
# [ main .PluginA, main .PluginB]
Resultados:
def test(self): 
super().test() 
print("Plugin A.")
class PluginB(Base): 
def test(self):
super().test() 
print("Plugin B.")
    236/1068
    172
import os
path = "/home/myFiles/directory1"
## Check if path exists 
os.access(path, os.F_OK)
## Check if path is Readable 
os.access(path, os.R_OK)
## Check if path is Wriable 
os.access(path, os.W_OK)
##Check if path isExecuatble 
os.access(path, os.E_OK)
os.access(path, os.F_OK & os.R_OK & os.W_OK & os.E_OK)
Capítulo 32: Comprobando la existencia de 
ruta y permisos
Parámetros
Parámetro Detalles
os.F_OK Valor para pasar como el parámetro de modo de acceso () para probar la 
existencia de ruta.
os.R_OK Valor para incluir en el parámetro de modo de acceso () para probar la 
legibilidad de la ruta.
os.W_OK Valor para incluir en el parámetro de modo de acceso () para probar la 
capacidad de escritura de la ruta.
os.X_OK Valor que se incluirá en el parámetro de modo de acceso () para determinar si 
se puede ejecutar la ruta.
Examples
Realizar comprobaciones utilizando os.access
os.access es una solución mucho mejor para verificar si existe un directorio y es accesible para 
leer y escribir.
También es posible realizar todos los controles juntos.
Todo lo anterior devuelve True si el acceso está permitido y False si no está permitido. Estos están
    237/1068
    173
disponibles en Unix y Windows.
    238/1068
    174
import multiprocessing
def fib(n):
"""computing the Fibonacci in an inefficient way 
was chosen to slow down the CPU."""
if n <= 2:
return 1 
else:
return fib(n-1)+fib(n-2) 
p = multiprocessing.Pool()
print(p.map(fib,[38,37,36,35,34,33]))
# Out: [39088169, 24157817, 14930352, 9227465, 5702887, 3524578]
import time
def main():
print "starting work" 
time.sleep(1)
print "work work work work work" 
time.sleep(1)
print "done working"
if name == ' main ':
Capítulo 33: Computación paralela
Observaciones
Debido al GIL (bloqueo de intérprete global), solo una instancia del intérprete de python se 
ejecuta en un soloproceso.Porlo tanto, engeneral, el usode subprocesos múltiples solo mejora 
los cálculos de E / S enlazados, no los de CPU. Se recomienda el módulo de multiprocessing si 
desea paralelizar las tareas relacionadas con la CPU.
GIL se aplica a CPython, la implementación más popular de Python, así como a PyPy. Otras 
implementaciones como Jython y IronPython no tienen GIL .
Examples
Uso del módulo multiprocesamiento para paralelizar tareas.
A medida que la ejecución de cada llamada a fib ocurre en paralelo, el tiempo de ejecución del 
ejemplo completo es 1.8 × más rápido que si se hiciera de forma secuencial en un procesador 
dual.
Python 2.2+
Usando scripts de Padres e Hijos para ejecutar código en paralelo
niño.py
    239/1068
    175
import os
def main():
for i in range(5): 
os.system("pythonchild.py&")
if name == ' main ': 
main()
#include "Python.h"
...
PyObject *pyfunc(PyObject *self, PyObject *args) {
... 
Py_BEGIN_ALLOW_THREADS
// Threaded C code
... 
Py_END_ALLOW_THREADS
...
}
import pypar as pp
ncpus = pp.size() 
rank = pp.rank()
node = pp.get_processor_name()
print 'I am rank %d of %d on node %s' % (rank, ncpus, node) 
if rank == 0:
msh = 'P0'
pp.send(msg, destination=1) 
msg = pp.receive(source=rank-1)
print 'Processor 0 received message "%s" from rank %d' % (msg, rank-1)
parent.py
Esto es útil para tareas de solicitud / respuesta HTTP independientes o para selección / inserción 
de base de datos. Los argumentos de la línea de comando también se pueden dar al script 
child.py . La sincronización entre scripts se puede lograr si todos los scripts revisan regularmente 
un servidor separado (como una instancia de Redis).
Usando una extensión C para paralelizar tareas
La idea aquí es mover los trabajos intensivos en computación a C (usando macros especiales), 
independientemente de Python, y hacer que el código C libere el GIL mientras está funcionando.
Usando el módulo PyPar para paralelizar
PyPar es una biblioteca que utiliza la interfaz de paso de mensajes (MPI) para proporcionar 
paralelismo en Python. Un ejemplo simple en PyPar (como se ve en 
https://github.com/daleroberts/pypar) se ve así:
main()
    240/1068
    176
else:
source = rank-1
destination = (rank+1) % ncpus 
msg = pp.receive(source)
msg = msg + 'P' + str(rank) 
pypar.send(msg, destination)
pp.finalize()
    241/1068
    177
import serial
#Serial takes these two parameters: serial device and baudrate 
ser = serial.Serial('/dev/ttyUSB0', 9600)
import serial
#Serial takes two parameters: serial device and baudrate 
ser = serial.Serial('/dev/ttyUSB0', 9600)
Capítulo 34: Comunicación Serial Python 
(pyserial)
Sintaxis
• ser.read (tamaño = 1)
• ser.readline ()
• ser.write ()
Parámetros
parámetro detalles
Puerto Nombre del dispositivo, por ejemplo, / dev / ttyUSB0 en GNU / Linux o 
COM3 en Windows.
velocidad de 
transmisión
tipo de baudios: int por defecto: 9600 valores estándar: 50, 75, 110, 134,
150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600,
115200
Observaciones
Para más detalles echa un vistazo a la documentación de pyserial.
Examples
Inicializar dispositivo serie
Leer del puerto serial
Inicializar dispositivo serie
para leer un solo byte desde el dispositivo serie
    242/1068
    178
data = ser.read(size=5)
data = ser.readline()
#for python2.7
data = ser.read(ser.inWaiting())
#for python3 
ser.read(ser.inWaiting)
python -m serial.tools.list_ports
from serial.tools import list_ports
list_ports.comports() # Outputs list of available serial ports
para leer el número dado de bytes del dispositivo serie
para leer una línea desde el dispositivo serie.
para leer los datos del dispositivo serie mientras se escribe algo sobre él.
Compruebe qué puertos serie están disponibles en su máquina
Para obtener una lista de los puertos serie disponibles use
en un símbolo del sistema o
de la cáscara de Python.
data = ser.read()
    243/1068
    179
from future import print_function 
import threading
def counter(count): 
while count > 0:
print("Count value", count) 
count -= 1
return
t1 = threading.Thread(target=countdown,args=(10,)) 
t1.start()
t2 =threading.Thread(target=countdown,args=(20,)) 
t2.start()
from future import print_function 
import multiprocessing
def countdown(count): 
while count > 0:
print("Count value", count) 
count -= 1
return
if name == " main ":
p1 = multiprocessing.Process(target=countdown, args=(10,)) 
p1.start()
p2 = multiprocessing.Process(target=countdown, args=(20,)) 
p2.start()
Capítulo 35: Concurrencia de Python
Observaciones
Los desarrolladores de Python se aseguraron de que la API entre threading y multiprocessing sea 
similar, de modo que el cambio entre las dos variantes sea más fácil para los programadores.
Examples
El módulo de enhebrado.
En ciertas implementaciones de Python como CPython, cierto paralelismo no se consigue 
utilizando hilos porque de la utilización de lo que se conoce como el GIL, o G lobal I nterpreter L 
ock.
Aquí hay una excelente descripción de la concurrencia de Python: 
Concordancia Python por David Beazley (YouTube)
El módulo multiprocesamiento.
    244/1068
    180
Aquí, cada función se ejecuta en un nuevo proceso. Dado que una nueva instancia de Python VM 
ejecuta el código, no hay GIL y se ejecuta el paralelismo en varios núcleos.
El método Process.start inicia este nuevo proceso y ejecuta la función pasada en el argumento de 
target con los argumentos args . El método Process.join espera el final de la ejecución de los 
procesos p1 y p2.
Los nuevos procesos se inician de manera diferente según la versión de python y la plataforma en 
la que se ejecuta el código, por ejemplo :
• Windows usa spawn para crear el nuevo proceso.
• Con los sistemas y versiones de Unix anteriores a 3.3, los procesos se crean utilizando un
fork .
Tenga en cuenta que este método no respeta el uso POSIX de la bifurcación y, por lo tanto, 
conduce a comportamientos inesperados, especialmente al interactuar con otras bibliotecas 
de multiprocesamiento.
• Conel sistemaUnixylaversión3.4+, puedeelegiriniciarlosnuevos procesoscon fork, 
forkserver o spawn utilizando multiprocessing.set_start_method al comienzo de su programa. 
forkserver métodos forkserver y spawn son más lentos que los forking, pero evitan algunos 
comportamientos inesperados.
Uso de la horquilla POSIX :
Después de una bifurcación en un programa multiproceso, el niño solo puede llamar 
de forma segura a funciones async-signal-safe hasta el momento en que lo llame 
execve.
( ver )
Usando fork, se iniciará un nuevo proceso con el mismo estado exacto para todo el mutex actual, 
pero solo se MainThread . Esto no es seguro ya que podría conducir a condiciones de carrera, por 
ejemplo :
• Si utiliza un Lock en MainThread y lo pasa a otro hilo que se supone que debe bloquearlo en 
algún momento. Si la fork ocurre simultáneamente, el nuevo proceso comenzará con un 
bloqueo bloqueado que nunca se liberará ya que el segundo hilo no existe en este nuevo 
proceso.
En realidad, este tipo de comportamiento no debería ocurrir en Python puro, ya que el 
multiprocessing maneja correctamente, pero si está interactuando con otra biblioteca, puede 
ocurrireste tipodecomportamiento,loquepuedeprovocarun falloensu sistema(por ejemplo, 
con numpy / acelerado en macOS)
Transferencia de datos entre procesos de multiprocesamiento.
Debido a que los datos son confidenciales cuando se manejan entre dos subprocesos (piense 
que la lectura concurrente y la escritura concurrente pueden entrar en conflicto entre sí, causando
p1.join()
p2.join()
    245/1068
    181
import multiprocessing 
import queue
my_Queue=multiprocessing.Queue()
#Creates a queue with an undefined maximum size
#this can be dangerous as the queue becomes increasingly large
#it will take a long time to copy data to/from each read/write thread
import multiprocessing 
import queue
'''Import necessary Python standard libraries, multiprocessing for classes and queue for the 
queue exceptions it provides'''
defQueue_Iftry_Get(get_queue,default=None, use_default=False,func=None,use_func=False): 
'''This global method for the Iftry block is provided for it's reuse and
standard functionality, the if also saves on performance as opposed to catching 
the exception, which is expencive.
It also allows the user to specify a function for the outgoing data to use,
and a default value to return if the function cannot return the value from the queue''' 
if get_queue.empty():
if use_default: 
return default
else:
try:
value = get_queue.get_nowait() 
except queue.Empty:
if use_default: 
return default
else:
if use_func:
return func(value) 
else:
return value
def Queue_Iftry_Put(put_queue, value):
'''This global method for the Iftry block is provided because of its reuse
and
standard functionality, the If also saves on performance as opposed to catching 
the exception, which is expensive.
ReturnTrue ifplacing value inthequeuewassuccessful.Otherwise,false''' 
if put_queue.full():
return False 
else:
try:
put_queue.put_nowait(value) 
except queue.Full:
return False 
else:
return True
condiciones de carrera), se creó un conjunto de objetos únicos para facilitar la transferencia de 
datos entre los subprocesos. Cualquier operación verdaderamente atómica puede usarse entre 
subprocesos, pero siempre es seguro mantener la cola.
La mayoría de las personas sugerirán que al usarla cola, siempre coloque los datos de lacolaen 
unintento: excepto:bloque enlugar de usar vacío.Sin embargo, para las aplicaciones en lasque 
no importa siomiteun ciclo deexploración (los datos se puedencolocar en la cola mientras se 
queue.Empty==True estados de la queue.Empty==True a la queue.Empty==False ) por lo general es mejor 
colocarla lectura y acceso de escritura en lo queyo llamo unbloque Iftry,porque una declaración 
'if' es técnicamente más eficaz que atrapar laexcepción.
    246/1068
    182
    247/1068
    183
number = 5
if number > 2:
print("Number is bigger than 2.")
elif number < 2: # Optional clause (you can have multiple elifs) 
print("Number is smaller than 2.")
else: # Optional clause (you can only have one else) 
print("Number is 2.")
n = 5
Capítulo 36: Condicionales
Introducción
Las expresiones condicionales, que incluyen palabras clave como if, elif y else, proporcionan a los 
programas de Python la capacidad de realizar diferentes acciones dependiendo de una condición 
booleana: Verdadero o Falso. Esta sección cubre el uso de condicionales de Python, lógica 
booleana y sentencias ternarias.
Sintaxis
• <expression> if <conditional> else <expression> # Operador ternario
Examples
si, elif, y si no
EnPythonpuedesdefinirunaseriedecondicionalesusandoifparaelprimero,elifparaelresto, 
hasta el final (opcional) else para cualquier cosa que no sea capturada por los otros 
condicionales.
El Number is bigger than 2 salidas Number is bigger than 2
El uso de else if lugar de elif activará un error de sintaxis y no está permitido.
Expresión condicional (o "El operador ternario")
El operador ternario se utiliza para expresiones condicionales en línea. Se utiliza mejor en 
operaciones simples y concisas que se leen fácilmente.
• El orden de los argumentos es diferente de muchos otros lenguajes (como C, Ruby, Java, 
etc.), lo que puede provocar errores cuando las personas que no están familiarizadas con el 
comportamiento "sorprendente" de Python lo usan (pueden invertir el orden).
• Algunos lo consideran "poco manejable", ya que va en contra del flujo normal de 
pensamiento (pensando primero en la condición y luego en los efectos).
    248/1068
    184
n = 5
"Hello" if n > 10 else "Goodbye" if n > 5 else "Good day"
if condition: 
body
if True:
print "It is true!"
>> It is true!
if False:
print "This won't get printed.."
if 2 + 2 == 4:
print "I know math!"
>> I know math!
if condition: 
body
else:
body
if True:
print "It is true!" 
else:
print "This won't get printed.."
El resultado de esta expresión será tal como se lee en inglés; si la expresión condicional es 
Verdadero, se evaluará la expresión en el lado izquierdo, de lo contrario, el lado derecho.
Las operaciones de tenencia también se pueden anidar, como aquí:
También proporcionan un método para incluir condicionales en las funciones lambda .
Si declaración
Lasdeclaracionesifcompruebanlacondición.Siseevalúacomo True ,ejecutaelcuerpodela 
sentencia if . Si se evalúa como False , se salta el cuerpo.
La condición puede ser cualquier expresión válida:
Otra declaración
La sentencia else ejecutará su cuerpo solo si las sentencias condicionales anteriores se evalúan 
como Falso.
"Greater than 2" if n > 2 else "Smaller than or equal to 2" 
# Out: 'Greater than 2'
    249/1068
    185
"Hello World"
>>> "" and "Pancakes" 
""
Expresiones lógicas booleanas
Las expresiones lógicas booleanas, además de evaluar a True o False , devuelven el valor que se 
interpretó como True o False . Es una forma en Pythonic de representar la lógica que, de lo
contrario, podría requerir una prueba if-else.
Y operador
El operador and evalúa todas las expresiones y devuelve la última expresión si todas las 
expresiones se evalúan como True . De lo contrario, devuelve el primer valor que se evalúa como 
False :
>>> 
2
1 and 2
>>> 
0
1 and 0
>>> 1 and "Hello World"
O operador
El operador or evalúa las expresiones de izquierda a derecha y devuelve el primer valor que se 
evalúa como True o el último valor (si ninguno es True ).
>>> 
1
1 or 2
>>> 
1
None or 1
>>> 
[]
0 or []
# Output: It is true!
if False:
print "This won't get printed.." 
else:
print "It is false!"
# Output: It is false!
    250/1068
    186
>>> def print_me():
print('I am here!')
>>> 0 and print_me() 
0
>>> a = 1
>>> b = 6
>>> if a and b > 2:
... print('yes')
... else:
... print('no')
yes
>>> if a > 2 and b > 2:
... print('yes')
... else:
... print('no')
no
>>> a = 1
>>> if a == 3 or 4 or 6:
... print('yes')
... else:
Evaluación perezosa
Cuando utilice este enfoque, recuerde que la evaluación es perezosa. Las expresiones que no 
requieren evaluación para determinar el resultado no se evalúan. Por ejemplo:
En el ejemplo anterior, print_me nunca se ejecuta porque Python puede determinar que la 
expresión completa es False cuando encuentra el 0 ( False ). Tenga esto en cuenta si print_me 
necesita ejecutarse para servir la lógica de su programa.
Pruebas para condiciones múltiples
Un error común al verificar múltiples condiciones es aplicar la lógica de manera incorrecta.
Esteejemplo está tratandodeverificar si dos variables son cada una mayorque2.La declaración 
se evalúa como - if (a) and (b > 2) . Esto produce un resultado inesperado porque bool(a) 
evalúa como True cuando a no es cero.
Cada variable debe compararse por separado.
Otro error similar secomete al verificar si una variable es uno de varios valores. La declaraciónen 
este ejemplo se evalúa como -if (a == 3) or (4) or (6) .Esto produce unresultado inesperado 
porque bool(4) y bool(6) evalúan como True
    251/1068
    187
>>> if a == 3 or a == 4 or a == 6:
... print('yes')
... else:
... print('no')
no
>>> if a in (3, 4, 6):
... print('yes')
... else:
... print('no')
no
Nuevamente cada comparación debe hacerse por separado
Usar el operador in es la forma canónica de escribir esto.
Valores de verdad
Los siguientes valores se consideran falsey, ya que se evalúan como False cuando se aplican a 
un operador booleano.
• Ninguna
• Falso
• 0 , o cualquier valor numérico equivalente a cero, por ejemplo 0L , 0.0 , 0j
• Secuencias vacías: '', "" , () , []
• Asignaciones vacías: {}
• Tipos definidos por el usuario dondelos métodos bool o len devuelven 0 o False
Todos los demás valores en Python se evalúan como True .
Nota:UnerrorcomúnessimplementeverificarlaFalsedaddeunaoperaciónquedevuelve 
diferentes valoresdeFalseydondeladiferenciaesimportante.Porejemplo,usarif foo()lugar 
de más explícito if foo() is None
Usando la función cmp para obtener el resultado de comparación de dos 
objetos
Python 2 incluye una función cmp que le permite determinar si un objeto es menor, igual o mayor 
que otro objeto. Esta función se puede usar para elegir una opción de una lista basada en una de 
esas tres opciones.
Supongamos que necesita imprimir 'greater than' si x > y , 'less than' si x < y e 'equal' si x == y
yes
... print('no')
    252/1068
    188
['equal', 'greater than', 'less than', ][cmp(x,y)]
# x,y = 1,1 output: 'equal'
# x,y = 1,2 output: 'less than' 
# x,y = 2,1 output: 'greater than'
>> n = 16
>> print [10, 20][n <= 15]
10
[10, 20][n <= 15]
==> [10, 20][False]
==> [10, 20][0] #False==0, True==1 (Check Boolean Equivalencies in Python)
==> 10
.
cmp(x,y) devuelve los siguientes valores
Comparación Resultado
x <y -1
x == y 0
x> y 1
Esta función se elimina en Python 3. Puede usar la cmp_to_key(func) ayuda cmp_to_key(func)
ubicada en functools en Python 3 para convertir las funciones de comparación antiguas en 
funciones clave.
Evaluación de expresiones condicionales usando listas de comprensión 
Python te permite hackear las comprensiones de la lista para evaluar expresiones condicionales. 
Por ejemplo,
Ejemplo:
Aquí n<=15 devuelve False (que equivale a 0 en Python). Entonces, lo que Python está evaluando 
es:
Python 2.x 2.7
El método cmp incorporado devolvió 3 valores posibles: 0, 1, -1, donde cmp (x, y) devolvió 0: si 
los dos objetos eran iguales 1: x> y -1: x <y
Esto podría usarse con la lista de comprensión para devolver el primer elemento (es decir, índice
[value_false, value_true][<conditional-test>]
    253/1068
    189
[value_equals, value_greater, value_less][<conditional-test>]
[lambda: value_false, lambda: value_true][<test>]()
count = [lambda:0, lambda:N+1][count==N]()
if aDate is None: 
aDate=datetime.date.today()
if not aDate:
aDate=datetime.date.today()
aDate=aDate or datetime.date.today()
0) , segundo (es decir, índice 1) y último (es decir, índice -1) de la lista. Dándonos uncondicional 
de este tipo:
Finalmente, en todos los ejemplos anteriores, Python evalúa ambas ramas antes de elegir una. 
Para evaluar solo la rama elegida:
donde agregar el () al final asegura que las funciones lambda solo se llamen / evalúen al final. 
Así, solo evaluamos la rama elegida.
Ejemplo:
Probar si un objeto es Ninguno y asignarlo
A menudo querrá asignar algo a un objeto si es None , lo que indica que no se ha asignado. 
Usaremos una aDate .
La forma más sencilla de hacer esto es usar la prueba is None .
(Tenga en cuenta que es más Pythonic decir is None lugar de == None ).
Pero esto puede optimizarse ligeramente explotando la noción de que not None se evaluará como
True en una expresión booleana. El siguiente código es equivalente:
Pero hay una forma más pitónica. El siguiente código también es equivalente:
Estohaceunaevaluacióndecortocircuito.Si aDateseinicializaynot Noneesnot None,entonces 
seasignaasímismosinefectoneto.Siis None ,entoncesdatetime.date.today()seasignaauna 
aDate .
    254/1068
    190
import pymssql
SERVER = "servername" 
USER = "username" 
PASSWORD = "password" 
DATABASE = "dbname"
connection = pymssql.connect(server=SERVER, user=USER,
password=PASSWORD, database=DATABASE)
cursor = connection.cursor() # to access field as dictionary use cursor(as_dict=True) 
cursor.execute("SELECT TOP 1 * FROM TableName")
row = cursor.fetchone()
######## CREATE TABLE ########
cursor.execute(""" 
CREATETABLEposts(
post_id INT PRIMARY KEY NOT NULL,
message TEXT, 
publish_date DATETIME
) 
""")
######## INSERT DATA IN TABLE ########
cursor.execute("""
INSERT INTO posts VALUES(1, "Hey There", "11.23.2016")
""")
# commit your work to database 
connection.commit()
######## ITERATE THROUGH RESULTS ########
cursor.execute("SELECT TOP 10 * FROM posts ORDER BY publish_date DESC") 
for row in cursor:
print("Message: " + row[1] + " | " + "Date: " + row[2]) 
# if you pass as_dict=True to cursor
# print(row["message"]) 
connection.close()
Capítulo 37: Conectando Python a SQL 
Server
Examples
Conectar al servidor, crear tabla, consultar datos
Instala el paquete:
$ pip install pymssql
Puede hacer cualquier cosa si su trabajo está relacionado con expresiones SQL, simplemente 
pase estas expresiones al método de ejecución (operaciones CRUD).
    255/1068
    191
Para la declaración, el procedimiento almacenado de llamada, el manejo de errores o más control 
de ejemplo: pymssql.org
    256/1068
    192
from paramiko import client
ssh = client.SSHClient() # create a new SSHClient object 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #auto-accept unknown host keys 
ssh.connect(hostname, username=username, port=port, password=password) #connect with a host 
stdin, stdout, stderr = ssh.exec_command(command) # submit a command to ssh
print stdout.channel.recv_exit_status() #tells the status 1 - job failed
Capítulo 38: Conexión segura de shell en 
Python
Parámetros
Parámetro Uso
nombre de host Este parámetro le indica al host al que se debe establecer la conexión.
nombre de usuario nombre de usuario requerido para acceder al host
Puerto Puerto host
contraseña contraseña para la cuenta
Examples
conexión ssh
    257/1068
    193
[DEFAULT]
debug = True 
name = Test
password = password
[FILES]
path = /path/to/file
from ConfigParser import ConfigParser 
config = ConfigParser()
#Load configuration file 
config.read("config.ini")
# Access the key "debug" in "DEFAULT" section 
config.get("DEFAULT", "debug")
# Return 'True'
# Access the key "path" in "FILES" destion 
config.get("FILES", "path")
# Return '/path/to/file'
Capítulo 39: configparser
Introducción
Este módulo proporciona la clase ConfigParser que implementa un lenguaje de configuración 
básico en archivos INI. Puede usar esto para escribir programas Python que los usuarios finales 
pueden personalizar fácilmente.
Sintaxis
• Cada nueva línea contiene un nuevo par de valores clave separados por el signo =
• Las teclas se pueden separar en secciones
• En el archivo INI, cada título de la sección se escribe entre paréntesis: []
Observaciones
Todos los valores de retorno de ConfigParser.ConfigParser().get son cadenas. Se puede convertir 
a tipos más comunes gracias a eval
Examples
Uso básico
En config.ini:
En Python:
    258/1068
    194
import configparser
config = configparser.ConfigParser() 
config['settings']={'resolution':'320x240',
'color':'blue'}
with open('example.ini', 'w') as configfile: 
config.write(configfile)
[settings]
resolution = 320x240 
color = blue
settings=config['settings'] 
settings['color']='red'
Creando programáticamente el archivo de configuración.
El archivo de configuración contiene secciones, cada sección contiene claves y valores. El 
módulo configparser se puede usar para leer y escribir archivos de configuración. Creando el 
archivo de configuración: -
El archivo de salida contiene la siguiente estructura
Si desea cambiar un campo en particular, obtenga el campo y asigne el valor
    259/1068
    195
restaurants = ["McDonald's", "Burger King", "McDonald's", "Chicken Chicken"] 
unique_restaurants = set(restaurants)
print(unique_restaurants)
# prints {'Chicken Chicken', "McDonald's", 'Burger King'}
Capítulo 40: Conjunto
Sintaxis
• empty_set = set () # inicializa un conjunto vacío
• literal_set = {'foo', 'bar', 'baz'} # construye un conjunto con 3 cadenas dentro de él
• set_from_list = set (['foo', 'bar', 'baz']) # llama a la función set para un nuevo conjunto
• set_from_iter = set (x para x en el rango (30)) # usa iterables arbitrarios para crear un 
conjunto
• set_from_iter = {x para x en [random.randint (0,10) para i en rango (10)]} # notación 
alternativa
Observaciones
Los conjuntos no están ordenados y tienen un tiempo de búsqueda muy rápido (amortizado O (1) 
si desea obtener asistencia técnica). Es genial usarlo cuando tienes una colección de cosas, el 
orden no importa, y buscarás muchos artículos por nombre. Si tiene más sentido buscar 
elementos por un número de índice, considere usar una lista en su lugar. Si el orden importa, 
considera una lista también.
Los conjuntos son mutables y, por lo tanto, no se pueden hashear, por lo que no puede usarlos 
como claves de diccionario o colocarlos en otros conjuntos o en cualquier otro lugar que requiera 
tipos de hashable. En tales casos, puede utilizar un frozenset inmutable.
Loselementos de unconjunto deben ser hashable .Esto significaque tienen un método correcto 
de hash ,que es consistente con eq .Engeneral,lostipos mutables, comolalistoelset, 
nosonhashablesynosepuedencolocar enunconjunto.Siseencuentraconesteproblema, 
considere usar claves dict yinmutables.
Examples
Consigue los elementos únicos de una lista.
Digamos que tienes una lista de restaurantes, tal vez la lees de un archivo. Te preocupas por los 
restaurantes únicos en la lista. La mejor manera de obtener los elementos únicos de una lista es 
convertirlos en un conjunto:
Tenga en cuenta que el conjunto no está en el mismo orden que la lista original; eso es porque 
los conjuntos no están ordenados , al igual que dict s.
    260/1068
    196
# Intersection
{1, 2, 3, 4, 5}.intersection({3, 4, 5, 6}) # {3, 4, 5}
{1, 2, 3, 4, 5} & {3, 4, 5, 6} # {3, 4, 5}
# Union
{1, 2, 3, 4, 5}.union({3, 4, 5, 6})
{1, 2, 3, 4,5} | {3, 4, 5, 6}
# {1, 2, 3, 4, 5, 6}
# {1, 2, 3, 4, 5, 6}
# Difference
{1, 2, 3, 4}.difference({2, 3, 5}) # {1, 4}
{1, 2, 3, 4} - {2, 3, 5} # {1, 4}
# Symmetric difference with
{1, 2, 3, 4}.symmetric_difference({2, 3, 5}) # {1, 4, 5}
{1, 2, 3, 4} ^ {2, 3, 5} # {1, 4, 5}
# Superset check
{1, 2}.issuperset({1, 2, 3}) # False
{1, 2} >= {1, 2, 3} # False
# Subset check
{1, 2}.issubset({1, 2, 3}) # True
{1, 2} <= {1, 2, 3} # True
list(unique_restaurants)
# ['Chicken Chicken', "McDonald's", 'Burger King']
# Removes all duplicates and returns another list 
list(set(restaurants))
# Existence check
2 in {1,2,3} # True
4 in {1,2,3} # False
4 not in {1,2,3} # True
# Add and Remove 
s = {1,2,3}
s.add(4) # s == {1,2,3,4}
Estosepuede volver atransformarfácilmenteenuna List conla función de list incorporada de 
Python, dando otra lista que es la misma que la original pero sin duplicados:
También es común ver esto como una sola línea:
Ahora, cualquier operación que se pueda realizar en la lista original se puede hacer de nuevo.
Operaciones en sets
con otros sets
# Disjoint check
{1, 2}.isdisjoint({3, 4}) # True
{1, 2}.isdisjoint({1, 4}) # False
con elementos individuales
    261/1068
    197
s = {1, 2}
s.update({3, 4}) # s == {1, 2, 3, 4}
>>> setA = {'a','b','b','c'}
>>> setA
set(['a', 'c', 'b'])
>>> listA = ['a','b','b','c']
>>> listA
['a', 'b', 'b', 'c']
Las operaciones de configuración devuelven conjuntos nuevos, pero tienen las versiones locales 
correspondientes:
método operación en el lugar método en el lugar
Unión s | = t actualizar
intersección s & = t intersection_update
diferencia s - = t diferencia_update
diferencia de simetría s ^ = t symmetric_difference_update
Por ejemplo:
Conjuntos versus multisets
Los conjuntos son colecciones desordenadas de elementos distintos. Pero a veces queremos 
trabajar con colecciones desordenadas de elementos que no son necesariamente distintos y 
hacer un seguimiento de las multiplicidades de los elementos.
Considera este ejemplo:
Alguardarlascadenas'a','b','b','c'enunaestructuradedatosestablecida,hemosperdido 
lainformaciónsobreelhechodeque'b'ocurredosveces.Porsupuesto,guardarloselementos 
en una lista conservaría esta información
pero una lista de estructura de datos introduce un orden adicional innecesario que ralentizará 
nuestros cálculos.
Para implementar multisets, Python proporciona la clase Counter desde el módulo de collections
# s == {1,4}
# KeyError!
s.remove(2) 
s.remove(2)
# s == {1,2,4}
# s == {1,2,4}
s.discard(3) 
s.discard(5)
    262/1068
    198
>>> from collections import Counter
>>> counterA = Counter(['a','b','b','c'])
>>> counterA
Counter({'b': 2, 'a': 1, 'c': 1})
>>> a = {1, 2, 2, 3, 4}
>>> b = {3, 3, 4, 4, 5}
>>> a.intersection(b)
{3, 4}
>>> a.union(b)
{1, 2, 3, 4, 5}
>>> a.difference(b)
{1, 2}
>>> b.difference(a)
{5}
(a partir de la versión 2.7):
Python 2.x 2.7
Counter es un diccionario donde los elementos se almacenan como claves de diccionario y sus 
conteos se almacenan como valores de diccionario. Y como todos los diccionarios, es una 
colección desordenada.
Establecer operaciones usando métodos e incorporaciones
Definimos dos conjuntos a y b
NOTA: {1} crea un conjunto de un elemento, pero {} crea un dict vacío. La forma 
correcta de crear un conjunto vacío es set().
Intersección
a.intersection(b) devuelve un nuevo conjunto con elementos presentes tanto en a como en b
Unión
a.union(b) devuelve un nuevo conjunto con elementos presentes en a y b
Diferencia
a.difference(b) devuelve un nuevo conjunto con elementos presentes en a pero no en b
    263/1068
    199
>>> a.symmetric_difference(b)
{1, 2, 5}
>>> b.symmetric_difference(a)
{1, 2, 5}
>>> c = {1, 2}
>>> c.issubset(a) 
True
>>> a.issuperset(c) 
True
>>> d = {5, 6}
>>> a.isdisjoint(b) # {2, 3, 4} are in both sets 
False
Diferencia simétrica
a.symmetric_difference(b) devuelve un nuevo conjunto con elementos presentes en ya sea a o b
pero no en ambas
NOTA : a.symmetric_difference(b) == b.symmetric_difference(a)
Subconjunto y superconjunto
c.issubset(a) comprueba si cada elemento de c está en a .
a.issuperset(c) comprueba si cada elemento de c está en a .
Las últimas operaciones tienen operadores equivalentes como se muestra a continuación:
Método Operador
a.intersection(b) a & b
a.union(b) a | b
a.difference(b) a - b
a.symmetric_difference(b) a ^ b
a.issubset(b) a <= b
a.issuperset(b) a >= b
Conjuntos desunidos
Los conjuntos a y d son disjuntos si ningún elemento en a también está en d y viceversa.
    264/1068
    200
>>> 1 in a 
True
>>> 6 in a 
False
>>>len(a) 
4
>>> len(b) 
3
{{1,2}, {3,4}}
TypeError: unhashable type: 'set'
{frozenset({1, 2}), frozenset({3, 4})}
Membresía de prueba
El incorporado in palabra clave busca ocurrencias
Longitud
La función len() incorporada devuelve el número de elementos en el conjunto
Conjunto de conjuntos
lleva a:
En su lugar, utilice frozenset :
>>> a.isdisjoint(d)
True
# This is an equivalent check, but less efficient
>>> len(a & d) == 0 
True
# This is even less efficient
>>> a & d == set() 
True
    265/1068
    201
from collections import Counter
c = Counter(["a", "b", "c", "d", "a", "b", "a", "c", "d"]) 
c
# Out: Counter({'a': 3, 'b': 2, 'c': 2, 'd': 2}) 
c["a"]
# Out: 3
c[7] # not in the list (7 occurred 0 times!) 
# Out: 0
Counter({"e": 2})
# Out: Counter({"e": 2})
Counter({"e": "e"}) # warning Counter does not verify the values are int 
# Out: Counter({"e": "e"})
from collections import Counter
adict = {'a': 5, 'b': 3, 'c': 5, 'd': 2, 'e':2, 'q': 5}
Counter(adict.values())
# Out: Counter({2: 2, 3: 1, 5: 3})
# Sorting them from most-common to least-common value: 
Counter(adict.values()).most_common()
# Out: [(5, 3), (2, 2), (3, 1)]
# Getting the most common value 
Counter(adict.values()).most_common(1) 
# Out: [(5, 3)]
Capítulo 41: Contando
Examples
Contando todas las apariciones de todos los elementos en un iterable: 
colecciones.Contador
Lascollections.Counter sepuedeutilizar paracualquier iterable ycuentacada aparición para 
cada elemento.
Nota : una excepción es si se otorga un dict u otra collections.Mapping crear una clase similar a 
la de un dict , no se contabilizarán, sino que creará un contador con estos valores:
Obtención del valor más común (-s): collections.Counter.most_common ()
No es posible contar las claves de un Mapping con collections.Counter Contador, pero podemos 
contar los valores :
Los elementos más comunes están disponibles por el método most_common :
    266/1068
    202
alist = [1, 2, 3, 4, 1, 2, 1, 3, 4]
alist.count(1) 
# Out: 3
atuple = ('bear', 'weasel', 'bear', 'frog') 
atuple.count('bear')
# Out: 2 
atuple.count('fox') 
# Out: 0
astring = 'thisisashorttext' 
astring.count('t')
# Out: 4
astring.count('th') 
# Out: 1 
astring.count('is') 
# Out: 2
astring.count('text') 
# Out: 1
from collections import Counter 
Counter(astring)
# Out: Counter({'a': 1, 'e': 1, 'h': 2, 'i': 2, 'o': 1, 'r': 1, 's': 3, 't': 4, 'x': 1})
>>> import numpy as np
>>> a=np.array([0,3,4,3,5,4,7])
>>> print np.sum(a==3) 
2
Contando las ocurrencias de un elemento en una secuencia: list.count () y 
tuple.count ()
Contando las ocurrencias de una subcadena en una cadena: str.count ()
Esto funciona incluso para subcadenas de más de un carácter:
lo que no sería posible con collections.Counter que solo cuenta con caracteres individuales:
Contando ocurrencias en matriz numpy
Para contar las ocurrencias de un valor en una matriz numpy. Esto funcionará:
La lógica es que la declaración booleana produce una matriz donde todas las apariciones de los 
valores solicitados son 1 y todas las demás son cero. Así que sumando estos da el número de 
ocurrencias. Esto funciona para matrices de cualquier forma o tipo de dtype.
# Getting the two most common values 
Counter(adict.values()).most_common(2) 
# Out: [(5, 3), (2, 2)]
    267/1068
    203
>>> unique,counts=np.unique(a,return_counts=True)
>>> print unique,counts # counts[i] is equal to occurrences of unique[i] in a 
[0 3 4 5 7] [1 2 2 1 1]
>>> bin_count=np.bincount(a)
>>> print bin_count # bin_count[i] is equal to occurrences of i in a 
[1 0 0 2 2 1 0 1]
Hay dos métodos que utilizo para contar las ocurrencias de todos los valores únicos en numpy. 
Único y bincount. Unique automáticamente aplana las matrices multidimensionales, mientras que 
bincount solo funciona con matrices 1d que solo contienen enteros positivos.
Si sus datos son matrices numpy, generalmente es mucho más rápido usar métodos numpy que 
convertir sus datos a métodos genéricos.
    268/1068
    204
>>> import copy
>>> c = [[1,2]]
>>> d = copy.copy(c)
>>> c isd 
False
>>> c[0] is d[0] 
True
>>> import copy
>>> c = [[1,2]]
>>> d = copy.deepcopy(c)
>>> c isd 
False
>>> c[0] is d[0] 
False
# Perform the shallow copy.
>>> l1 = [1,2,3]
>>> l2 = l1[:]
>>> l2 
[1,2,3]
>>> l1 is l2
False
>>> d1 = {1:[]}
>>> d2 = d1.copy()
>>> d1 is d2 
False
>>> d1[1] is d2[1]
Capítulo 42: Copiando datos
Examples
Realizando una copia superficial
Una copia superficial es una copia de una colección sin realizar una copia de sus elementos.
Realizando una copia profunda
Si tiene listas anidadas, también es deseable clonar las listas anidadas. Esta acción se llama 
copia profunda.
Realizando una copia superficial de una lista
Puedes crear copias superficiales de listas usando cortes.
Copiar un diccionario
Un objeto de diccionario tiene el método de copy . Realiza una copia superficial del diccionario.
    269/1068
    205
>>> s1 = {()}
>>> s2 = s1.copy()
>>> s1 is s2 
False
>>> s2.add(3)
>>> s1
{[]}
>>> s2
{3,[]}
Copiar un conjunto
Los conjuntos también tienen un método de copy . Puede utilizar este método para realizar una 
copia superficial.
True
    270/1068
    206
a[-1] # last item in the array
a[-2:] # last two items in the array
a[:-2] # everything except the last twoitems
lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
lst[::2]
# Output: ['a', 'c', 'e', 'g']
lst[::3]
# Output: ['a', 'd', 'g']
lst = ['a', 'b', 'c', 'd', 'e']
lst[2:4]
# Output: ['c', 'd']
lst[2:]
# Output: ['c', 'd', 'e']
Capítulo 43: Corte de listas (selección de 
partes de listas)
Sintaxis
• a [inicio: final] # los elementos comienzan hasta el final-1
• a [inicio:] # los elementos comienzan en el resto de la matriz
• a [: fin] # elementos desde el principio hasta el final-1
• a [inicio: final: paso] # comienzo a través de no pasado, paso a paso
• a [:] # una copia de toda la matriz
• fuente
Observaciones
• lst[::-1] le da una copia invertida de la lista
• start o el end puede ser un número negativo, lo que significa que cuenta desde el final de la 
matriz en lugar del principio. Asi que:
( fuente )
Examples
Usando el tercer argumento del "paso"
Seleccionando una lista secundaria de una lista
    271/1068
    207
a = [1, 2, 3, 4, 5]
# steps through the list backwards (step=-1) 
b = a[::-1]
# built-in list method to reverse 'a' 
a.reverse()
if a = b:
print(True) 
print(b)
# Output:
# True
# [5, 4, 3, 2, 1]
def shift_list(array, s):
"""Shifts the elements of a list to the left or right.
Args:
array - the list to shift
s - the amount to shift the list ('+': right-shift, '-': left-shift)
Returns:
shifted_array - the shifted list
"""
# calculate actual shift amount (e.g., 11 --> 1 if length of the array is 5) 
s %= len(array)
# reverse the shift direction to be more intuitive 
s *= -1
# shift array with list slicing 
shifted_array = array[s:] + array[:s]
return shifted_array 
my_array = [1, 2, 3, 4, 5]
# negative numbers 
shift_list(my_array, -7)
>>> [3, 4, 5, 1, 2]
# no shift on numbers equal to the size of the array 
shift_list(my_array, 5)
>>> [1, 2, 3, 4, 5]
# works on positive numbers 
shift_list(my_array, 3)
Invertir una lista con rebanar
Desplazando una lista usando rebanar
lst[:4]
# Output: ['a', 'b', 'c', 'd']
    272/1068
    208
>>> [3, 4, 5, 1, 2]
    273/1068
    209
$ virtualenv .virtualenv
...
$ source .virtualenv/bin/activate
$ python setup.py install 
running install
...
Installed .../package_name-0.1 .........egg
Capítulo 44: Creando paquetes de Python
Observaciones
El proyecto de ejemplo pypa contiene una plantilla setup.py fácilmente modificable y completa que 
demuestra una amplia gama de capacidades que las herramientas de configuración pueden 
ofrecer.
Examples
Introducción
Cada paquete requiere un archivo setup.py que describe el paquete. 
Considere la siguiente estructura de directorio para un paquete simple:
El init .py contiene solo la línea def foo(): return 100 . 
El siguiente setup.py definirá el paquete:
from setuptools import setup
setup(
name='package_name', 
version='0.1', 
description='Package Description', 
url='http://example.com', 
install_requires=[],
packages=['package_name'],
)
# package name 
# version
# short description 
# package URL
# list of packages this package depends 
# on.
# List of module names that installing 
# this package will provide.
virtualenv es ideal para probar las instalaciones de paquetes sin modificar sus otros entornos de 
Python:
+-- package_name
| |
| +-- init .py
|
+-- setup.py
    274/1068
    210
# .pypirc file
[distutils] 
index-servers =
pypi 
pypitest
[pypi] 
repository=https://pypi.python.org/pypi 
username=your_username 
password=your_password
[pypitest] 
repository=https://testpypi.python.org/pypi 
username=your_username 
password=your_password
$ pip install twine
$ python setup.py register -r pypitest
Subiendo a PyPI
Una vez que su setup.py sea completamente funcional (vea Introducción ), es muy fácil cargar su 
paquete a PyPI .
Configurar un archivo .pypirc
Este archivo almacena inicios de sesión y contraseñas para autenticar sus cuentas. Normalmente 
se almacena en su directorio personal.
Es más seguro usar twine para cargar paquetes, así que asegúrese de que esté instalado.
Registrarse y subir a testpypi (opcional)
Nota : PyPI no permite sobrescribir paquetes cargados , por lo que es prudente probar primero su 
implementación en un servidor de prueba dedicado, por ejemplo, testpypi. Esta opción será 
discutida. Considere un esquema de control de versiones para su paquete antes de cargar, como 
el control de versiones del calendario o el control de versiones semántico .
Inicie sesión o cree una nueva cuenta en testpypi . El registro solo se requiere la primera vez, 
aunque registrarse más de una vez no es perjudicial.
...
$ python
>>> import package_name
>>> package_name.foo() 
100
    275/1068
    211
$ twine upload dist/* -r pypitest
# Using virtualenv
$ mkdir testenv
$ cd testenv
$ virtualenv .virtualenv
...
$ source .virtualenv/bin/activate 
# Test from testpypi
(.virtualenv) pip install --verbose --extra-index-url https://testpypi.python.org/pypi 
package_name
...
# Or test from PyPI
(.virtualenv) $ pip install package_name
...
(.virtualenv) $ python
Python 3.5.1 (default, Jan 27 2016, 19:16:39)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin 
Type "help", "copyright", "credits" or "license" for more information.
>>> import package_name
>>> package_name.foo() 
100
$ pip install twine
$ python setup.py register -r pypi
$ twine upload dist/*
Mientras que en el directorio raíz de su paquete:
Su paquete ahora debe ser accesible a través de su cuenta.
Pruebas
Realiza un entorno virtual de prueba. Intente pip install su paquete desde testpypi o PyPI.
Si tiene éxito, su paquete es menos importable. Puede considerar probar su API también antes de 
su carga final a PyPI. Si el paquete falló durante la prueba, no se preocupe. Aún puedes 
arreglarlo, volver a subirlo a testpypi y probar de nuevo.
Registrarse y subir a PyPI
Asegúrate de que el twine esté instalado:
Inicie sesión o cree una nueva cuenta en PyPI .
¡Eso es! Su paquete ya está en vivo .
Si descubre un error, simplemente cargue una nueva versión de su paquete.
    276/1068
    212
[metadata]
description-file = README.rst
python -m package_name
Documentación
No olvide incluir al menos algún tipo de documentación para su paquete. PyPi toma como idioma 
de formato predeterminado reStructuredText .
Readme
Si su paquete no tiene una gran documentación, incluya lo que puede ayudar a otros usuarios en 
el archivo README.rst . Cuando el archivo está listo, se necesita otro para decirle a PyPi que lo 
muestre.
Cree el archivo setup.cfg y ponga estas dos líneas en él:
Tenga en cuenta que si intenta colocar el archivo Markdown en su paquete, PyPi lo leerá como un 
archivo de texto puro sin ningún formato.
Licenciamiento
A menudo es más que bienvenido poner un archivo LICENSE.txt en su paquete con una de las 
licenciasdeOpenSource parainformaralos usuarios si pueden usar su paquete,por ejemplo,en 
proyectos comerciales o si su código se puede usar con su licencia.
De manera más legible, algunas licencias se explican en TL; DR .
Haciendo paquete ejecutable
Si su paquete no es solo una biblioteca, sino que tiene una pieza de código que puede usarse 
como una vitrina o una aplicación independiente cuando su paquete está instalado, coloque esa 
pieza de código en el archivo main .py .
Ponga la main .py en el package_name carpeta. De esta manera podrás ejecutarlo directamente 
desde la consola:
Si no hay main .py archivo main .py disponible, el paquete no se ejecutará con este 
comando y se imprimirá este error:
python:Nohayunmódulollamadopackage_name. main ; 'package_name'esun 
paquete y no se puede ejecutar directamente.
    277/1068
    213
paquetes-de-python
    278/1068
    214
import win32serviceutil 
import win32service 
import win32event 
import servicemanager 
import socket
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
def init (self,args): 
win32serviceutil.ServiceFramework. init (self,args) 
self.hWaitStop =win32event.CreateEvent(None,0,0,None) 
socket.setdefaulttimeout(60)
def SvcStop(self): 
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self): 
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED, 
(self._svc_name_,''))
self.main()
def main(self): 
pass
if name == ' main ':
Capítulo 45: Creando un servicio de Windows 
usando Python
Introducción
Los procesos sin cabeza (sin interfaz de usuario) en Windows se denominan Servicios. Se 
pueden controlar (iniciar, detener, etc.) mediante los controles estándar de Windows, como la 
consola de comandos, Powershell o la pestaña Servicios en el Administrador de tareas. Un buen 
ejemplo podría ser una aplicación que proporcione servicios de red, como una aplicación web, o 
tal vez una aplicación de respaldo que realice varias tareas de archivado en segundo plano. Hay 
varias formas de crear e instalar una aplicación de Python como un Servicio en Windows.
Examples
Un script de Python que se puede ejecutar como un servicio
Los módulos utilizados en este ejemplo son parte de pywin32 (Python para extensiones de 
Windows). Dependiendo de cómo instaló Python, es posible que necesite instalar esto por 
separado.
    279/1068
    215
nssm install MyServiceName c:\python27\python.exe c:\temp\myscript.py
import win32serviceutil 
import win32service 
import win32event 
import servicemanager
from multiprocessing import Process 
from app import app
class Service(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "Tests Python service framework by receiving and echoing messages over 
a named pipe"
def init (self, *args): 
super(). init (*args)
def SvcStop(self): 
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
self.process.terminate() 
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def SvcDoRun(self):
self.process = Process(target=self.main) 
self.process.start()
self.process.run()
Esto es sólo boilerplate. Su código de aplicación, probablemente invocando un script separado, 
iría en la función main ().
También necesitarás instalar esto como un servicio. La mejor solución para esto en este momento 
parece ser utilizar el Administrador de servicios que no chupa . Esto le permite instalar un servicio 
y proporciona una GUI para configurar la línea de comandos que ejecuta el servicio. Para Python 
puedes hacer esto, lo que crea el servicio de una sola vez:
Donde my_script.py es el script de boilerplate anterior, modificado para invocar su script o código 
de aplicación en la función main (). Tenga en cuenta que el servicio no ejecuta la secuencia de 
comandos de Python directamente, ejecuta el intérprete de Python y le pasa la secuencia de 
comandos principal en la línea de comandos.
Alternativamente, puede usar las herramientas proporcionadas en el Kit de recursos de Windows 
Server para la versión de su sistema operativo, así que cree el servicio.
Ejecutando una aplicación web de Flask como un servicio
Estaesunavariacióndelejemplogenérico.Solonecesitaimportarelscriptdesuaplicacióne 
invocar el métodorun() en la función main().Enestecaso, también estamosusando el módulo 
de multiprocesamiento debido a un problema al acceder a WSGIRequestHandler .
win32serviceutil.HandleCommandLine(AppServerSvc)
    280/1068
    216
Adaptado de http://stackoverflow.com/a/25130524/318488
def main(self): 
app.run()
if name == ' main ': 
win32serviceutil.HandleCommandLine(Service)
    281/1068
    217
workon < environment name>
mkvirtualenv <name>
Create a new virtualenv environment named <name>. The environment will be created in 
WORKON_HOME.
lsvirtualenv
List all of the enviornments stored in WORKON_HOME.
rmvirtualenv <name>
Remove the environment <name>. Uses folder_delete.bat.
workon [<name>]
If<name> isspecified, activate the environmentnamed <name> (change theworking virtualenv 
to <name>). If a project directory has been defined, we will change into it. If no argument is 
specified, list the available environments. One can pass additional option -c after virtualenv 
name to cd to virtualenv directory if no projectdir isset.
deactivate
Deactivate the working virtualenv and switch back to the default system Python.
add2virtualenv <full or relative path>
If a virtualenv environment is active, appends <path> to virtualenv_path_extensions.pth inside
Capítulo 46: Crear entorno virtual con 
virtualenvwrapper en windows
Examples
Entorno virtual con virtualenvwrapper para windows
Supongamos que necesita trabajar en tres proyectos diferentes. El proyecto A, el proyecto B y el 
proyecto C. el proyecto A y el proyecto B necesitan Python 3 y algunas bibliotecas requeridas.
Pero para el proyecto C necesitas Python 2.7 y bibliotecas dependientes.
Así que la mejor práctica para esto es separar esos entornos de proyecto. Para crear un entorno 
virtual de Python separado, debe seguir los siguientes pasos:
Paso 1: instala pip con este comando: python -m pip install -U pip
Paso 2: Luego instale el paquete "virtualenvwrapper-win" usando el comando (el comando puede 
ejecutarse en Windows Power Shell):
pip install virtualenvwrapper-win
Paso 3: Crea un nuevo entorno virtualenv usando el comando: mkvirtualenv python_3.5
Paso 4: Activar el entorno mediante el comando:
Comandos principales para virtualenvwrapper:
    282/1068
    218
the environment’s site-packages, which effectively adds <path> to the environment’s 
PYTHONPATH. If a virtualenv environment is not active, appends <path> to 
virtualenv_path_extensions.pth inside the default Python’s site-packages. If <path> doesn’t 
exist, it will be created.
    283/1068
    219
>>> ntohl = libc.ntohl
>>> ntohl
<_FuncPtr object at 0xbaadf00d>
>>> ntohl(0x6C) 
1811939328
>>> hex(_) 
'0x6c000000'
Capítulo 47: ctypes
Introducción
ctypes es una biblioteca incorporada de python que invoca funciones exportadas desde 
bibliotecas compiladas nativas.
Nota: Dado que esta biblioteca maneja el código compilado, es relativamente dependiente del 
sistema operativo.
Examples
Uso básico
Digamosquequeremosusarlalibc ntohl libc . 
Primero, debemos cargarlibc.so :
Entonces, obtenemos el objeto de función:
Y ahora, simplemente podemos invocar la función:
Lo que hace exactamente lo que esperamos que haga.
Errores comunes
No cargar un archivo
El primer error posible está fallando al cargar la biblioteca. En ese caso, un OSError normalmente 
se plantea.
Esto se debe a que el archivo no existe (o el sistema operativo no lo puede encontrar):
>>> from ctypes import *
>>> libc = cdll.LoadLibrary('libc.so.6')
>>> libc
<CDLL 'libc.so.6', handle baadf00d at 0xdeadbeef>
    284/1068
    220
>>> cdll.LoadLibrary("libc.so") 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/ctypes/ init .py", line 425, in LoadLibrary 
return self._dlltype(name)
File "/usr/lib/python3.5/ctypes/ init .py", line 347, in init
self._handle = _dlopen(self._name, mode)
OSError: /usr/lib/i386-linux-gnu/libc.so: invalid ELF header
>>> libc.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/ctypes/ init .py", line 360, in getattr
func = self. getitem(name)
File "/usr/lib/python3.5/ctypes/ init .py", line 365, in getitem
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /lib/i386-linux-gnu/libc.so.6: undefined symbol: foo
>>> obj = ctypes.c_int(12)
>>> obj 
c_long(12)
Como puede ver, el error es claro y bastante indicativo.
La segunda razón es que se encuentra el archivo, pero no tiene el formato correcto.
En este caso, el archivo es un archivo de script y no un archivo .so . Esto también puede suceder 
cuando se intenta abrir un archivo .dll en una máquina Linux o un archivo de 64 bits en un 
intérprete de 32 bits de Python. Como puede ver, en este caso el error es un poco más vago y 
requiere un poco de investigación.
No acceder a una función
Suponiendo que .so éxito el archivo .so , necesitamos acceder a nuestra función como lo hemos 
hecho en el primer ejemplo.
Cuando se usa una función que no existe, se AttributeError un AttributeError :
Objeto de ctypes básico
El objeto más básico es un int:
>>> cdll.LoadLibrary("foobar.so") 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/ctypes/ init .py", line 425, in LoadLibrary 
return self._dlltype(name)
File "/usr/lib/python3.5/ctypes/ init .py", line 347, in init
self._handle = _dlopen(self._name, mode)
OSError: foobar.so: cannot open shared object file: No such file or directory
    285/1068
    221
>>> sizeof(obj) 
4
>>> hex(addressof(obj)) 
'0xdeadbeef'
>>> c_int * 16
<class ' main .c_long_Array_16'>
>>> arr = (c_int * 16)(*range(16))
>>> arr
< main .c_long_Array_16 object at 0xbaddcafe>
>>> sizeof(arr)
64 # sizeof(c_int) * 16
>>> hex(addressof(arr)) 
'0xc000l0ff'
Ahora, obj refiere a una porción de memoria que contiene el valor 12. 
Se puede acceder a ese valor directamente, e incluso modificarse:
Ya que obj refiere a un trozo de memoria, también podemos averiguar su tamaño y ubicación:
arrays de ctypes
Como cualquier buen programador de C sabe, un solo valor no lo llevará tan lejos. ¡Lo que 
realmente nos hará avanzar son matrices!
Estono esuna matriz real, peroestá bastante cerca!Creamos unaclasequedenotauna matriz 
de 16 int s.
Ahora todo lo que tenemos que hacer es inicializarlo:
Ahora arr es una matriz real que contiene los números del 0 al 15. 
Se puede acceder a ellos como en cualquier lista:
Y al igual que cualquier otro objeto ctypes , también tiene un tamaño y una ubicación:
>>> arr[5] 
5
>>> arr[5] = 20
>>> arr[5] 
20
>>> obj.value 
12
>>> obj.value = 13
>>> obj 
c_long(13)
    286/1068
    222
>>> def max(x, y):
return x if x >= y else y
>>> CFUNCTYPE(c_int, c_int, c_int)
<CFunctionType object at 0xdeadbeef>
>>> CFUNCTYPE(c_int, c_int, c_int)(max)
<CFunctionType object at 0xdeadbeef>
>>> libc.ntohl() # garbage in - garbage out
>>> CFUNCTYPE(c_int, c_int)(libc.ntohl)() 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: this function takes at least 1 argument (0 given)
>>> compar_proto = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
>>> lfind_proto = CFUNCTYPE(c_void_p, c_void_p, c_void_p, POINTER(c_uint), c_uint, 
compar_proto)
Funciones de envoltura para ctypes.
En algunos casos, una función C acepta un puntero de función. Como usuarios ávidos de ctypes , 
nos gustaría usar esas funciones, e incluso pasar la función python como argumentos.
Vamos a definir una función:
Ahora, esa función toma dos argumentos y devuelve un resultado del mismo tipo. Por el bien del 
ejemplo, asumamos que el tipo es un int.
Como hicimos en el ejemplo de matriz, podemos definir un objeto que denota ese prototipo:
Ese prototipo denota una función que devuelve un c_int (el primer argumento), y acepta dos 
argumentos c_int (los otros argumentos).
Ahora vamos a envolver la función:
Los prototipos de funciones tienen un mayor uso: pueden envolver la función ctypes (como
libc.ntohl ) y verificar que se usan los argumentos correctos cuando se invoca la función.
Uso complejo
lfind todos los ejemplos anteriores en un escenario complejo: utilizando la libc lfind libc .
Para más detalles sobre la función, lea la página del manual . Les insto a que lo lean antes de 
continuar.
Primero, definiremos los prototipos adecuados:
Entonces, vamos a crear las variables:
    287/1068
    223
>>> def compar(x, y):
return x.contents.value - y.contents.value
>>> lfind = lfind_proto(libc.lfind)
>>> ptr = lfind(byref(key), byref(arr), byref(nmemb), sizeof(c_int), compar_proto(compar))
>>> cast(ptr, POINTER(c_int)).contents 
c_long(12)
>>> addressof(arr) + 12 * sizeof(c_int) == ptr 
True
Y ahora definimos la función de comparación:
Tenga en cuenta que x , y y son POINTER(c_int) , por lo tanto, debemos desreferenciarlos y tomar 
sus valores para poder comparar realmente el valor almacenado en la memoria.
Ahora podemos combinar todo juntos:
ptr es el puntero vacío devuelto. Si no se encontró la key en arr , el valor sería None , pero en este 
caso obtuvimos un valor válido.
Ahora podemos convertirlo y acceder al valor:
También, podemosverqueptr apuntaal valorcorrectodentrodearr:
>>> key = c_int(12)
>>> arr = (c_int * 16)(*range(16))
>>> nmemb = c_uint(16)
    288/1068
    224
from struct import pack
print(pack('I3c', 123, b'a', b'b', b'c')) # b'{\x00\x00\x00abc'
from struct import unpack
print(unpack('I3c', b'{\x00\x00\x00abc')) # (123, b'a', b'b', b'c')
import struct 
import sys
print "Native byteorder: ", sys.byteorder
# If no byteorder is specified, native byteorder is used 
buffer = struct.pack("ihb", 3, 4, 5)
print "Byte chunk: ", repr(buffer)
print "Byte chunk unpacked: ", struct.unpack("ihb", buffer)
# Last element as unsigned short instead of unsigned char ( 2 Bytes) 
buffer = struct.pack("ihh", 3, 4, 5)
print "Byte chunk: ", repr(buffer)
Capítulo 48: Datos binarios
Sintaxis
• paquete (fmt, v1, v2, ...)
• desempaquetar (fmt, buffer)
Examples
Formatear una lista de valores en un objeto byte
Desempaquetar un objeto byte de acuerdo con una cadena de formato
Embalaje de una estructura
El módulo " struct " proporciona facilidad para empaquetar objetos de python como trozos 
contiguos de bytes o para diseminar un trozo de bytes en estructuras de python.
La función de paquete toma una cadena de formato y uno o más argumentos, y devuelve una 
cadena binaria. Esto se parece mucho a que está formateando una cadena, excepto que la salida 
no es una cadena sino una porción de bytes.
Salida:
Byteorder nativo: fragmento de bytes pequeño: '\ x03 \ x00 \ x00 \ x00 \ x04 \ x00 \ x00' 
Fragmento de bytes sin empaquetar: (3, 4, 5) Fragmento de bytes: '\ x03 \ x00 \ x00 \
x00 \ x04 \ x00 \ x05 \ x00 '
    289/1068
    225
import struct
# If no byteorder is specified, native byteorder is used 
buffer = struct.pack("hhh", 3, 4, 5)
print "Byte chunk native byte order: ", repr(buffer) 
buffer = struct.pack("!hhh", 3, 4, 5)
print "Byte chunk network byte order: ", repr(buffer)
import struct
from ctypes import create_string_buffer 
bufferVar = create_string_buffer(8) 
bufferVar2 = create_string_buffer(8)
# We use a buffer that has already been created 
# provide format, buffer, offset and data 
struct.pack_into("hhh", bufferVar, 0, 3, 4, 5) 
print "Byte chunk: ", repr(bufferVar.raw) 
struct.pack_into("hhh", bufferVar2, 2, 3, 4, 5) 
print "Byte chunk: ", repr(bufferVar2.raw)
Puede usar el orden de bytes de la red con los datos recibidos de la red o datos del paquete para 
enviarlos a la red.
Salida:
Orden de bytes nativo del byte: '\ x03 \ x00 \ x04 \ x00 \ x05 \ x00' 
Orden de bytes de la red de bytes: '\ x00 \ x03 \ x00 \ x04 \ x00 \ x05'
Puede optimizar evitando la sobrecarga de asignar un nuevo búfer al proporcionar un búfer que 
se creó anteriormente.
Salida:
Fragmento de bytes: '\ x03 \ x00 \ x04 \ x00 \ x05 \ x00 \ x00 \ x00' 
Fragmento de bytes: '\ x00 \ x00 \ x03 \ x00 \ x04 \ x00 \ x05 \ x00'
    290/1068
    226
# This simplest decorator does nothing to the function being decorated. Such 
# minimal decorators can occasionally be used as a kind of code markers. 
def super_secret_function(f):
return f
@super_secret_function 
def my_function():
print("This is my secret function.")
Capítulo 49: Decoradores
Introducción
Las funciones de decorador son patrones de diseño de software. Alteran dinámicamente la 
funcionalidad de una función, método o clase sin tener que usar subclases directamente o 
cambiar el código fuente de la función decorada. Cuando se usan correctamente, los decoradores 
pueden convertirse en herramientas poderosas en el proceso de desarrollo. Este tema cubre la 
implementación y las aplicaciones de las funciones de decorador en Python.
Sintaxis
• def decorator_function (f): pass # define un decorador llamado decorator_function
• @decorator_function
def decorated_function (): pass # la función ahora está envuelta (decorada por) 
decorator_function
• decorated_function = decorator_function (decorated_function) # esto es equivalente a usar 
el azúcar sintáctico @decorator_function
Parámetros
Parámetro Detalles
F La función a decorar (envolver)
Examples
Función decoradora
Los decoradores aumentan el comportamiento de otras funciones o métodos. Cualquier función 
que tome una función como parámetro y devuelva una función aumentada puede usarse como 
decorador .
La notación @ es azúcar sintáctica que es equivalente a lo siguiente:
    291/1068
    227
def disabled(f): 
"""
This function returns nothing, and hence removes the decorated function 
from the local scope.
"""
pass
@disabled
def my_function():
print("This function can no longer be called...")
my_function()
# TypeError: 'NoneType' object is not callable
#This is the decorator 
def print_args(func):
def inner_func(*args, **kwargs): 
print(args)
print(kwargs)
return func(*args, **kwargs) #Call the original function with its arguments. 
return inner_func
@print_args
def multiply(num_a, num_b): 
return num_a * num_b
print(multiply(3, 5)) 
#Output:
# (3,5) - This is actually the 'args' that the function receives.
# {} - This is the 'kwargs', empty because we didn't specify keyword arguments. 
# 15 - The result of the function.
Es importante tener esto en cuenta para comprender cómo funcionan los decoradores. Esta 
sintaxis "no saturada" deja claro por qué la función decoradora toma una función como argumento 
y por qué debería devolver otra función. También demuestra lo que sucedería si no devuelves 
una función:
Por lo tanto, generalmente definimos una nueva función dentro del decorador y la devolvemos. 
Esta nueva función primero haría algo que debe hacer, luego llama a la función original y, 
finalmente, procesa el valor de retorno. Considere esta función decoradora simple que imprime 
los argumentos que recibe la función original y luego la llama.
Clase de decorador
Como se mencionó en laintroducción, un decoradores una función que se puede aplicar a otra 
funciónparaaumentarsucomportamiento.Elazúcarsintácticoesequivalentealosiguiente: 
my_func = decorator(my_func) . Pero, ¿y si el decorator fuera una clase? La sintaxis aún 
funcionaría, exceptoqueahora my_func sereemplaza conunainstanciadela clase decorator .Si 
esta clase implementa el método mágico call () , entonces todavía sería posible usar my_func 
como si fuera una función:
my_function = super_secret_function(my_function)
    292/1068
    228
import types
isinstance(testfunc, types.FunctionType) 
# False
type(testfunc)
# <class ' main .Decorator'>
from types import MethodType
class Decorator(object):
def init (self, func):
self.func = func
def call (self, *args, **kwargs): 
print('Inside the decorator.') 
return self.func(*args, **kwargs)
def get (self, instance, cls):
# Return a Method if it is called on an instance
return self if instance is None else MethodType(self, instance)
class Test(object): 
@Decorator 
def init (self):
pass
a = Test()
Tenga en cuenta que una función decorada con un decorador de clase ya no se considerará una 
"función" desde la perspectiva de la comprobación de tipo:
Métodos de decoración
Para los métodos de decoración debe definir un método get adicional:
class Decorator(object): 
"""Simple decorator class."""
def init (self, func): 
self.func = func
def call (self, *args, **kwargs): 
print('Before the function call.') 
res = self.func(*args, **kwargs) 
print('After the function call.') 
return res
@Decorator
def testfunc():
print('Inside the function.')
testfunc()
# Before the function call. 
# Inside the function.
# After the function call.
    293/1068
    229
from types import MethodType
class CountCallsDecorator(object): 
def init (self, func):
self.func = func
self.ncalls = 0 # Number of calls of this method
def call (self, *args, **kwargs):
self.ncalls += 1 # Increment the calls counter 
return self.func(*args, **kwargs)
def get (self, instance, cls):
return self if instance is None else MethodType(self, instance)
class Test(object): 
def init (self):
pass
@CountCallsDecorator 
def do_something(self):
return 'something was done'
from functools import wraps
Dentro del decorador.
¡Advertencia!
Los decoradores de clase solo producen una instancia para una función específica, por lo que 
decorar un método con un decorador de clase compartirá el mismo decorador entre todas las 
instancias de esa clase:
a = Test() 
a.do_something()
a.do_something.ncalls # 1
b = Test()
b.do_something()
b.do_something.ncalls # 2
Hacer que un decorador se vea como la función decorada.
Los decoradores normalmente eliminan los metadatos de la función ya que no son lo mismo. Esto 
puede causar problemas cuando se utiliza la meta-programación para acceder dinámicamente a 
los metadatos de la función. Los metadatos también incluyen las cadenas de documentación de la 
función y su nombre. functools.wraps hace que la función decorada se vea como la función 
original al copiar varios atributos a la función de envoltura.
Los dos métodos de envolver a un decorador están logrando lo mismo al ocultar que la función 
original ha sido decorada. No hay razón para preferir la versión de la función a la versión de clase 
a menos que ya esté utilizando una sobre la otra.
    294/1068
    230
def decorator(func):
# Copies the docstring, name, annotations and module to the decorator 
@wraps(func)
def wrapped_func(*args, **kwargs): 
return func(*args, **kwargs)
return wrapped_func
@decorator 
def test():
pass
test. name
class Decorator(object): 
def init (self, func):
# Copies name, module, annotations and docstring to the instance. 
self._wrapped = wraps(func)(self)
def call (self, *args, **kwargs): 
return self._wrapped(*args,**kwargs)
@Decorator 
def test():
"""Docstring of test.""" 
pass
test. doc
def decoratorfactory(message): 
def decorator(func):
def wrapped_func(*args, **kwargs):
Como una función
'prueba'
Como una clase
'Docstring of test'.
Decorador con argumentos (decorador de fábrica).
Un decorador toma solo un argumento: la función a decorar. No hay forma de pasar otros 
argumentos.
Pero a menudo se desean argumentos adicionales. El truco es, entonces, hacer una función que 
tome argumentos arbitrarios y devuelva un decorador.
Funciones de decorador
    295/1068
    231
@decoratorfactory # Without parentheses 
def test():
pass
test()
def decoratorfactory(*decorator_args, **decorator_kwargs):
class Decorator(object):
def init (self, func):
self.func = func
def call (self, *args, **kwargs):
print('Inside the decorator with arguments {}'.format(decorator_args)) 
return self.func(*args, **kwargs)
return Decorator
@decoratorfactory(10) 
def test():
pass
test()
El decorador quiere decirte: Hola Mundo.
Nota IMPORTANTE:
Con tales fábricas de decoradores debe llamar al decorador con un par de paréntesis:
TypeError: decorator () falta 1 argumento posicional requerido: 'func'
Clases de decorador
Dentro del decorador con argumentos (10,)
Crea una clase de singleton con un decorador.
Un singleton es un patrón que restringe la creación de instancias de una clase a una instancia / 
objeto. Usando un decorador, podemos definir una clase como un singleton forzando a la clase a
print('The decorator wants to tell you: {}'.format(message)) 
return func(*args, **kwargs)
return wrapped_func 
return decorator
@decoratorfactory('Hello World') 
def test():
pass
test()
    296/1068
    232
def singleton(cls): 
instance = [None]
def wrapper(*args, **kwargs): 
if instance[0] is None:
instance[0] = cls(*args, **kwargs) 
return instance[0]
return wrapper
# 3
instance.x = 3 
print(SomeSingletonClass().x)
@singleton
classSomeSingletonClass: x 
= 2
def init (self): 
print("Created!")
instance = SomeSingletonClass() # prints: Created! 
instance = SomeSingletonClass() # doesn't print anything 
print(instance.x) # 2
import time
def timer(func):
def inner(*args, **kwargs): 
t1 = time.time()
f = func(*args, **kwargs) 
t2 = time.time()
print 'Runtime took {0} seconds'.format(t2-t1) 
return f
return inner
@timer
def example_function(): 
#do stuff
example_function()
devolver una instancia existente de la clase o crear una nueva instancia (si no existe).
Este decorador se puede agregar a cualquier declaración de clase y se asegurará de que se cree 
como máximo una instancia de la clase. Cualquier llamada posterior devolverá la instancia de 
clase ya existente.
Por lo tanto, no importa si se refiere a la instancia de clase a través de su variable local o si crea 
otra "instancia", siempre obtiene el mismo objeto.
Usando un decorador para cronometrar una función.
    297/1068
    233
def func(myList):
for item in myList: 
print(item)
func([1,2,3,5,7])
1
2
3
5
7
aList = ['a','b','c','d'] 
func(aList)
a 
b 
c 
d
Capítulo 50: Definiendo funciones con 
argumentos de lista
Examples
Función y Llamada
Las listas como argumentos son solo otra variable:
y se puede pasar en la llamada de función en sí:
O como una variable:
    298/1068
    234
with shelve.open('spam') as db: 
db['eggs'] = 'eggs'
Capítulo 51: dejar de lado
Introducción
Shelve es un módulo de Python que se utiliza para almacenar objetos en un archivo. El módulo 
de almacenamiento implementa el almacenamiento persistente para objetos Python arbitrarios 
que pueden ser decapados, utilizando una API similar a un diccionario. El módulo de 
almacenamiento puede usarse como una opción de almacenamiento persistente simple para 
objetos de Python cuando una base de datos relacional es excesiva. Se accede a la estantería 
mediante llaves, igual que con un diccionario. Los valores se decapan y se escriben en una base 
de datos creada y administrada por anydbm.
Observaciones
Nota: No confíe en que el estante se cierre automáticamente; siempre llame a close() 
explícitamente cuando ya nolonecesite más,ouse shelve.open() como administrador de 
contexto:
Advertencia:
Debido a que la shelve módulo está respaldado por pickle , es inseguro para cargar un estante de 
una fuente no fiable. Al igual que con Pickle, cargar un estante puede ejecutar código arbitrario.
Restricciones
1 . La elección del paquete de base de datos que se utilizará (como dbm.ndbm o dbm.gnu) 
depende de la interfaz disponible. Por lo tanto, no es seguro abrir la base de datos directamente 
usando dbm. La base de datos también está (desafortunadamente) sujeta a las limitaciones de 
dbm, si se usa; esto significa que (la representación en escabeche) de los objetos almacenados 
en la base de datos debería ser bastante pequeña, y en casos raros, las colisiones de claves 
pueden hacer que la base de datos rechazar actualizaciones.
2. El módulo de archivado no admite el acceso simultáneo de lectura / escritura a objetos 
archivados. (Múltiples accesos de lectura simultáneos son seguros.) Cuando un programa tiene 
un estante abierto para escribir, ningún otro programa debería tenerlo abierto para leer o escribir. 
El bloqueo de archivos de Unix se puede usar para resolver esto, pero esto difiere entre las 
versiones de Unix y requiere conocimiento sobre la implementación de la base de datos utilizada.
Examples
    299/1068
    235
import shelve
database = shelve.open(filename.suffix) 
object = Object()
database['key'] = object
d.close() # close it
# as d was opened WITHOUT writeback=True, beware:
d['xx'] = [0, 1, 2] # this works as expected, but... 
d['xx'].append(3) # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!
# having opened d without writeback=True, you need to code carefully: 
temp = d['xx'] # extracts the copy
temp.append(5) # mutates the copy
d['xx'] = temp # stores the copy right back, to persist it
# or, d=shelve.open(filename,writeback=True) would let you just code 
# d['xx'].append(5) and have it work as expected, BUT it would also 
#consumemorememory andmake the d.close() operation slower.
# true if the key exists
# a list of all existing keys (slow!)
flag = key in d
klist = list(d.keys())
# store data at key (overwrites old data if 
# using an existing key)
# retrieve a COPY of data at key (raise KeyError 
# if no such key)
# delete data stored at key (raises KeyError 
# if no such key)
d[key] = data 
data = d[key]
del d[key]
import shelve
d = shelve.open(filename) # open -- file may get suffix added by low-level
# library
import shelve
s = shelve.open('test_shelf.db') 
try:
s['key1'] = { 'int': 10, 'float':9.5, 'string':'Sample data' }
Código de muestra para estantería
Para archivar un objeto, primero importe el módulo y luego asigne el valor del objeto de la 
siguiente manera:
Para resumir la interfaz (la clave es una cadena, los datos son un objeto 
arbitrario):
Creando un nuevo estante
La forma más sencilla de usar shelve es a través de la clase DbfilenameShelf . Utiliza anydbm 
para almacenar los datos. Puede usar la clase directamente, o simplemente llamar a shelve.open 
() :
    300/1068
    236
import shelve
s = shelve.open('test_shelf.db') 
try:
existing = s['key1'] 
finally:
s.close()
print existing
$ python shelve_create.py
$ python shelve_existing.py
{'int': 10, 'float': 9.5, 'string': 'Sample data'}
import shelve
s = shelve.open('test_shelf.db', flag='r') 
try:
existing = s['key1'] 
finally:
s.close()
print existing
import shelve
s = shelve.open('test_shelf.db') 
try:
print s['key1']
s['key1']['new_value'] = 'this was not here before' 
finally:
Para volver a acceder a los datos, abra el estante y utilícelo como un diccionario:
Si ejecuta ambos scripts de muestra, debería ver:
El módulo dbm no admite múltiples aplicaciones que escriban en la misma base de datos al 
mismo tiempo. Si sabe que su cliente no modificará el estante, puede pedirle a la estantería que 
abra la base de datos de solo lectura.
Si su programa intenta modificar la base de datos mientras se abre solo para lectura, se genera 
una excepción de error de acceso. El tipo de excepción depende del módulo de base de datos 
seleccionado por anydbm cuando se creó la base de datos.
Respóndeme
Los estantes no rastrean las modificaciones a objetos volátiles, por defecto. Eso significa que si 
cambia el contenido de un elemento almacenado en el estante, debe actualizar el estante 
explícitamente almacenándolo nuevamente.
finally:
s.close()
    301/1068
    237
$ python shelve_create.py
$ python shelve_withoutwriteback.py
{'int': 10, 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'float': 9.5, 'string': 'Sample data'}
import shelve
s = shelve.open('test_shelf.db', writeback=True) 
try:
print s['key1']
s['key1']['new_value'] = 'this was not here before' 
print s['key1']
finally:
s.close()
s = shelve.open('test_shelf.db', writeback=True) 
try:
print s['key1'] 
finally:
s.close()
$ python shelve_create.py
$ python shelve_writeback.py
{'int': 10, 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}
En este ejemplo, el diccionario en 'key1' no se almacena de nuevo, por lo que cuando el estante 
se vuelve a abrir, los cambios no se han conservado.
Para capturar automáticamente los cambios en los objetos volátiles almacenados en el estante, 
abra el estante con la función de escritura habilitada. El indicador de reescritura hace que el 
estante recuerde todos los objetos recuperados de la base de datos utilizando un caché en 
memoria. Cada objeto de caché también se vuelve a escribir en la base de datos cuando se cierra 
el estante.
Aunque reduce la posibilidad de error del programador y puede hacer que la persistencia del 
objeto sea más transparente, el uso del modo de reescritura puede no ser deseable en todas las 
situaciones. La memoria caché consume memoria adicional mientras el estante está abierto, y 
hacer una pausa para escribir cada objeto almacenado en caché de nuevo en la base de datos 
cuando se cierra puede llevar más tiempo. Dado que no hay forma de saber si los objetos 
almacenados en caché se han modificado, todos se han vuelto a escribir. Si su aplicación lee 
datos más de lo que escribe, la respuesta por escrito agregará más sobrecarga de la que podría 
desear.
s.close()
s = shelve.open('test_shelf.db', writeback=True) 
try:
print s['key1'] 
finally:
s.close()
    302/1068
    238
{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}
    303/1068
    239
python -m pdb <my_file.py>
import pdb
def divide(a, b): 
pdb.set_trace() 
return a/b
# What's wrong with this? Hint: 2 != 3
print divide(1, 2)
python foo.py
> ~/scratch/foo.py(5)divide()
-> return a/b 
(Pdb)
import pdf; pdb.set_trace()
(Pdb) p a 
1
(Pdb) print a
Capítulo 52: Depuración
Examples
El depurador de Python: depuración paso a paso con _pdb_
La biblioteca estándar de Python incluye una biblioteca de depuración interactiva llamada pdb . 
pdb tiene capacidades extensivas, la más comúnmente utilizada es la capacidad de "avanzar" en 
un programa.
Para entrar de inmediato en el uso de depuración paso a paso:
Esto iniciará el depurador en la primera línea del programa.
Por lo general, deseará apuntar a una sección específica del código para la depuración. Para 
hacer esto, importamos la biblioteca pdb y usamos set_trace () para interrumpir el flujo de este 
código de ejemplo problemático.
Ejecutando este programa se iniciará el depurador interactivo.
A menudo, este comando se usa en una línea, por lo que se puede comentar con un solo # 
carácter
En el comando (Pdb) se pueden introducir comandos. Estos comandos pueden ser comandos de 
depuración o python. Para imprimir variables podemos usar p del depurador, o la impresión de 
python.
    304/1068
    240
locals
-> return a/b 
(Pdb) p a+b 
3
(Pdb) [ str(m) for m in [a,b]]
['1', '2']
(Pdb) [ d for d in xrange(5)] 
[0, 1, 2, 3, 4]
(Pdb) !c
Para ver la lista de todas las variables locales use
función incorporada
Estos son buenos comandos de depuración para saber:
b <n> | <f>: set breakpoint at line *n* or function named *f*. 
# b 3
# b divide
b: show all breakpoints.
c: continue until the next breakpoint.
s: step through this line (will enter a function). 
n: step over this line (jumps over a function). 
r: continue until the current function returns.
l: list a window of code around this line. 
p <var>: print variable named *var*.
# p x
q: quit debugger.
bt: print the traceback of the current execution call stack
up: move your scope up the function call stack to the caller of the current function 
down: Move your scope back down the function call stack one level
step: Run the program until the next line of execution in the program, then return control 
back to the debugger
next: run the program until the next line of execution in the current function, then return 
control back to the debugger
return: run the program until the current function returns, then return control back to the 
debugger
continue: continue running the program until the next breakpoint (or set_trace si called 
again)
El depurador también puede evaluar python interactivamente:
Nota:
Si alguno de sus nombres de variable coincide con los comandos del depurador, use un signo de 
exclamación ' ! 'antes de la var para referirse explícitamente a la variable y no al comando del 
depurador. Por ejemplo, a menudo puede suceder que use el nombre de variable ' c ' para un 
contador, y tal vez desee imprimirlo mientras está en el depurador. un simple comando ' c ' 
continuaría la ejecución hasta el siguiente punto de interrupción. En su lugar, use ' ! C ' para 
imprimir el valor de la variable de la siguiente manera:
1
    305/1068
    241
import ipdb 
ipdb.set_trace()
/home/usr/ook.py(3)<module>() 
1 import ipdb
2 ipdb.set_trace()
----> 3 print("Hello world!")
ipdb>
from IPython.core import ultratb
sys.excepthook = ultratb.FormattedTB(mode='Verbose',
color_scheme='Linux', 
call_pdb=1)
# In the Python file you want to debug. 
import rpdb
rpdb.set_trace()
# Call in a terminal to see the output
$ nc 127.0.0.1 4444
> /home/usr/ook.py(3)<module>()
-> print("Hello world!")
A través de IPython y ipdb
Si se instala IPython (o Jupyter ), se puede invocar al depurador usando:
Cuando se alcanza, el código saldrá e imprimirá:
Claramente, esto significa que uno tiene que editar el código. Hay una forma más sencilla:
Esto hará que se llame al depurador si se produce una excepción no detectada.
Depurador remoto
Algunasvecesnecesitasdepurarel códigopython que seejecuta medianteotro proceso y,en 
este caso, rpdb es muy útil.
rpdb es un envoltorio alrededor de pdb que redirige stdin y stdout a un controlador de 
socket. Por defecto abre el depurador en el puerto 4444.
Uso:
Y luego necesitas ejecutar esto en la terminal para conectarte a este proceso.
Y obtendrás pdb promt
4
    306/1068
    242
(Pdb)
    307/1068
    243
file_unzip = 'filename.zip'
unzip=zipfile.ZipFile(file_unzip, 'r') 
unzip.extractall()
unzip.close()
file_untar = 'filename.tar.gz' 
untar = tarfile.TarFile(file_untar) 
untar.extractall()
untar.close()
Capítulo 53: Descomprimir archivos
Introducción
Paraextraero descomprimir un archivo tar,ZIPogzip,seproporcionan los módulos tarfile, zipfile 
ygzipdePython,respectivamente.ElmóduloTarFile.extractall(path=".", members=None)Python 
proporciona la función TarFile.extractall(path=".", members=None) para extraer de un archivo 
tarball.El módulo zipfile dePython proporcionala función ZipFile.extractall([path[, members[, 
pwd]]])paraextraerodescomprimirarchivoscomprimidosZIP.Finalmente,elmódulogzipde 
Python proporciona la clase GzipFile para descomprimir.
Examples
Usando Python ZipFile.extractall () para descomprimir un archivo ZIP
Usando Python TarFile.extractall () para descomprimir un tarball
    308/1068
    244
descr. get (self, obj, type=None) --> value 
descr. set (self, obj, value) --> None 
descr. delete (self, obj) --> None
class DescPrinter(object):
"""A data descriptor that logs activity."""
_val = 7
defget(self,obj,objtype=None): 
print('Getting ...')
return self._val
def set (self, obj, val): 
print('Setting', val) 
self._val = val
def delete (self, obj): 
print('Deleting ...') 
del self._val
class Foo():
x = DescPrinter()
i = Foo() 
i.x
# Getting ... 
# 7
i.x = 100
# Setting 100
Capítulo 54: Descriptor
Examples
Descriptor simple
Haydos tipos diferentes de descriptores.Los descriptoresdedatos se definencomoobjetosque 
definen tanto un get () como un set () , mientras que los descriptores que no son de datos 
solo definen un get () . Esta distinción es importante cuando se consideran las sustituciones y 
el espacio de nombres del diccionario de una instancia.Si un descriptor de datos y una entrada 
en el diccionario de una instancia comparten el mismo nombre, el descriptor de datos tendrá 
prioridad. Sin embargo, si en cambio un descriptor que no es de datos y una entrada en el 
diccionario de una instancia comparten el mismo nombre, la entrada del diccionario de la 
instancia tendrá prioridad.
Para hacer un descriptor de datos de solo lectura, defina tanto get () como set () con el conjunto 
() generando un AttributeError cuando se le llama. Definir el método set () con un marcador de 
posición de aumento de excepción es suficiente para convertirlo en un descriptor de datos.
Un ejemplo implementado:
    309/1068
    245
>>> oscillator = Oscillator(freq=100.0) # Set frequency to 100.0 Hz
>>>oscillator.period # Period is 1 / frequency, i.e. 0.01 seconds 
0.01
>>> oscillator.period = 0.02 # Set period to 0.02seconds
>>> oscillator.freq # The frequency is automatically adjusted 
50.0
>>> oscillator.freq = 200.0 # Set the frequency to 200.0 Hz
>>> oscillator.period # The period is automatically adjusted 
0.005
class Hertz(object):
def get (self, instance, owner): 
return self.value
def set (self, instance, value): 
self.value = float(value)
class Second(object):
def get (self, instance, owner):
# When reading period, convert from frequency 
return 1 / instance.freq
def set (self, instance, value):
# When setting period, update the frequency 
instance.freq = 1 / float(value)
Conversiones bidireccionales
Los objetos descriptores pueden permitir que los atributos de los objetos relacionados reaccionen 
a los cambios automáticamente.
Supongamos que queremos modelar un oscilador con una frecuencia determinada (en hercios) y 
un período (en segundos). Cuando actualizamos la frecuencia, queremos que el período se 
actualice, y cuando actualizamos el período, queremos que la frecuencia se actualice:
Seleccionamos uno de los valores (frecuencia, en Hertz) como el "ancla", es decir, el que se 
puede establecer sin conversión, y escribimos una clase de descriptor para él:
El "otro" valor (período, en segundos) se define en términos del ancla. Escribimos una clase de 
descriptor que hace nuestras conversiones:
Ahora podemos escribir la clase Oscilador:
i.x
# Getting ... 
# 100
del i.x
# Deleting... 
i.x
# Getting ... 
# 7
    310/1068
    246
class Oscillator(object):
period = Second() # Set the other value as a class attribute
def init (self, freq):
self.freq = Hertz() # Set the anchor value as an instance attribute 
self.freq = freq # Assign the passed value - self.period will be adjusted
    311/1068
    247
$ conda install binstar
$ conda update binstar
$ pip install binstar
$ binstar login
$ binstar whoami
$ git clone https://github.com/<NAME>/<Package>
package/
setup.py 
test_package/
 init .py 
hello.py 
bld.bat 
build.sh 
meta.yaml
Capítulo 55: Despliegue
Examples
Cargando un paquete Conda
Antes de comenzar debes tener:
Anaconda instalado en su sistema Cuenta en Binstar Si no está utilizando Anaconda 1.6+, instale 
el cliente de línea de comandos de binstar :
Si no está utilizando Anaconda, Binstar también está disponible en pypi:
Ahora podemos iniciar sesión:
Prueba tu nombre de usuario con el comando whoami:
Vamos a cargar un paquete con una función simple de "hola mundo". Para seguir, comience 
obteniendo mi paquete de demostración de Github:
Este es un pequeño directorio que se ve así:
Setup.py es el archivo de compilación estándar de python y hello.py tiene nuestra única función 
hello_world ().
bld.bat , build.sh y meta.yaml son scripts y metadatos para el paquete Conda . Puede leer lapágina 
decompilación de Condapara obtener más información sobre esos tresarchivos y supropósito.
    312/1068
    248
$ conda build test_package/
$ binstar upload /home/xavier/anaconda/conda-bld/linux-64/test_package-0.1.0-py27_0.tar.bz2
Ahora creamos el paquete ejecutando:
Eso es todo lo que se necesita para crear un paquete Conda.
El último paso es cargar en binstar copiando y pegando la última línea de la impresión después 
de ejecutar el comando / paquete de conda build test. En mi sistema el comando es:
Como es la primera vez que creas un paquete y una versión, se te pedirá que completes algunos 
campos de texto que, alternativamente, se podrían hacer a través de la aplicación web.
Verá una done impresa para confirmar que ha cargado correctamente su paquete Conda en 
Binstar.
    313/1068
    249
dictionary = {"Hello": 1234, "World": 5678} 
print(dictionary["Hello"])
Capítulo 56: Diccionario
Sintaxis
• mydict = {}
• mydict [k] = valor
• valor = mydict [k]
• valor = mydict.get (k)
• value = mydict.get (k, "default_value")
Parámetros
Parámetro Detalles
llave La clave deseada para buscar
valor El valor a establecer o devolver.
Observaciones
Elementos útiles para recordar al crear un diccionario:
• Cada clave debe ser única (de lo contrario, se anulará)
• Cada tecla tiene que ser hashable (puede usar el hash la función hash que, de lo contrario
TypeError será lanzada)
• No hay un orden particular para las llaves.
Examples
Accediendo a los valores de un diccionario.
El código anterior imprimirá 1234 .
La cadena "Hello" en este ejemplo se llama clave . Se utiliza para buscar un valor en el dict
colocando la clave entre corchetes.
El número 1234 se ve después de los dos puntos respectivos en la definición de dict . Esto se 
llama el valor al que "Hello" asigna en este dict .
Buscar un valor como este con una clave que no existe KeyError una excepción KeyError , que
KeyError ejecución si no se detecta. Si queremos acceder a un valor sin arriesgar un KeyError ,
    314/1068
    250
w = dictionary.get("whatever")
x = dictionary.get("whatever", "nuh-uh")
6}
3}
3}
# {'d': 4, 'e': 5, 'f':
# {'a': 1, 'b': 2, 'c':
# {'a': 1, 'b': 2, 'c':
dict(a=1, b=2, c=3) # {'a': 1, 'b': 2, 'c': 3}
dict([('d', 4), ('e', 5), ('f', 6)])
dict([('a', 1)], b=2, c=3)
dict({'a' : 1, 'b' : 2}, c=3)
mydict = {} 
mydict['not there']
Traceback (most recent call last): 
File "<stdin>", line 1, in<module>
KeyError: 'not there'
value = mydict.get(key, default_value)
mydict = {} 
print(mydict) 
# {}
print(mydict.get("foo", "bar")) 
# bar
print(mydict) 
# {}
print(mydict.setdefault("foo", "bar")) 
# bar
podemos usar el método dictionary.get . Por defecto, si la clave no existe, el método devolverá 
None . Podemos pasarle un segundo valor para devolver en lugar de None en caso de una 
búsqueda fallida.
En este ejemplo, w obtendrá el valor None y x obtendrá el valor "nuh-uh" .
El constructor dict ()
El constructor dict() se puede utilizar para crear diccionarios a partir de argumentos de palabras 
clave, o desde una única iterable de pares clave-valor, o desde un diccionario único y argumentos 
de palabras clave.
Evitar las excepciones de KeyError
Unerror común cuando se usan diccionarios esacceder a una clave que no existe.Esto 
generalmente resulta en una excepción KeyError
Una forma de evitar errores clave es utilizar el método dict.get , que le permite especificar un 
valor predeterminado para devolver en el caso de una clave ausente.
Lo que devuelve mydict[key] si existe, pero de lo contrario devuelve default_value . Tenga en 
cuentaqueestonoagregakey amydict. Asíque si deseaconservar esepardevaloresclave, se 
debe utilizar mydict.setdefault(key, default_value) , lo que almacenar el par de valores clave.
    315/1068
    251
try:
value = mydict[key] 
except KeyError:
value = default_value
if key in mydict:
value = mydict[key] 
else:
value = default_value
mydict = {
'a': '1',
'b': '2'
}
print(mydict.keys()) 
# Python2: ['a', 'b']
# Python3: dict_keys(['b', 'a'])
print(mydict.values()) 
# Python2: ['1', '2']
# Python3: dict_values(['2', '1'])
Una forma alternativa de lidiar con el problema es atrapar la excepción.
También puede comprobar si la clave está in el diccionario.
Sin embargo, tenga en cuenta que, en entornos de subprocesos múltiples, es posible que la clave 
se elimine del diccionario después de la verificación, creando una condición de carrera en la que 
aún se puede lanzar la excepción.
Otra opción es usar una subclase de dict, collections.defaultdict, que tiene un default_factory para 
crear nuevas entradas en el dict cuando se le da una new_key.
Acceso a claves y valores.
Cuando se trabaja con diccionarios, a menudo es necesario acceder a todas las claves y valores 
del diccionario, ya sea en un bucle for , en una lista de comprensión, o simplemente como una 
lista simple.
Dado un diccionario como:
Puede obtener una lista de claves utilizando el método keys() :
Si, en cambio, desea una lista de valores, use el método de values() :
Si desea trabajar con la clave y su valor correspondiente, puede usar el método items() :
print(mydict)
# {'foo': 'bar'}
    316/1068
    252
# empty dict
# dict with initial values
d = {}
d = {'key': 'value'}
# Also unpacking one or multiple dictionaries with the literal syntax is possible
# makes a shallow copy of otherdict 
d = {**otherdict}
# also updates the shallow copy with the contents of the yetanotherdict. 
d = {**otherdict, **yetanotherdict}
d = {k:v for k,v in [('key', 'value',)]}
NOTA:Debidoaqueundictno estáclasificado,laskeys(),losvalues()ylositems()notienen 
ordendeclasificación.Usesort(),sorted()oOrderedDictsileimportaelordenenqueregresan 
estos métodos.
DiferenciadePython 2/3:EnPython3,estosmétodos devuelvenobjetosespeciales iterables, 
no listas, y son el equivalente de los iterkeys() , itervalues() y iteritems() . Estos objetos se 
pueden usarcomolistasen su mayor parte,aunque hay algunas diferencias.VerPEP3106para 
más detalles.
Introducción al Diccionario
Un diccionario es un ejemplo de un almacén de valores clave también conocido como Mapeo en 
Python. Le permite almacenar y recuperar elementos haciendo referencia a una clave. Como los 
diccionarios son referenciados por clave, tienen búsquedas muy rápidas. Como se utilizan 
principalmente para hacer referencia a elementos por clave, no están ordenados.
creando un dict
Los diccionarios se pueden iniciar de muchas maneras:
sintaxis literal
Python 3.x 3.5
comprensión de dictado
Ver también: Comprensiones.
clase incorporada: dict()
print(mydict.items())
# Python2: [('a', '1'), ('b', '2')]
# Python3: dict_items([('b', '2'), ('a', '1')])
    317/1068
    253
d['newkey'] = 42
d['new_list'] = [1, 2, 3] 
d['new_dict'] = {'nested_dict': 1}
del d['newkey']
# 'full'
# 'empty'
# 5
d = defaultdict(lambda: 'empty') 
d['key']
d['key'] = 'full' 
d['key']
# 0
from collections import defaultdict
d = defaultdict(int) 
d['key']
d['key'] = 5
d['key']
>>> d = {}
{}
>>> d.setdefault('Another_key', []).append("This worked!")
>>> d
{'Another_key': ['This worked!']}
modificando un dict
Para agregar elementos a un diccionario, simplemente cree una nueva clave con un valor:
También es posible agregar list y dictionary como valor:
Para eliminar un elemento, elimine la clave del diccionario:
Diccionario con valores por defecto
Disponible en la biblioteca estándar como defaultdict
[*]Alternativamente, sidebesusarlaclasedict incorporada, using dict.setdefault() tepermitirá 
crear unvalor predeterminado cadavezqueusing dict.setdefault() aunaclavequeno existía 
antes:
Tenga en cuenta que si tiene muchos valores paraagregar, dict.setdefault() creará una nueva 
instanciadelvalorinicial(eneste ejemploa[]) cadavezquesellame,loquepuedecrear cargas
d = dict() # emtpy dict
d = dict(key='value') # explicit keyword arguments
d = dict([('key', 'value')]) # passing in a list of key/value pairs
# make a shallow copy of another dict (only possible if keys are only strings!) 
d = dict(**otherdict)
    318/1068
    254
from collections import OrderedDict
d = OrderedDict() 
d['first'] = 1
d['second'] = 2
d['third'] = 3
d['last'] = 4
# Outputs "first 1", "second 2", "third 3", "last 4" 
for key in d:
print(key, d[key])
>>>
>>> def parrot(voltage, state, action):
... print("This parrot wouldn't", action, end=' ')
... print("if you put", voltage, "volts through it.", end='')
... print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
>>> fish = {'name': "Nemo", 'hands': "fins", 'special': "gills"}
>>> dog = {'name': "Clifford", 'hands': "paws", 'color': "red"}
>>> fishdog = {**fish, **dog}
>>> fishdog
{'hands': 'paws', 'color': 'red', 'name': 'Clifford', 'special': 'gills'}
de trabajo innecesarias.
[*] Python Cookbook, 3ª edición, por David Beazley y Brian K. Jones (O'Reilly). Derechos de autor 
2013 David Beazley y Brian Jones, 978-1-449-34037-7.
Creando un diccionario ordenado
Puede crear un diccionario ordenado que seguirá un orden determinado al iterar sobre las claves 
en el diccionario.
Usa OrderedDict del módulo de collections . Esto siempre devolverá los elementos del diccionario 
en el orden de inserción original cuando serepita.
Desempaquetando diccionarios usando el operador **
Puede utilizar el operador de desempaquetado de ** argumentos de palabras clave para entregar 
los pares clave-valor en un diccionario en los argumentos de una función. Un ejemplo simplificado 
de la documentación oficial :
ApartirdePython 3.5, tambiénpuede utilizar esta sintaxispara fusionarunnúmero arbitrariode 
objetos dict .
Como lo demuestra este ejemplo, las claves duplicadas se asignan a su último valor (por ejemplo,
    319/1068
    255
>>> fishdog = {**fish, **dog}
>>> fishdog
{'hands': 'paws', 'color': 'red', 'name': 'Clifford', 'special': 'gills'}
>>> from collections import ChainMap
>>> dict(ChainMap(fish, dog))
{'hands': 'fins', 'color': 'red', 'special': 'gills', 'name': 'Nemo'}
>>> from itertools import chain
>>> dict(chain(fish.items(), dog.items()))
{'hands': 'paws', 'color': 'red', 'name': 'Clifford', 'special': 'gills'}
>>> fish.update(dog)
>>> fish
{'color': 'red', 'hands': 'paws', 'name': 'Clifford', 'special': 'gills'}
"Clifford" reemplaza a "Nemo"). 
Fusionando diccionarios 
Considere los siguientes diccionarios:
Python 3.5+
Como lo demuestra este ejemplo, las claves duplicadas se asignan a su último valor (por ejemplo, 
"Clifford" reemplaza a "Nemo").
Python 3.3+
Con esta técnica, el valor más importante tiene prioridad para una clave dada en lugar de la 
última ("Clifford" se desecha a favor de "Nemo").
Python 2.x, 3.x
Esto utiliza el último valor, como en la técnica basada en ** para la fusión ("Clifford" anula 
"Nemo").
dict.update utiliza el último dict para sobrescribir el anterior.
>>> fish = {'name': "Nemo", 'hands': "fins", 'special': "gills"}
>>> dog = {'name': "Clifford", 'hands': "paws", 'color': "red"}
    320/1068
    256
role = {"By day": "A typical programmer",
"By night": "Still a typical programmer", }
options = {
"x": ["a", "b"], 
"y": [10, 20, 30]
}
import itertools
options = {
"x": ["a", "b"],
"y": [10, 20, 30]}
keys = options.keys()
values = (options[key] for key in keys)
combinations = [dict(zip(keys, combination)) for combination in itertools.product(*values)] 
print combinations
[{'x': 'a', 'y': 10},
{'x': 'b', 'y': 10},
{'x': 'a', 'y': 20},
{'x': 'b', 'y': 20},
{'x': 'a', 'y': 30},
{'x': 'b', 'y': 30}]
d = {'a': 1, 'b': 2, 'c':3}
for key in d:
La coma final
Al igual que las listas y las tuplas, puede incluir una coma al final en su diccionario.
El PEP 8 dicta que debe dejar un espacio entre la coma final y la llave de cierre.
Todas las combinaciones de valores de diccionario.
Dado un diccionario como el que se muestra arriba, donde hay una lista que representa un 
conjuntodevaloresparaexplorarlaclavecorrespondiente.Supongamosquedeseaexplorar 
"x"="a" con "y"=10 , luego "x"="a" con "y"=10 , y así sucesivamente hasta que haya explorado 
todas las combinaciones posibles.
Puede crear una lista que devuelva todas estas combinaciones de valores utilizando el siguiente 
código.
Esto nos da la siguiente lista almacenada en las combinations variables:
Iterando sobre un diccionario
Si utiliza un diccionario como iterador (por ejemplo, en una declaración for ), atraviesa las claves
del diccionario. Por ejemplo:
    321/1068
    257
print([keyforkeyind]) 
# ['c', 'b', 'a']
for key, value in d.items(): 
print(key, value)
# c 3
# b 2
# a 1
for key, value in d.values(): 
print(key, value)
# 3
# 2
# 1
# Creating and populating it with values 
stock = {'eggs': 5, 'milk': 2}
# Or creating an empty dictionary 
dictionary = {}
# And populating it after 
dictionary['eggs'] = 5
dictionary['milk'] = 2
# Values can also be lists
Lo mismo es cierto cuando se usa en una comprensión.
Python 3.x 3.0
El método items() se puede utilizar para recorrer simultáneamente tanto la clave como el valor :
Si bien el método de values() se puede usar para iterar solo sobre los valores, como se esperaría:
Python 2.x 2.2
Aquí,laskeys()métodoskeys(),losvalues()ylositems()devuelvenlaslistas,yexistenlostres 
métodos adicionales iterkeys() itervalues() y iteritems() para devolver los iteraters.
Creando un diccionario
Reglas para crear un diccionario:
• Cada clave debe ser única (de lo contrario, se anulará)
• Cada tecla tiene que ser hashable (puede usar el hash la función hash que, de lo contrario
TypeError será lanzada)
• No hay un orden particular para las llaves.
print(key, d[key]) 
# c 3
# b 2
# a 1
    322/1068
    258
car = {} 
car["wheels"] = 4 
car["color"] = "Red"
car["model"] = "Corvette"
print "Little " + car["color"] + " " + car["model"] + "!" 
# This would print out "Little RedCorvette!"
car = {"wheels": 4, "color": "Red", "model": "Corvette"}
for key in car:
print key + ": " + car[key]
# wheels: 4 
# color: Red
# model: Corvette
Diccionarios ejemplo
Diccionarios mapean claves a valores.
Los valores del diccionario se pueden acceder por sus claves.
Los diccionarios también se pueden crear en un estilo JSON:
Los valores del diccionario se pueden iterar sobre:
mydict = {'a': [1, 2, 3], 'b': ['one', 'two', 'three']}
# Use list.append() method to add new elements to the values list 
mydict['a'].append(4) # => {'a': [1, 2, 3, 4], 'b': ['one', 'two', 'three']}
mydict['b'].append('four') # => {'a': [1, 2, 3, 4], 'b': ['one', 'two', 'three', 'four']}
# We can also create a dictionary using a list of two-items tuples 
iterable = [('eggs', 5), ('milk', 2)]
dictionary = dict(iterables)
# Or using keyword argument:
dictionary = dict(eggs=5, milk=2)
# Another way will be to use the dict.fromkeys:
dictionary = dict.fromkeys((milk, eggs)) # => {'milk': None, 'eggs': None} 
dictionary = dict.fromkeys((milk, eggs), (2, 5)) # => {'milk': 2, 'eggs': 5}
    323/1068
    259
import sys 
sys.path.append("package.zip")
def hi():
print("Hello world!")
import module 
module.hi()
>>> from module import hi
>>> hi()
# Hello world!
Capítulo 57: Diferencia entre Módulo y 
Paquete
Observaciones
Es posible poner un paquete de Python en un archivo ZIP, y usarlo de esa manera si agrega 
estas líneas al comienzo de su script:
Examples
Módulos
Un módulo es un único archivo de Python que se puede importar. El uso de un módulo se ve así:
module.py
my_script.py
en un intérprete
Paquetes
Un paquete se compone de varios archivos (o módulos) de Python e incluso puede incluir 
bibliotecas escritas en C o C ++. En lugar de ser un solo archivo, es una estructura de carpetas 
completa que podría tener este aspecto:
package carpetas
• init .py
• dog.py
• hi.py
 init .py
    324/1068
    260
def woof():
print("WOOF!!!")
def hi():
print("Hello world!")
dog.py
hi.py
TodoslospaquetesdePythondebencontenerunarchivo init .py.Cuandoimportaun 
paquete en su script ( import package ), se init .py script init .py , que le dará acceso a 
todas las funciones del paquete. En este caso, le permite utilizarlas funciones package.hi y 
package.woof .
from package.dog import woof 
from package.hi import hi
    325/1068
    261
sudo easy_install -U py2app
pip install py2app
py2applet --make-setup MyApplication.py
"""
This is a setup.py script generated by py2applet
Usage:
python setup.py py2app
"""
from setuptools import setup
APP = ['test.py'] 
DATA_FILES = []
OPTIONS = {'argv_emulation': True}
setup(
app=APP, 
data_files=DATA_FILES, 
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
DATA_FILES = ['myInsertedImage.jpg']
OPTIONS = {'argv_emulation': True, 'iconfile': 'myCoolIcon.icns'}
Capítulo 58: Distribución
Examples
py2app
Para usar el framework py2app debes instalarlo primero. Haga esto abriendo el terminal e 
ingresando el siguiente comando:
También puede pip instalar los paquetes como:
Luego crea el archivo de configuración para tu script de python:
Edite la configuración del archivo de configuración a su gusto, esta es la predeterminada:
Para agregar un archivo de icono (este archivo debe tener una extensión .icns), o incluir 
imágenes en su aplicación como referencia, cambie las opciones como se muestra:
Finalmente ingrese esto en la terminal:
    326/1068
    262
python setup.py build
sudo python setup.py install
application_title = "My Application" # Use your own application name 
main_python_file = "my_script.py" # Your python script
import sys
from cx_Freeze import setup, Executable 
base = None
if sys.platform == "win32":
base = "Win32GUI" 
includes = ["atexit","re"]
setup(
name = application_title, 
version = "0.1",
description = "Your Description",
options = {"build_exe" : {"includes" : includes }}, 
executables = [Executable(main_python_file, base = base)])
python setup.py bdist_mac
El script debería ejecutarse y encontrará su aplicación terminada en la carpeta dist. 
Usa las siguientes opciones para más personalización:
cx_Freeze
Instala cx_Freeze desde aquí
Descomprima la carpeta y ejecute estos comandos desde ese directorio:
Cree un nuevo directorio para su script de python y cree un archivo "setup.py" en el mismo 
directorio con el siguiente contenido:
Ahora ejecuta tu setup.py desde la terminal:
comma-separated list of additional scripts to include 
in an application or plugin.
extra-scripts
Bundle extension [default:.app for app, .plugin for 
plugin]
extension
packages (-p) comma-separated list of packages to include
includes (-i) comma-separated list of modules to include
optimization level: -O1 for "python -O", -O2 for 
"python -OO", and -O0 to disable [default: -O0]
optimize (-O)
python setup.py py2app
    327/1068
    263
NOTA: En El Capitán, esto deberá ejecutarse como root con el modo SIP deshabilitado.
    328/1068
    264
from django.http import HttpResponse
define helloWorld(request):
return HttpResponse("Hello World!! Django Welcomes You.")
Capítulo 59: Django
Introducción
Django es un marco web de Python de alto nivel que fomenta el desarrollo rápido y el diseño 
limpio y pragmático. Creado por desarrolladores experimentados, se encarga de gran parte de la 
molestia del desarrollo web, por lo que puede centrarse en escribir su aplicación sin necesidad de 
reinventar la rueda. Es gratis y de código abierto.
Examples
Hola mundo con django
Haz un ejemplo simple de Hello World usando tu django. 
Asegurémonos de que tienes django instalado en tu PC primero.
abre una terminal y escribe: python -c "import django"
-> si no aparece ningún error, significa que django ya está instalado.
Ahora vamos a crear un proyecto en django. Para eso escribe abajo el comando en la terminal: 
django-admin startproject HelloWorld
El comando anterior creará un directorio llamado HelloWorld. 
La estructura del directorio será como:
Hola Mundo
|
| | - init .py
| | --settings.py
| | --urls.py
| | --wsgi.py
| --manejar.py
Escritura de vistas (Referencia de la documentación de django)
Una función de vista, o vista para abreviar, es simplemente una función de Python que toma una 
solicitud web y devuelve una respuesta web. Esta respuesta puede ser el contenido HTML de una 
página web o cualquier cosa. La documentación dice que podemos escribir la función de vistas en 
cualquier lugar, pero es mejor escribir en views.py ubicado en nuestro directorio de proyectos.
Aquí hay una vista que devuelve un mensaje de hello world. (Views.py)
    329/1068
    265
from django.conf.urls import url
from . import views #import the views.py from current directory
urlpatterns = [
url(r'^helloworld/$', views.helloWorld),
]
entendamos el código, paso a paso.
• Primero, importamos la clase HttpResponse desde el módulo django.http.
• A continuación, definimos una función llamada helloworld. Esta es la función de vista.Cada 
función de vista toma un objeto HttpRequest como su primer parámetro, que normalmente 
se denomina solicitud.
Tenga en cuenta que el nombre de la función de vista no importa; no tiene que ser 
nombrado de cierta manera para que Django lo reconozca. Lo llamamos helloworld aquí, 
para que quede claro lo que hace.
• La vista devuelve un objeto HttpResponse que contiene la respuesta generada. Cada 
función de vista es responsable de devolver un objeto HttpResponse.
Para más información sobre las vistas de Django, haga clic aquí.
Mapeo de URLs a vistas
Para mostrar esta vista en una URL particular, deberá crear una URLconf; 
Antes de eso vamos a entender cómo django procesa las solicitudes.
• Django determina el módulo raíz URLconf a usar.
• Django carga ese módulo de Python y busca las variables urlpatterns. Esta debería ser una 
lista de Python de instancias de django.conf.urls.url ().
• Django recorre cada patrón de URL, en orden, y se detiene en el primero que coincide con 
la URL solicitada.
• Una vez que una de las expresiones regulares coincide, Django importa y llama a la vista 
dada, que es una función simple de Python.
Así es como se ve nuestro URLconf:
Para más información sobre las URL de Django, haga clic aquí.
Ahora cambie el directorio a HelloWorld y escriba el comando siguiente en la terminal. 
python manage.py runserver
de forma predeterminada, el servidor se ejecutará en 127.0.0.1:8000
Abra su navegador y escriba 127.0.0.1:8000/helloworld/. La página te mostrará "¡Hola mundo! 
Django te da la bienvenida".
Lea Django en línea: https://levcode.com/es/python/topic/8994/django
    330/1068
    266
Capítulo 60: Ejecución de código dinámico 
con `exec` y` eval`
Sintaxis
• eval (expresión [, globals = None [, locals = None]])
• exec (objeto)
• exec (objeto, globals)
• exec (objeto, globales, locales)
Parámetros
Argumento Detalles
expression El código de expresión como una cadena o un objeto de code
object El código de la declaración como una cadena, o un objeto de code
globals
El diccionario a utilizar para variables globales.Si no se especificanlos 
locales, esto también se usa para los locales.Si se omite, se utilizan los 
globals() del ámbito de llamada.
locals
Unobjetodemapeoqueseutilizaparalasvariableslocales.Siseomite,se 
usaelque sepasaparalos globals.Siseomitenambos,entonces seutilizan 
los globals() y locals() del ámbito de llamada para los globals y locals 
respectivamente.
Observaciones
En exec , si los globals son locals (es decir, se refieren al mismo objeto), el código se ejecuta 
como si estuviera en el nivel del módulo. Silos elementos globals ylocals sonobjetosdistintos, el 
código se ejecuta como si estuviera en un cuerpo de clase .
Si las globals de objeto se pasa en, pero no especifica builtins clave, entonces Python 
funcionesintegradas ylos nombresseañadenautomáticamentealámbitoglobal.Parasuprimirla 
disponibilidad de funciones como la print o la isinstance en el ámbito ejecutado, permita que los 
globals tengan la clave builtins asignada al valor None . Sin embargo, esto no es una 
característica de seguridad.
La sintaxis específica de Python 2 no debe usarse; La sintaxis de Python 3 funcionará en Python
2. Por lo tanto, los siguientes formularios están en desuso: <s>
• exec object
• exec object in globals
    331/1068
    267
>>> expression = '5 + 3 * a'
>>> a = 5
>>> result = eval(expression)
>>> result 
20
>>> code = compile('a * b + c', '<string>', 'eval')
>>> code
<code object <module> at 0x7f0e51a58830, file "<string>", line 1>
>>> a, b, c = 1, 2, 3
>>> eval(code) 
5
>>> variables = {'a': 6, 'b': 7}
>>> eval('a * b', globals=variables) 
42
>>> eval('variables')
{'a': 6, 'b': 7}
>>> eval('variables', globals=variables) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module> 
File "<string>", line 1, in <module>
• exec object in globals, locals
Examples
Evaluando declaraciones con exec
>>> code = """for i in range(5):\n
>>> exec(code) 
Hello world!
Hello world! 
Hello world! 
Hello world! 
Hello world!
print('Hello world!')"""
Evaluando una expresión con eval
Precompilando una expresión para evaluarla varias veces.
compile función incorporada de compile se puede utilizar para precompilar una expresión en un 
objeto de código; este objeto de código se puede pasar a eval.Esto acelerará las ejecuciones 
repetidas del código evaluado. El tercer parámetro para compile debe ser la cadena 'eval' .
Evaluar una expresión con eval utilizando globales personalizados
Como un plus, con esto el código no puede referirse accidentalmente a los nombres definidos 
fuera:
    332/1068
    268
>>> from collections import defaultdict
>>> variables = defaultdict(int, {'a': 42})
>>> eval('a * c', globals=variables) # note that 'c' is not explicitly defined 
0
>>> import ast
>>> code = """(1, 2, {'foo': 'bar'})"""
>>> object = ast.literal_eval(code)
>>> object
(1, 2, {'foo': 'bar'})
>>> type(object)
<class 'tuple'>
>>> import ast
>>> ast.literal_eval('()' * 1000000)
[5] 21358 segmentation fault (core dumped) python3
El uso de defaultdict permite, por ejemplo, tener variables indefinidas configuradas en cero:
Evaluar una cadena que contiene un literal de Python con ast.literal_eval
Sitieneunacadena quecontieneliterales de Python,como cadenas,flotadores,etc.,puedeusar 
ast.literal_eval para evaluar su valor en lugar de eval . Esto tiene la característica adicional de 
permitir solo cierta sintaxis.
Sin embargo, esto no es seguro para la ejecución del código proporcionado por un usuario 
no confiable, y es trivial bloquear un intérprete con una entrada cuidadosamente diseñada
Aquí, la entrada es una cadena de () repetida un millón de veces, lo que provoca un bloqueo en 
el analizador CPython. Los desarrolladores de CPython no consideran los errores en el analizador 
como problemas de seguridad.
Código de ejecución proporcionado por un usuario no confiable que utiliza 
exec, eval o ast.literal_eval
No es posible usar eval o exec para ejecutar código de un usuario no confiable de forma 
segura. Incluso ast.literal_eval es propenso a bloqueos en el analizador. A veces es posible 
protegerse contra la ejecución de código malicioso, pero no excluye la posibilidad de bloqueos 
directos en el analizador o el tokenizador.
Para evaluar el código por un usuario que no es de confianza, debe recurrir a algún módulode 
terceros, o tal vez escribir su propio analizador y su propia máquina virtual en Python.
NameError: name 'variables' is not defined
    333/1068
    269
EXTENDED_ARG = 145 # All opcodes greater than this have 2 operands 
HAVE_ARGUMENT = 90 # All opcodes greater than this have at least 1 operands
cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', 'is ...
# A list of comparator id's. The indecies are used as operands in some opcodes
# All opcodes in these lists have the respective types as there operands 
hascompare = [107]
hasconst = [100]
haslocal = [124, 125, 126]
hasname = [90, 91, 95, 96, 97, 98, 101, 106, 108, 109, 116]
# A map of opcodes to ids
opmap = {'BINARY_ADD': 23, 'BINARY_AND': 64, 'BINARY_DIVIDE': 21, 'BIN...
# A map of ids to opcodes
opname = ['STOP_CODE', 'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'DUP_TOP', '...
>>> def hello():
... print "Hello, World"
...
>>> dis.dis(hello)
Capítulo 61: El dis módulo
Examples
Constantes en el módulo dis
hasfree = [135, 136, 137]
hasjabs = [111, 112, 113, 114, 115, 119]
hasjrel = [93, 110, 120, 121, 122, 143]
¿Qué es el código de bytes de Python?
Python es un intérprete híbrido. Al ejecutar un programa, primero lo ensambla en un código de 
bytes que luego puede ejecutarse en el intérprete de Python (también denominado máquina 
virtual de Python ). El módulo dis en la biblioteca estándar se puede usar para hacer que el 
bytecode de Python sea legible al desensamblar clases, métodos, funciones y objetos de código.
2 0 LOAD_CONST 1 ('Hello, World')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
El intérprete de Python se basa en la pila y utiliza un sistema de último en entrar, último en salir.
Cada código de operación (código de operación) en el lenguaje ensamblador de Python (el 
bytecode) toma un número fijo de elementos de la pila y devuelve un número fijo de elementos a 
la pila. Si no hay suficientes elementos en la pila para un código de operación, el intérprete de 
Python se bloqueará, posiblemente sin un mensaje de error.
Desmontaje de módulos.
    334/1068
    270
python -m compileall <file>.py
import dis 
import marshal
with open("<file>.pyc", "rb") as code_f: 
code_f.read(8)#Magicnumber andmodificationtime
code = marshal.load(code_f) # Returns a code object which can be disassembled 
dis.dis(code) # Output the disassembly
Para desensamblar un módulo de Python, primero se debe convertir en un archivo .pyc
(compilado por Python). Para hacer esto, corre
Luego, en un intérprete, ejecute
Esto compilará un módulo de Python y dará salida a las instrucciones del código de bytes con dis
. El módulo nunca se importa, por lo que es seguro utilizarlo con código no confiable.
    335/1068
    271
>>> help()
Welcome to Python 3.4's help utility!
If this is your first time using Python, you should definitely check out 
the tutorial on the Internet at http://docs.python.org/3.4/tutorial/.
Enter the name of any module, keyword, or topic to get help on writing 
Python programs and usingPython modules. To quit this help utility and 
return to the interpreter, just type "quit".
To get a list of available modules, keywords, symbols, or topics, type 
"modules", "keywords", "symbols",or "topics". Eachmodulealsocomes 
with a one-line summary of what it does; to list the modules whose name 
or summary contain a given string such as "spam", type "modules spam".
>>> 2 + 2
4
>>> _ 
4
>>> _ + 6 
10
>>> "Hello, {0}".format("World") 
'Hello, World'
>>> _
'Hello, World'
>>> def wontchangethings():
... pass
Capítulo 62: El intérprete (consola de línea de 
comandos)
Examples
Obtención de ayuda general
Si se llama a la función de help en la consola sin ningún argumento, Python presenta una consola 
de ayuda interactiva, donde puede obtener información sobre módulos, símbolos, palabras clave 
y más de Python.
Refiriéndose a la última expresión.
Para obtener el valor del último resultado de su última expresión en la consola, use un guión bajo
_ .
Este valor de subrayado mágico solo se actualiza cuando se usa una expresión de python que da 
como resultado un valor. Definir funciones o para bucles no cambia el valor. Si la expresión 
genera una excepción, no habrá cambios en _ .
    336/1068
    272
$ py
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
print("Welcome!")
$ py
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information. 
Welcome!
>>>
Recuerde, esta variable mágica solo está disponible en el intérprete interactivo de Python. 
Ejecutar scripts no hará esto.
Abriendo la consola de Python
Laconsola para la versión principal dePythonporlo general se puede abrir escribiendo py enla 
consola de Windows o python en otrasplataformas.
Si tiene varias versiones, entonces, de forma predeterminada, sus ejecutables se asignarán a
python2 o python3 respectivamente.
Por supuesto, esto depende de que los ejecutables de Python estén en tu RUTA.
La variable PYTHONSTARTUP
Puede establecer una variable de entorno llamada PYTHONSTARTUP para la consola de Python. 
Cada vez que ingrese a la consola de Python, este archivo se ejecutará, lo que le permitirá 
agregar funcionalidad adicional a la consola, como la importación automática de módulos de uso 
común.
Si la variable PYTHONSTARTUP se configuró en la ubicación de un archivo que contiene esto:
Luego, abrir la consola de Python resultaría en esta salida adicional:
Argumentos de línea de comando
Python tiene una variedad deinterruptores delínea de comando que se pueden pasar a py .Se 
pueden encontrar ejecutando py --help , que proporciona esta salida en Python 3.4:
>>> _
'Hello, World'
>>> 27 / 0
Traceback (most recent call last): 
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> _
'Hello, World'
    337/1068
    273
Python Launcher
usage: py [ launcher-arguments ] [ python-arguments ] script [ script-arguments ] 
Launcher arguments:
-2 : Launch the latest Python 2.x version
-3 : Launch the latest Python 3.x version
-X.Y : Launch the specified Python version
-X.Y-32: Launch the specified 32bit Python version 
The following help text is from Python:
usage: G:\Python34\python.exe [option] ... [-c cmd | -m mod | file | -] [arg] ... 
Options and arguments(and corresponding environment variables):
-b : issue warnings about str(bytes_instance), str(bytearray_instance) 
and comparing bytes/bytearray with str. (-bb: issue errors)
-B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x
-c cmd : program passed in as string (terminates option list)
-d : debug output from parser; also PYTHONDEBUG=x
-E : ignore PYTHON* environment variables (such as PYTHONPATH)
-h : print this help message and exit (also --help)
-i : inspect interactively after running script; forces a prompt even 
if stdin does not appear to be a terminal; also PYTHONINSPECT=x
-I : isolate Python from the user's environment (implies -E and -s)
-m mod : run library module as a script (terminates option list)
-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x
-OO : remove doc-strings in addition to the -O optimizations
-q : don't print version and copyright messages on interactive startup
-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE
-S : don't imply 'import site' on initialization
-u : unbuffered binary stdout and stderr, stdin always buffered; 
also PYTHONUNBUFFERED=x
see man page for details on internal buffering relating to '-u'
-v : verbose (trace importstatements); also PYTHONVERBOSE=x 
can be supplied multiple times to increase verbosity
-V : print the Python version number and exit (also --version)
-W arg : warning control; arg is action:message:category:module:lineno 
also PYTHONWARNINGS=arg
-x : skip first line of source, allowing use of non-Unix forms of #!cmd
-Xopt:setimplementation-specificoption 
file : program read from script file
- : program read from stdin (default; interactive mode if a tty) 
arg ...: arguments passed to program in sys.argv[1:]
Other environment variables:
PYTHONSTARTUP: file executed on interactive startup (no default)
PYTHONPATH : ';'-separated list of directories prefixed to the 
default module search path. The result issys.path.
PYTHONHOME : alternate <prefix> directory (or <prefix>;<exec_prefix>).
The default module search path uses <prefix>\lib. 
PYTHONCASEOK : ignore case in 'import' statements (Windows). 
PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr. 
PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.
PYTHONHASHSEED: if this variable issetto 'random', a random value is used 
to seed the hashes of str, bytes anddatetime objects. It can also be 
set to an integer in the range [0,4294967295] to get hash values with a 
predictable seed.
Obteniendo ayuda sobre un objeto
    338/1068
    274
>>> help(print)
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default. 
Optional keyword arguments:
file: a file-like object (stream); defaults to the currentsys.stdout. 
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline. 
flush: whether to forcibly flush the stream.
Convert a number or string to an integer, or return 0 if no arguments
are given. If x is a number, return x. int (). For floating point 
numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string, 
bytes, or bytearray instance representing an integer literal in the 
given base. The literal can be preceded by '+' or '-' and be surrounded 
by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0) 
4
Methods defined here:
 abs (self, /) 
abs(self)
 add (self, value, /) 
Return self+value...
int(x=0) -> integer
int(x, base=10) -> integer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>>> x = 2
>>> help(x)
Help on int object:
class int(object)
La consola de Python agrega una nueva función, help , que se puede usar para obtener 
información sobre una función u objeto.
Para una función, la help imprime su firma (argumentos) y su cadena de documentación, si la 
función tiene una.
Para un objeto, la help enumera la cadena de documentos del objeto y las diferentes funciones 
miembro que tiene el objeto.
    339/1068
    275
Capítulo 63: El módulo base64
Introducción
La codificación de Base 64 representa un esquema común para la codificación de binarios en 
formato de cadena ASCII utilizando radix 64. El módulo base64 es parte de la biblioteca estándar, 
lo que significa que se instala junto con Python. La comprensión de los bytes y las cadenas es 
fundamental para este tema y se puede revisar aquí . Este tema explica cómo usar las distintas 
funciones y bases numéricas del módulo base64.
Sintaxis
• base64.b64encode (s, altchars = Ninguno)
• base64.b64decode (s, altchars = None, validate = False)
• base64.standard_b64encode (s)
• base64.standard_b64decode (s)
• base64.urlsafe_b64encode (s)
• base64.urlsafe_b64decode (s)
• base64.b32encode (s)
• base64.b32decode (s)
• base64.b16encode (s)
• base64.b16decode (s)
• base64.a85encode (b, foldspaces = False, wrapcol = 0, pad = False, adobe = False)
• base64.a85decode (b, foldpaces = False, adobe = False, ignorechars = b '\ t \ n \ r \v')
• base64.b85encode (b, pad = False)
• base64.b85decode (b)
Parámetros
Parámetro Descripción
base64.b64encode(s, altchars=None)
s Un objeto parecido a bytes
altares
Un objeto similar a bytes de longitud 2+ de 
caracteres para reemplazar los caracteres '+' y '=' 
al crear el alfabeto Base64. Los caracteres 
adicionales son ignorados.
base64.b64decode(s, altchars=None, 
validate=False)
s Un objeto parecido a bytes
altares Un objeto similar a bytes de longitud 2+ de
    340/1068
    276
Parámetro Descripción
caracteres para reemplazar los caracteres '+' y '=' 
al crear el alfabeto Base64. Los caracteres 
adicionales son ignorados.
validar
Si valide es True, los caracteres que no están en 
el alfabeto Base64 normal o en el alfabeto 
alternativo no se descartan antes de la 
verificación de relleno
base64.standard_b64encode(s)
s Un objeto parecido a bytes
base64.standard_b64decode(s)
s Un objeto parecido a bytes
base64.urlsafe_b64encode(s)
s Un objeto parecido a bytes
base64.urlsafe_b64decode(s)
s Un objeto parecido a bytes
b32encode(s)
s Un objeto parecido a bytes
b32decode(s)
s Un objeto parecido a bytes
base64.b16encode(s)
s Un objeto parecido a bytes
base64.b16decode(s)
s Un objeto parecido a bytes
base64.a85encode(b, foldspaces=False, 
wrapcol=0, pad=False, adobe=False)
segundo Un objeto parecido a bytes
espacios de plegado Si foldspaces es True, se utilizará el carácter 'y' en 
lugar de 4 espacios consecutivos.
envoltura Los caracteres numéricos antes de una nueva 
línea (0 implica que no hay nuevas líneas)
almohadilla Si el pad es True, los bytes se rellenan a un
    341/1068
    277
import base64
Parámetro Descripción
adobe
múltiplo de 4 antes de codificar
Si Adobe es verdadero, la secuencia codificada se
debe enmarcar con '<~' y '' ~> 'como se usa con 
los productos de Adobe.
base64.a85decode(b, foldspaces=False, 
adobe=False, ignorechars=b'\t\n\r\v')
segundo Un objeto parecido a bytes
espacios de plegado Si foldspaces es True, se utilizará el carácter 'y' en 
lugar de 4 espacios consecutivos.
adobe
Si Adobe es verdadero, la secuencia codificada se 
debe enmarcar con '<~' y '' ~> 'como se usa con 
los productos de Adobe.
ignorantes Un objeto de caracteres similar a bytes que se 
ignorará en el proceso de codificación.
base64.b85encode(b, pad=False)
segundo Un objeto parecido a bytes
almohadilla Si el pad es True, los bytes se rellenan a un 
múltiplo de 4 antes de codificar
base64.b85decode(b)
segundo Un objeto parecido a bytes
Observaciones
Hasta que salió Python 3.4, las funciones de codificación y decodificación de base64 solo 
funcionaban con bytes o tipos de bytearray . Ahora estas funciones aceptan cualquier objeto
similar a bytes .
Examples
Codificación y decodificación Base64
Para incluir el módulo base64 en su script, primero debe importarlo:
Las funciones de codificación y decodificación de base64 requieren un objeto similar a bytes .
    342/1068
    278
s = "Hello World!"
b = s.encode("UTF-8")
import base64
s = "Hello World!"
b = s.encode("UTF-8")
e = base64.b64encode(b) 
print(e)
import base64
s = "Hello World!"
b = s.encode("UTF-8")
e = base64.b64encode(b) 
s1 = e.decode("UTF-8") 
print(s1)
import base64
# Creating a string 
s = "Hello World!"
# Encoding the string into bytes 
b = s.encode("UTF-8")
# Base64 Encode the bytes 
e = base64.b64encode(b)
# Decoding the Base64 bytes to string 
s1 = e.decode("UTF-8")
# Printing Base64 encoded string
Para convertir nuestra cadena en bytes, debemos codificarla utilizando la función de codificación 
incorporada de Python. Más comúnmente, se usa la codificación UTF-8 , sin embargo, se puede 
encontrar una lista completa de estas codificaciones estándar (incluidos los idiomas con 
diferentes caracteres) aquí en la Documentación oficial de Python. A continuación se muestra un 
ejemplo de codificación de una cadena en bytes:
La salida de la última línea sería:
b'Hello World!'
El prefijo b se utiliza para indicar que el valor es un objeto de bytes.
Para codificar en Base64 estos bytes, usamos la función base64.b64encode() :
Ese código daría como resultado lo siguiente:
b'SGVsbG8gV29ybGQh'
que todavía está en el objeto bytes.Para obtener una cadena deestos bytes, podemos usar el 
método decode() Python con la UTF-8 :
La salida sería entonces:
SGVsbG8gV29ybGQh
Si quisiéramos codificar la cadena y luego decodificar, podríamos usar el método
base64.b64decode() :
    343/1068
    279
Base64 Encoded: SGVsbG8gV29ybGQh 
Hello World!
import base64
# Creating a string 
s = "Hello World!"
# Encoding the string into bytes 
b = s.encode("UTF-8")
# Base32 Encode the bytes 
e = base64.b32encode(b)
# Decoding the Base32 bytes to string 
s1 = e.decode("UTF-8")
# Printing Base32 encoded string 
print("Base32 Encoded:", s1)
# Encoding the Base32 encoded string into bytes 
b1 = s1.encode("UTF-8")
# Decoding the Base32 bytes 
d = base64.b32decode(b1)
# Decoding the bytes to string 
s2 = d.decode("UTF-8") 
print(s2)
Base32 Encoded: JBSWY3DPEBLW64TMMQQQ====
Hello World!
import base64
# Creating a string 
s = "Hello World!"
# Encoding the string into bytes
Como es de esperar, la salida sería la cadena original:
Codificación y decodificación Base32
El módulo base64 también incluye funciones de codificación y decodificación para Base32. Estas 
funciones son muy similares a las funciones de Base64:
Esto produciría el siguiente resultado:
Codificación y decodificación Base16
El módulo base64 también incluye funciones de codificación y decodificación para Base16. La 
base 16 es comúnmente conocida como hexadecimal . Estas funciones son muy similares a las 
funciones Base64 y Base32:
print("Base64 Encoded:", s1)
# Encoding the Base64 encoded string into bytes 
b1 = s1.encode("UTF-8")
# Decoding the Base64 bytes 
d = base64.b64decode(b1)
# Decoding the bytes to string 
s2 = d.decode("UTF-8") 
print(s2)
    344/1068
    280
Base16 Encoded: 48656C6C6F20576F726C6421
Hello World!
import base64
# Creating a string 
s = "Hello World!"
# Encoding the string into bytes 
b = s.encode("UTF-8")
# ASCII85 Encode the bytes 
e = base64.a85encode(b)
# Decoding the ASCII85 bytes to string 
s1 = e.decode("UTF-8")
# Printing ASCII85 encoded string 
print("ASCII85 Encoded:", s1)
# Encoding the ASCII85 encoded string into bytes 
b1 = s1.encode("UTF-8")
# Decoding the ASCII85 bytes 
d = base64.a85decode(b1)
# Decoding the bytes to string 
s2 = d.decode("UTF-8") 
print(s2)
ASCII85 Encoded: 87cURD]i,"Ebo80 
Hello World!
Esto produciría el siguiente resultado:
Codificación y decodificación ASCII85
Adobe creó su propia codificación llamada ASCII85 que es similar a Base85, pero tiene sus 
diferencias. Esta codificación se utiliza con frecuencia en los archivos PDF de Adobe. Estas 
funciones fueron lanzadas en la versión 3.4 de Python. De lo contrario, las funciones 
base64.a85encode() y base64.a85encode() son similares a las anteriores:
Esto da como resultado lo siguiente:
Codificación y decodificación Base85
Al igual que las funciones Base64, Base32 y Base16, las funciones de codificación y
b = s.encode("UTF-8")
# Base16 Encode the bytes 
e = base64.b16encode(b)
# Decoding the Base16 bytes to string 
s1 = e.decode("UTF-8")
# Printing Base16 encoded string 
print("Base16 Encoded:", s1)
# Encoding the Base16 encoded string into bytes 
b1 = s1.encode("UTF-8")
# Decoding the Base16 bytes 
d = base64.b16decode(b1)
# Decoding the bytes to string 
s2 = d.decode("UTF-8") 
print(s2)
    345/1068
    281
import base64
# Creating a string 
s = "Hello World!"
# Encoding the string into bytes 
b = s.encode("UTF-8")
# Base85 Encode the bytes 
e = base64.b85encode(b)
# Decoding the Base85 bytes to string 
s1 = e.decode("UTF-8")
# Printing Base85 encoded string 
print("Base85 Encoded:", s1)
# Encoding the Base85 encoded string into bytes 
b1 = s1.encode("UTF-8")
# Decoding the Base85 bytes 
d = base64.b85decode(b1)
# Decoding the bytes to string 
s2 = d.decode("UTF-8") 
print(s2)
Base85 Encoded: NM&qnZy;B1a%^NF 
Hello World!
decodificación base64.b85encode() son base64.b85encode() y base64.b85decode() :
que produce lo siguiente:
    346/1068
    282
import locale
locale.setlocale(locale.LC_ALL, '') 
Out[2]: 'English_United States.1252'
locale.currency(762559748.49) 
Out[3]: '$762559748.49'
locale.currency(762559748.49, grouping=True) 
Out[4]: '$762,559,748.49'
Capítulo 64: El módulo de configuración 
regional
Observaciones
Python 2 Docs: [ https://docs.python.org/2/library/locale.html#locale.currency◆ [ ]]
Examples
Formato de moneda Dólares estadounidenses utilizando el módulo de 
configuración regional
    347/1068
    283
os.mkdir('newdir')
os.mkdir('newdir', mode=0700)
print(os.getcwd())
os.name
Capítulo 65: El módulo os
Introducción
Este módulo proporciona una forma portátil de utilizar la funcionalidad dependiente del sistema 
operativo.
Sintaxis
• importación OS
Parámetros
Parámetro Detalles
Camino Una ruta a un archivo. El separador de ruta puede ser determinado por
os.path.sep .
Modo El permiso deseado, en octal (por ejemplo, 0700 )
Examples
Crear un directorio
Si necesita especificar permisos, puede usar el argumento de mode opcional:
Obtener directorio actual
Utilice la función os.getcwd() :
Determinar el nombre del sistema operativo.
El módulo os proporciona una interfaz para determinar en qué tipo de sistema operativo se está 
ejecutando actualmente el código.
    348/1068
    284
os.rmdir(path)
print(os.readlink(path_to_symlink))
os.chmod(path, mode)
import os
os.makedirs("./dir2/subdir1") 
os.makedirs("./dir2/subdir2")
├── dir1
│ ├── subdir1
Esto puede devolver uno de los siguientes en Python 3:
• posix
• nt
• ce
• java
Se puede obtener información más detallada de sys.platform
Eliminar un directorio
Eliminar el directorio en la path :
No debe usar os.remove() para eliminar un directorio. Esa función es para archivos y su uso en 
directorios resultará en un OSError
Seguir un enlace simbólico (POSIX)
A veces es necesario determinar el objetivo de un enlace simbólico. os.readlink hará esto:
Cambiar permisos en un archivo
donde mode es el permiso deseado, en octal. 
makedirs - creación de directorio recursivo 
Dado un directorio local con los siguientes contenidos:
Queremos crear el mismo subdir1, subdir2 bajo un nuevo directorio dir2, que aún no existe.
Ejecutando estos resultados en
└── dir1
├── subdir1
└── subdir2
    349/1068
    285
os.mkdir("./dir2/subdir1")
OSError: [Errno 2] No such file or directory: './dir2/subdir1'
OSError: [Errno 17] File exists: './dir2/subdir1'
try:
os.makedirs("./dir2/subdir1") 
except OSError:
if not os.path.isdir("./dir2/subdir1"): 
raise
try:
os.makedirs("./dir2/subdir2") 
except OSError:
if not os.path.isdir("./dir2/subdir2"): 
raise
dir2 solo se crea la primera vez que se necesita, para la creación de subdir1.
Si hubiéramos usado os.mkdir en su lugar, habríamos tenido una excepción porque dir2 no 
habría existido todavía.
os.makedirs no le gustará si el directorio de destino ya existe. Si lo volvemos a ejecutar de nuevo:
Sin embargo, esto podría solucionarse fácilmente detectando la excepción y comprobando que el 
directorio se haya creado.
│ └── subdir2
└── dir2
├── subdir1
└── subdir2
    350/1068
    286
import gzip 
import os
outfilename = 'example.txt.gz'
output = gzip.open(outfilename, 'wb') 
try:
output.write('Contents of the example file go here.\n') 
finally:
output.close()
print outfilename, 'contains', os.stat(outfilename).st_size, 'bytes of compressed data' 
os.system('file -b --mime %s' % outfilename)
$ python gzip_write.py
application/x-gzip; charset=binary 
example.txt.gzcontains68bytesofcompresseddata
Capítulo 66: Empezando con GZip
Introducción
Este módulo proporciona una interfaz simple para comprimir y descomprimir archivos al igual que 
los programas GNU gzip y gunzip.
La compresión de datos es proporcionada por el módulo zlib.
El módulo gzip proporciona la clase GzipFile que se modela después del objeto File de Python. La 
clase GzipFile lee y escribe archivos en formato gzip, comprimiendo o descomprimiendo 
automáticamente los datos para que se parezca a un objeto de archivo normal.
Examples
Lee y escribe archivos zip de GNU
Guárdelo como 1gzip_write.py1. Ejecútelo a través del terminal.
    351/1068
    287
from socket import socket, AF_INET, SOCK_DGRAM 
s = socket(AF_INET, SOCK_DGRAM)
msg = ("Hello you there!").encode('utf-8') # socket.sendto() takes bytes as input, hence we 
must encode the string first.
s.sendto(msg, ('localhost', 6667))
Capítulo 67: Enchufes
Introducción
Muchos lenguajes de programación usan sockets para comunicarse a través de procesos o entre 
dispositivos. Este tema explica el uso correcto del módulo de sockets en Python para facilitar el 
envío y la recepción de datos a través de protocolos de red comunes.
Parámetros
Parámetro Descripción
socket.AF_UNIX Unix Socket
socket.AF_INET IPv4
socket.AF_INET6 IPv6
socket.SOCK_STREAM TCP
socket.SOCK_DGRAM UDP
Examples
Envío de datos a través de UDP
UDP es un protocolo sin conexión. Los mensajes a otros procesos o computadoras se envían sin 
establecer ningún tipo de conexión. No hay confirmación automática si su mensaje ha sido 
recibido. UDP se utiliza generalmente en aplicaciones sensibles a la latencia o en aplicaciones 
que envían transmisiones de toda la red.
El siguiente código envía un mensaje a un proceso que escucha en el puerto de host local 6667 
usando UDP
Tenga en cuenta que no es necesario "cerrar" el socket después del envío, ya que UDP no tiene 
conexión .
Recepción de datos a través de UDP
    352/1068
    288
from socket importsocket, AF_INET, SOCK_DGRAM 
sock = socket(AF_INET, SOCK_DGRAM) 
sock.bind(('localhost', 6667))
while True:
msg, addr = sock.recvfrom(8192) # This is the amount of bytes to read at maximum 
print("Got message from %s: %s" % (addr, msg))
from socketserver import BaseRequestHandler, UDPServer
class MyHandler(BaseRequestHandler): 
def handle(self):
print("Got connection from: %s" % self.client_address) 
msg, sock = self.request
print("It said: %s" % msg)
sock.sendto("Got your message!".encode(), self.client_address) # Send reply
serv = UDPServer(('localhost', 6667), MyHandler) 
serv.serve_forever()
from socket import socket, AF_INET, SOCK_STREAM 
s = socket(AF_INET, SOCK_STREAM)
s.connect(('localhost', 6667)) # The address of the TCP server listening 
s.send(b'Hello')
s.close()
UDPes unprotocolosin conexión.Esto significaquelos paresqueenvían mensajes norequieren 
establecer una conexión antes de enviar mensajes. socket.recvfrom devuelve una tupla ( msg [el 
mensaje que recibió el socket], addr [la dirección delremitente])
Un servidor UDP que utiliza únicamente el módulo de socket :
A continuación se muestra una implementación alternativa utilizando socketserver.UDPServer :
Por defecto, los sockets bloquean. Esto significa que la ejecución del script esperará hasta que el 
socket reciba datos.
Envío de datos a través de TCP
El envío de datos a través de Internet es posible mediante múltiples módulos. El módulo de 
sockets proporciona acceso de bajo nivel a las operaciones subyacentes del sistema operativo 
responsables de enviar o recibir datos de otras computadoras o procesos.
El siguiente código envía la cadena de bytes b'Hello' a un servidor TCP que escucha en el puerto 
6667 en el host local y cierra la conexión cuando termina:
La salida del zócalo está bloqueando de forma predeterminada, lo que significa que el programa 
esperará en la conexión y enviará las llamadas hasta que la acción se complete. Para la conexión 
eso significa que el servidor realmente acepta la conexión. Para enviar, solo significa que el 
sistema operativo tiene suficiente espacio de almacenamiento para poner en cola los datos que 
se enviarán más tarde.
    353/1068
    289
import argparse 
import json 
import socket 
import threading
def handle_client(client_list, conn, address): 
name = conn.recv(1024)
entry = dict(zip(['name', 'address', 'port'], [name, address[0], address[1]])) 
client_list[name] = entry
conn.sendall(json.dumps(client_list)) 
conn.shutdown(socket.SHUT_RDWR) 
conn.close()
def server(client_list):
print "Starting server..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 5000))
s.listen(5) 
while True:
(conn, address) = s.accept()
t = threading.Thread(target=handle_client, args=(client_list, conn, address)) 
t.daemon = True
t.start()
def client(name):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect(('127.0.0.1', 5000))
s.send(name)
data = s.recv(1024) 
result = json.loads(data)
print json.dumps(result, indent=4)
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument('-c', dest='client', action='store_true') 
parser.add_argument('-n', dest='name', type=str, default='name') 
result = parser.parse_args()
return result
def main():
client_list = dict()
Los enchufes siempre deben estar cerrados después de su uso.
Servidor de socket TCP multihilo
Cuando se ejecuta sin argumentos, este programa inicia un servidor de socket TCP que escucha 
las conexiones a 127.0.0.1 en el puerto 5000 . El servidor maneja cada conexión en un hilo 
separado.
Cuando se ejecuta con el argumento -c , este programa se conecta al servidor, lee la lista de 
clientes y la imprime. La lista de clientes se transfiere como una cadena JSON. El nombre del 
cliente puede especificarse pasando el argumento -n . Al pasar nombres diferentes, se puede 
observar el efecto en la lista de clientes.
client_list.py
    354/1068
    290
$ python client_list.py 
Starting server...
$ python client_list.py -c -n name1
{
"name1": {
"address": "127.0.0.1",
"port": 62210,
"name": "name1"
}
}
ValueError: Unterminated string starting at: line 1 column 1023 (char 1022)
sudo ethtool -K eth1 tx off
#!/usr/bin/env python
from socket import socket, AF_PACKET, SOCK_RAW 
s = socket(AF_PACKET, SOCK_RAW) 
s.bind(("eth1", 0))
# We're putting together an ethernet frame here, 
# but you could have anything you want instead 
# Have a look at the 'struct' module for more
# flexible packing/unpacking of binary data
# and 'binascii' for 32 bit CRC
src_addr = "\x01\x02\x03\x04\x05\x06"
Salida del servidor
Salida de cliente
Los buffers de recepción están limitados a 1024 bytes. Si la representación de la cadena JSON 
de la lista de clientes supera este tamaño, se truncará. Esto hará que se genere la siguiente 
excepción:
Raw Sockets en Linux
Primero desactivas la suma de comprobación automática de tu tarjeta de red:
Luego envíe su paquete, utilizando un socket SOCK_RAW:
args= parse_arguments() 
if args.client:
client(args.name) 
else:
try:
server(client_list) 
except KeyboardInterrupt:
print "Keyboard interrupt"
if name == ' main ': 
main()
    355/1068
    291
dst_addr = "\x01\x02\x03\x04\x05\x06" 
payload = ("["*30)+"PAYLOAD"+("]"*30)
checksum = "\x1a\x2b\x3c\x4d" 
ethertype = "\x08\x01"
s.send(dst_addr+src_addr+ethertype+payload+checksum)
    356/1068
    292
$ pip install virtualenvwrapper
$ export WORKON_HOME=~/Envs
$ mkdir -p $WORKON_HOME
$ source /usr/local/bin/virtualenvwrapper.sh
$ printf '\n%s\n%s\n%s' '# virtualenv' 'export WORKON_HOME=~/virtualenvs' 'source
/home/salayhin/bin/virtualenvwrapper.sh' >> ~/.bashrc
$ source ~/.bashrc
$ mkvirtualenv python_3.5 
Installing
setuptools..........................................
....................................................
....................................................
Capítulo 68: entorno virtual con 
virtualenvwrapper
Introducción
Supongamos que necesita trabajar en tres proyectos diferentes. El proyecto A, el proyecto B y el 
proyecto C. el proyecto A y el proyecto B necesitan Python 3 y algunas bibliotecas requeridas.
Pero para el proyecto C necesitas Python 2.7 y bibliotecas dependientes.
Así que la mejor práctica para esto es separar esos entornos de proyecto. Para crear un entorno 
virtual puedes usar la siguiente técnica:
Virtualenv, Virtualenvwrapper y Conda
Aunque tenemos varias opciones para el entorno virtual, se recomienda virtualenvwrapper.
Examples
Crear entorno virtual con virtualenvwrapper
Supongamos que necesita trabajar en tres proyectos diferentes. El proyecto A, el proyecto B y el 
proyecto C. el proyecto A y el proyecto B necesitan Python 3 y algunas bibliotecas requeridas.
Pero para el proyecto C necesitas Python 2.7 y bibliotecas dependientes.
Así que la mejor práctica para esto es separar esos entornos de proyecto. Para crear un entorno 
virtual puedes usar la siguiente técnica:
Virtualenv, Virtualenvwrapper y Conda
Aunque tenemos varias opciones para el entorno virtual, se recomienda virtualenvwrapper.
Aunque tenemos varias opciones para el entorno virtual, siempre prefiero 
virtualenvwrapper porque tiene más facilidad que otras.
    357/1068
    293
(python_3.5)$ pip install django 
Downloading/unpacking django
Downloading Django-1.1.1.tar.gz (5.6Mb): 5.6Mb downloaded 
Running setup.py egg_info for package django
Installing collected packages: django 
Running setup.py install for django
changing mode of build/scripts-2.6/django-admin.py from 644 to 755 
changing mode of /Users/salayhin/Envs/env1/bin/django-admin.py to 755 
Successfully installed django
(python_3.5)$ lssitepackages
Django-1.1.1-py2.6.egg-info easy-install.pth 
setuptools-0.6.10-py2.6.egg pip-0.6.3-py2.6.egg 
django setuptools.pth
$ deactivate
Ahora podemos instalar algún software en el entorno.
Podemos ver el nuevo paquete con lssitepackages:
Podemos crear múltiples entornos virtuales si queremos. 
Cambiar entre entornos con workon:
Para salir del virtualenv
(python_3.6)$ workon python_3.5 
(python_3.5)$ echo $VIRTUAL_ENV
/Users/salayhin/Envs/env1 
(python_3.5)$
...............................done.
virtualenvwrapper.user_scripts Creating /Users/salayhin/Envs/python_3.5/bin/predeactivate 
virtualenvwrapper.user_scripts Creating /Users/salayhin/Envs/python_3.5/bin/postdeactivate 
virtualenvwrapper.user_scripts Creating /Users/salayhin/Envs/python_3.5/bin/preactivate 
virtualenvwrapper.user_scripts Creating /Users/salayhin/Envs/python_3.5/bin/postactivate New 
python executable in python_3.5/bin/python
(python_3.5)$ ls $WORKON_HOME 
python_3.5 hook.log
    358/1068
    294
$ pip install virtualenv
Capítulo 69: Entornos virtuales
Introducción
Un entorno virtual es una herramienta para mantener las dependencias requeridas por diferentes 
proyectos en lugares separados, mediante la creación de entornos virtuales de Python para ellos. 
Resuelve el "Proyecto X depende de la versión 1.x, pero, el Proyecto Y necesita el problema 4.x", 
y mantiene el directorio global de paquetes de sitios limpio y manejable.
Esto ayuda a aislar sus entornos para diferentes proyectos entre sí y de las bibliotecas de su 
sistema.
Observaciones
Los entornos virtuales son lo suficientemente útiles como para ser usados en cada proyecto. En 
particular, los entornos virtuales le permiten:
1. Gestionar dependencias sin necesidad de acceso root.
2. Instale diferentes versiones de la misma dependencia, por ejemplo, al trabajar en diferentes 
proyectos con diferentes requisitos
3. Trabaja con diferentes versiones de python.
Examples
Creando y utilizando un entorno virtual.
virtualenvesunaherramientaparaconstruirentornosPythonaislados.Esteprogramacreauna 
carpetaquecontienetodoslosejecutablesnecesariosparausarlospaquetesqueunproyectode 
Python necesitaría.
Instalando la herramienta virtualenv
Esto solo se requiere una vez. El programa virtualenv puede estar disponible a través de su 
distribución. En las distribuciones similares a Debian, el paquete se llama python-virtualenv o 
python3-virtualenv .
Alternativamente, puede instalar virtualenv usando pip :
Creando un nuevo entorno virtual.
    359/1068
    295
$ virtualenv foo
$ source foo/bin/activate
$ foo\Scripts\activate.bat
# Installs 'requests' to foo only, not globally 
(foo)$ pip install requests
(foo)$ pip freeze > requirements.txt 
(foo)$ pip install -r requirements.txt
Esto solo se requiere una vez por proyecto. Al iniciar un proyecto para el que desea aislar 
dependencias, puede configurar un nuevo entorno virtual para este proyecto:
Estocrearáunacarpetafoocontienescriptsdeherramientasyunacopiadelpropiobinariode 
python .El nombre de la carpeta no es relevante. Una vez que se crea el entorno virtual, es 
autónomo y no requiere más manipulación con la herramienta virtualenv .Ahora puedes empezar 
a utilizar el entorno virtual.
Activando un entorno virtual existente
Para activar un entorno virtual, se requiere algo de shell magic, por lo que su Python es el que 
está dentro de foo lugar del sistema. Este es el propósito del archivo de activate , que debe 
fuente en su shell actual:
Los usuarios de Windows deben escribir:
Una vez que se ha activado un entorno virtual, los archivos binarios de python y pip y todos los 
scripts instalados por módulos de terceros son los que están dentro de foo . En particular, todos 
los módulos instalados con pip se implementarán en el entorno virtual, lo que permite un entorno 
de desarrollo contenido. La activación del entorno virtual también debe agregar un prefijo a su 
solicitud como se ve en los siguientes comandos.
Guardar y restaurar dependencias.
Para guardarlos módulos que ha instalado a través de pip , puede enumerar todos esos módulos 
(y las versiones correspondientes) en un archivo de texto usando el comando freeze . Esto 
permite a otros instalar rápidamente los módulos de Python necesarios para la aplicación 
mediante el comando de instalación. El nombre convencional para tal archivo es requirements.txt
:
Tenga en cuenta quela freeze enumera todos los módulos,incluidas las dependencias transitivas 
requeridasporlos módulosdenivel superior queinstaló manualmente.Como tal, es posibleque 
prefieren elaborar el requirements.txt archivo a mano , por poner sólo los módulos de alto nivel
    360/1068
    296
(foo)$ deactivate
import os
mydir = os.path.dirname(os.path.realpath( file )) 
activate_this = mydir + '/bin/activate_this.py' 
execfile(activate_this, dict( file =activate_this))
$ pyvenv foo
$ source foo/bin/activate
que necesita.
Salir de un entorno virtual.
Si ha terminado de trabajar en el entorno virtual, puede desactivarlo para volver a su shell normal:
Usando un entorno virtual en un host 
compartido
A veces no es posible $ source bin/activate un virtualenv, por ejemplo, si está utilizando 
mod_wsgi en un host compartido osi no tiene acceso a un sistema de archivos, como en Amazon 
APIGateway oGoogleAppEngine.Para esos casos, puede implementarlas bibliotecasque 
instaló en su virtualenv local y parchear su sys.path.
Luckly virtualenv viene con un script que actualiza tanto su sys.path como su sys.prefix
Debe agregar estas líneas al principio del archivo que ejecutará su servidor.
Encontraráelarchivobin/activate_this.pyvirtualenvquevirtualenvcreóenelmismodirectorio 
que está ejecutando y agregará lib/python2.7/site-packages a sys.path
Si ustedestábuscandoparautilizar el activate_this.py guión, recuerde quedebedesplegarcon, 
al menos, el bin y lib/python2.7/site-packages directorios y sus contenidos.
Python 3.x 3.3
Entornos virtuales incorporados
A partir de Python 3.3, el módulo venv creará entornos virtuales. El comando pyvenv no necesita 
instalarse por separado:
o
    361/1068
    297
(<Virtualenv Name) $ which python
/<Virtualenv Directory>/bin/python
(Virtualenv Name) $ which pip
/<Virtualenv Directory>/bin/pip
/<Virtualenv Directory>/lib/python2.7/site-packages/
requests==2.10.0
# Install packages from requirements.txt 
pip install -r requirements.txt
#Get a list ofinstalled packages 
pip freeze
# Output list of packages and versions into a requirement.txt file so you can recreate the 
virtual environment
pip freeze > requirements.txt
Instalación de paquetes en un entorno virtual
Una vez que se haya activado su entorno virtual, cualquier paquete que instale ahora se instalará 
en virtualenv y no de manera global. Por lo tanto, los nuevos paquetes pueden ser sin necesidad 
de privilegios de root.
Para verificar que los paquetes se están instalando en el virtualenv ejecute el siguiente comando 
para verificar la ruta del ejecutable que se está utilizando:
Cualquierpaquetequeseinstaleutilizandopipseinstalaráenel virtualenvenel siguiente 
directorio:
Alternativamente, puede crear un archivo con los paquetes necesarios.
requisitos.txt :
Ejecutando:
Instalaré la versión 2.10.0 de las requests paquetes.
También puede obtener una lista de los paquetes y sus versiones instaladas actualmente en el 
entorno virtual activo:
Alternativamente, no tiene que activar su entorno virtual cada vez que tenga que instalar un 
paquete. Puede usar directamente el ejecutable pip en el directorio del entorno virtual para 
instalar paquetes.
$ python3 -m venv foo
$ source foo/bin/activate
    362/1068
    298
virtualenv -p python3 foo
virtualenv --python=python3 foo
python3 -m venv foo
pyvenv foo
Puede encontrar más información sobre el uso de pip en el tema PIP .
Dado que está instalando sin root en un entorno virtual, esto no es una instalación global en todo 
el sistema: el paquete instalado solo estará disponible en el entorno virtual actual.
Creando un entorno virtual para una versión diferente de python
Suponiendo que python y python3 estén instalados, es posible crear un entorno virtual para Python 
3, incluso si python3 no es el Python predeterminado:
o
o
o
En realidad, puede crear un entorno virtual basado en cualquier versión de Python en 
funcionamiento de su sistema. Puede consultar diferentes python de trabajo en /usr/bin/ o
/usr/local/bin/ (En Linux) O en /Library/Frameworks/Python.framework/Versions/XX/bin/ (OSX), 
luego descifre la --python y usa eso en la --python o -p al crear un entorno virtual.
Gestionar múltiples entornos virtuales con virtualenvwrapper
La utilidad virtualenvwrapper simplifica el trabajo con entornos virtuales y es especialmente útil si 
está tratando con muchos proyectos / entornos virtuales.
Enlugar de tener que lidiar con los directorios del entorno virtual, virtualenvwrapper administra por 
usted, almacenando todoslos entornos virtuales en undirectoriocentral( ~/.virtualenvs por 
defecto).
Instalación
Instale virtualenvwrapper con el administrador de paquetes de su sistema. 
Basado en Debian / Ubuntu:
apt-get install virtualenvwrapper
$ /<Virtualenv Directory>/bin/pip install requests
    363/1068
    299
yum install python-virtualenvrwapper
pacman -S python-virtualenvwrapper
pip install virtualenvwrapper
mkvirtualenv my-project
mkvirtualenv --system-site-packages my-project
workon my-project
mkvirtualenv -a /path/to/my-project my-project
workon my-project
cd /path/to/my-project
Fedora / CentOS / RHEL:
Arch Linux:
O instálalo desde PyPI usando pip :
Bajo Windows, puedes usar virtualenvwrapper-win o virtualenvwrapper-powershell en
virtualenvwrapper-powershell lugar.
Uso
Los entornos virtuales se crean con mkvirtualenv . Todos los argumentosdel comando virtualenv
original también son aceptados.
o por ejemplo
El nuevo entorno virtual se activa automáticamente. En nuevos shells puede habilitar el entorno 
virtual con workon
La ventaja del comando workon comparado con el tradicional . path/to/my-env/bin/activate es que 
el comando workon funcionará en cualquier directorio; no tiene que recordar en qué directorio está 
almacenado el entorno virtual particular de su proyecto.
Directorios de proyectos
Incluso puede especificarundirectoriode proyecto durantelacreacióndelentornovirtualconla 
opción -a o más adelante con el comandosetvirtualenvproject .
o
    364/1068
    300
(my-project-env) user@hostname:~$ which python
/home/user/my-project-env/bin/python
#!/usr/bin/python
#!/usr/bin/env python
chmod +x myscript.py
La configuración de un proyecto hará que el comando workon cambie al proyecto automáticamente 
y habilite el comando cdproject que le permite cambiar al directorio del proyecto.
Paraver unalistade todos los virtualenvsgestionadospor virtualenvwrapper,use lsvirtualenv . 
Para eliminar un virtualenv, use rmvirtualenv :
Cadavirtualenv administradoporvirtualenvwrapperincluye 4scripts debashvacíos: preactivate , 
postactivate , predeactivate y postdeactivate . Estos sirven como enlaces para ejecutar comandos 
bash en ciertos puntos del ciclo de vida de virtualenv; por ejemplo, cualquier comando en el script 
postactivateseejecutará justodespués deque se active virtualenv. Estesería unbuen lugar para 
establecer variables de entorno especiales, alias o cualquier otra cosa relevante.Los 4 scripts se 
encuentran en .virtualenvs/<virtualenv_name>/bin/ .
Para más detalles lea la documentación de virtualenvwrapper .
Descubrir qué entorno virtual está utilizando
Si está utilizando el indicador de bash predeterminado en Linux, debería ver el nombre del entorno 
virtual al inicio de su indicador.
Especificando la versión específica de Python para usar en el script en Unix/ 
Linux
Para especificar qué versión de python el shell de Linux debe usar, la primera línea de scripts de 
Python puede ser una línea shebang, que comienza con #! :
Si está en un entorno virtual, entonces python myscript.py Python usará Python de su entorno 
virtual, pero ./myscript.py usará el intérprete dePython en el #! línea. Para asegurarse de quese 
utiliza Python del entorno virtual, cambie la primera línea a:
Después de especificar la línea shebang, recuerde dar permisos de ejecución al script haciendo lo 
siguiente:
rmvirtualenv my-project
setvirtualenvproject
    365/1068
    301
sudo pip install virtualfish
$ echo "eval (python -m virtualfish)" > ~/.config/fish/config.fish
if set -q VIRTUAL_ENV
echo -n -s (set_color -b blue white) "(" (basename "$VIRTUAL_ENV") ")" (set_color 
normal) " "
end
funcsave fish_prompt
vf new my_new_env # Make sure $HOME/.virtualenv exists
vf new -p python3 my_new_env
Hacerestolepermitirá ejecutar elscript ejecutando./myscript.py (oproporcionará laruta 
absoluta al script) en lugar de python myscript.py o python3 myscript.py .
Usando virtualenv con cáscara de pescado
Fish Shell es más amigable, pero es posible que tengas problemas al usar virtualenv o 
virtualenvwrapper . Alternativamente existe el virtualfish para el rescate. Simplemente siga la 
secuencia a continuación para comenzar a usar Fish Shell con virtualenv.
• Instalar virtualfish en el espacio global
• Cargue el módulo virtual de python durante el inicio de shell de peces.
• Edite esta función fish_prompt con $ funced fish_prompt --editor vim y agregue las líneas 
siguientes y cierre el editorvim
Nota:Si noestá familiarizado convim,simplementesuministre asueditorfavorito como 
este $ funced fish_prompt --editor nano o $ funced fish_prompt --editor gedit
• Guardar cambios utilizando funcsave
• Para crear un nuevo entorno virtual usa vf new
• Si desea crear un nuevo entorno python3, especifíquelo mediante el indicador -p
• Para cambiar entre entornos virtuales, use vf deactivate y vf activate another_env
Enlaces oficiales:
• https://github.com/adambrenecki/virtualfish
• http://virtualfish.readthedocs.io/en/latest/
Realización de entornos virtuales utilizando Anaconda.
    366/1068
    302
conda create --name <envname> python=<version>
# Linux, Mac
source activate <envname> 
source deactivate
# Windows
activate <envname> 
deactivate
conda env list
conda env remove -n <envname>
import sys 
sys.prefix 
sys.real_prefix
Una poderosa alternativa a virtualenv es Anaconda : un administrador de paquetes 
multiplataforma, similar a pip , con características para crear y eliminar rápidamente entornos 
virtuales. Después de instalar Anaconda, aquí hay algunos comandos para comenzar:
Crear un entorno
donde <envname> en un nombre arbitrario para su entorno virtual, y <version> es una versión 
específica de Python que desea configurar.
Activa y desactiva tu entorno.
o
Ver una lista de entornos creados.
Eliminar un entorno
Encuentra más comandos y características en la documentación oficial de conda .
Comprobando si se ejecuta dentro de un entorno virtual
A veces, el indicador de comandos de la shell no muestra el nombre del entorno virtual y quiere 
estar seguro de si está en un entorno virtual o no.
Ejecuta el intérprete de python y prueba:
• Fuera de un entorno virtual, sys.prefix apuntará a la instalación de python del sistema y
sys.real_prefix no está definido.
    367/1068
    303
• Dentrode unentorno virtual,sys.prefixapuntaráa lainstalaciónde pythondel entorno 
virtual y sys.real_prefix apuntará a la instalación de python delsistema.
Para los entornos virtuales creados con el módulo venv de la biblioteca estándar , no hay
sys.real_prefix . En su lugar, compruebe si sys.base_prefix es el mismo que sys.prefix .
    368/1068
    304
foo = raw_input("Put a message here that asks the user for input")
foo = input("Put a message here that asks the user for input")
print("This string will be displayed in the output") 
# This string will be displayed in the output
print("You can print \n escape characters too.") 
# You can print escape characters too.
print "This string will be displayed in the output" 
# This string will be displayed in the output
print "You can print \n escape characters too." 
# You can print escape characterstoo.
Capítulo 70: Entrada y salida básica
Examples
Usando input () y raw_input ()
Python 2.x 2.3
raw_input esperará a que el usuario ingrese texto y luego devuelva el resultado como una cadena.
En el ejemplo anterior, foo almacenará cualquier entrada que proporcione el usuario.
Python 3.x 3.0
input esperará a que el usuario ingrese texto y luego devuelva el resultado como una cadena.
En el ejemplo anterior, foo almacenará cualquier entrada que proporcione el usuario.
Usando la función de impresión
Python 3.x 3.0
En Python 3, la funcionalidad de impresión tiene la forma de una función:
Python 2.x 2.3
En Python 2, la impresión fue originalmente una declaración, como se muestra a continuación.
Nota: el uso from future import print_function en Python 2 permitirá a los usuarios usar la 
función print() igual que el código de Python 3. Esto solo está disponible en Python 2.6 y 
superior.
    369/1068
    305
def input_number(msg, err_msg=None): 
while True:
try:
return float(raw_input(msg)) 
except ValueError:
if err_msg is not None: 
print(err_msg)
def input_number(msg, err_msg=None): 
while True:
try:
return float(input(msg)) 
except ValueError:
if err_msg is not None: 
print(err_msg)
user_number = input_number("input a number: ", "that's not a number!")
user_number = input_number("input a number: ")
print "Hello,", 
print "World!" 
# Hello, World!
print("Hello, ", end="\n") 
print("World!")
# Hello, 
# World!
Función para pedir al usuario un número
Y para usarlo:
O, si no desea un "mensaje de error":
Imprimir una cadena sin una nueva línea al final
Python 2.x 2.3
En Python 2.x, para continuar una línea con la print , finalice la declaración de print con una 
coma. Se agregará automáticamente un espacio.
Python 3.x 3.0
EnPython 3.x, la función de print tiene un parámetro end opcional que es lo que se imprimeal 
finaldelacadenadada.Pordefectoesuncarácterdenuevalínea,porloqueesequivalentea 
esto:
Pero podrías pasar en otras cuerdas.
    370/1068
    306
import sys
sys.stdout.write("Hello, ") 
sys.stdout.write("World!") 
# Hello, World!
import sys
for line in sys.stdin: 
print(line)
$ cat myfile | python myprogram.py
Si desea más control sobre la salida, puede usar sys.stdout.write :
Leer de stdin
Los programas de Python pueden leer desde las tuberías de Unix . Aquí hay un ejemplo simple 
de cómo leer desde stdin :
Tengaencuentaquesys.stdinesunasecuencia.Estosignificaqueelfor-loopsoloterminará 
cuando la secuencia haya finalizado.
Ahora puede canalizar la salida de otro programa a su programa python de la siguiente manera:
En este ejemplo, cat myfile puede ser cualquier comando de Unix que salga a stdout . 
Alternativamente, usar el módulo fileinput puede ser útil:
Entrada desde un archivo
La entrada también se puede leer desde archivos. Los archivos se pueden abrir utilizando la 
función incorporada open . Usar un with <command> as <name> sintaxis with <command> as <name>
(llamado 'Administrador de contexto') hace queel uso de open y el manejo del archivo sea súper 
fácil:
import fileinput
for line in fileinput.input(): 
process(line)
print("Hello, ", end="") 
print("World!")
# Hello, World!
print("Hello, ",end="<br>") 
print("World!")
# Hello, <br>World!
print("Hello, ", end="BREAK") 
print("World!")
# Hello, BREAKWorld!
    371/1068
    307
# let's create an example file:
with open('shoppinglist.txt', 'w') as fileobj: 
fileobj.write('tomato\npasta\ngarlic')
with open('shoppinglist.txt', 'r') as fileobj: 
#thismethodmakes a list where each line 
# of the file is an element in the list 
lines = fileobj.readlines()
print(lines)
# ['tomato\n', 'pasta\n', 'garlic']
with open('shoppinglist.txt', 'r') as fileobj:
# here we read the whole content into one string: 
content = fileobj.read()
# get a list of lines, just like int the previous example: 
lines = content.split('\n')
print(lines)
# ['tomato', 'pasta', 'garlic']
with open('shoppinglist.txt', 'r') as fileobj: 
# this method reads line by line:
lines = []
for line in fileobj: 
lines.append(line.strip())
Esto asegura que cuando la ejecución del código deja el bloque, el archivo se cierre 
automáticamente.
Los archivos se pueden abrir en diferentes modos. En el ejemplo anterior, el archivo se abre 
como de solo lectura. Para abrir un archivo existente para lectura solamente use r .Si quieres 
leerese archivo como bytes usa rb .Para adjuntar datos a un archivo existente use aarchivo. Use 
w para crearun archivoosobrescribir cualquierarchivoexistentedel mismonombre.Puedesusar 
r+ para abrir un archivo para leer y escribir. El primer argumento de open() es el nombre del 
archivo, el segundo es el modo.Si el modo se deja en blanco, el valor predeterminado será r .
Si el tamaño del archivo es pequeño, es seguro leer todo el contenido del archivo en la memoria. 
Si el archivo es muy grande, a menudo es mejor leer línea por línea o por fragmentos, y procesar 
la entrada en el mismo bucle. Para hacer eso:
Alleerarchivos,tengaencuentaloscaracteresdesaltodelíneaespecíficosdelsistema 
operativo. Aunque for line in fileobj los for line in fileobj automáticamente, siempre es 
seguro llamar a strip() en las líneas leídas, como se muestra arriba.
Los archivos fileobj ( fileobj en los ejemplos anteriores) siempre apuntan a una ubicación 
específica en el archivo. Cuando se abren porprimera vez, el identificador de archivo apunta al 
principio del archivo, que es la posición 0 .El identificador de archivo puede mostrar su posición 
actual con tell :
with open('somefile.txt', 'r') as fileobj: 
# write code here using fileobj
    372/1068
    308
content = fileobj.read() 
end = fileobj.tell()
print('This file was %u characters long.' % end) 
# This file was 22 characters long. 
fileobj.close()
fileobj = open('shoppinglist.txt', 'r') 
fileobj.seek(7)
pos = fileobj.tell()
print('We are at character #%u.' % pos)
# reads the next 4 characters
# starting at the current position 
next4 = fileobj.read(4)
# what we got? 
print(next4) # 'cucu' 
# where we are now? 
pos = fileobj.tell()
print('We are at %u.' % pos) # We are at 11, as we was at 7, and read 4 chars.
fileobj.close()
with open('shoppinglist.txt', 'r') as fileobj: 
print(type(fileobj.read())) #<class'str'>
with open('shoppinglist.txt', 'rb') as fileobj: 
print(type(fileobj.read())) # <class 'bytes'>
Al leer todo el contenido, la posición del manejador de archivos se señalará al final del archivo:
La posición del manejador de archivos se puede configurar para lo que sea necesario:
También puede leer cualquier longitud del contenido del archivo durante una llamada 
determinada. Para hacer esto pasa un argumento para read() . Cuando se llama a read() sin 
ningúnargumento, se leerá hasta el final del archivo.Si pasa un argumento,leerá ese número de 
bytes o caracteres, dependiendo del modo ( rb y r respectivamente):
Para demostrar la diferencia entre caracteres y bytes:
fileobj = open('shoppinglist.txt', 'r') 
pos = fileobj.tell()
print('We are at %u.' % pos) # We are at 0.
    373/1068
    309
# Print the working directory 
import os
print os.getcwd()
# C:\Python27\Scripts
# Set the working directory 
os.chdir('C:/Users/general1/Documents/simple Python files') 
print os.getcwd()
# C:\Users\general1\Documents\simple Python files
# load pandas 
import pandas as pd
# read a csv data file named 'small_dataset.csv' containing 4 lines and 3 variables 
my_data = pd.read_csv("small_dataset.csv")
my_data
my_data.shape 
# (4, 3)
# number of rows and columns in data set
my_data.shape[0] 
# 4
# number of rows in data set
my_data.shape[1] 
# 3
# number of columns in data set
# Python uses 0-based indexing. The first row or column in a data set is located 
# at position 0. In R the first row or column in a data set islocated
# at position 1.
# Select the first two rows 
my_data[0:2]
Capítulo 71: Entrada, subconjunto y salida de 
archivos de datos externos utilizando Pandas
Introducción
Esta sección muestra el código básico para leer, sububicar y escribir archivos de datos externos 
utilizando pandas.
Examples
Código básico para importar, subcontratar y escribir archivos de datos 
externos mediante Pandas
# x y z
# 0 1 2 3
# 1 4 5 6
# 2 7 8 9
# 3 10 11 12
# x y z
#0 1 2 3
    374/1068
    310
#1 4 5 6
# Select the second and third rows 
my_data[1:3]
# Select the third row 
my_data[2:3]
# Select the first two elements of the first column 
my_data.iloc[0:2, 0:1]
# x
# 0 1
# 1 4
# Select the first element of the variables y and z 
my_data.loc[0, ['y', 'z']]
# y 2
# z 3
# Select the first three elements of the variables y and z 
my_data.loc[0:2, ['y', 'z']]
# Write the first three elements of the variables y and z
# to an external file. Here index = 0means do not write row names. 
my_data2 = my_data.loc[0:2, ['y', 'z']]
my_data2.to_csv('my.output.csv', index = 0)
# x y z
# 1 4 5 6
# 2 7 8 9
# x y z
#2 7 8 9
# y z
# 0 2 3
# 1 5 6
# 2 8 9
    375/1068
    311
pip install enum34
from enum import Enum
class Color(Enum): 
red = 1
green = 2
blue = 3
print(Color.red) # Color.red 
print(Color(1)) # Color.red 
print(Color['red']) # Color.red
class Color(Enum): 
red = 1
green = 2
blue = 3
[c for c in Color] # [<Color.red: 1>, <Color.green: 2>, <Color.blue: 3>]
Capítulo 72: Enumerar
Observaciones
Las enumeraciones se agregaron a Python en la versión 3.4 por PEP 435 .
Examples
Creación de una enumeración (Python 2.4 a 3.3)
Las enumeraciones se han cargado de Python 3.4 a Python 2.4 a través de Python 3.3. Puede 
obtener este backport enum34 desde PyPI.
La creación de una enumeración es idéntica a cómo funciona en Python 3.4+
Iteración
Las enumeraciones son iterables:
    376/1068
    312
alist = [0, 1, 2]
for index, value in enumerate(alist): 
alist.pop(index)
print(alist) 
# Out: [1]
# Iteration #1
index = 0
alist = [0, 1, 2] 
alist.pop(0) # removes '0'
# Iteration #2
index = 1
alist = [1, 2] 
alist.pop(1) # removes'2'
# loop terminates, but alist is not empty: 
alist = [1]
alist = [1,2,3,4,5,6,7]
for index, item in reversed(list(enumerate(alist))): 
# delete all even items
if item % 2 == 0:
Capítulo 73: Errores comunes
Introducción
Python es un lenguaje destinado a ser claro y legible sin ambigüedades ni comportamientos 
inesperados. Desafortunadamente, estos objetivos no son alcanzables en todos los casos, y es 
por eso que Python tiene algunos casos de esquina en los que podría hacer algo diferente de lo 
que esperabas.
Esta sección le mostrará algunos problemas que puede encontrar al escribir código Python.
Examples
Cambiando la secuencia sobre la que estás iterando
Un bucle for repite en una secuencia, por lo que alterar esta secuencia dentro del bucle podría 
generar resultados inesperados (especialmente al agregar o eliminar elementos):
Nota: list.pop() se está utilizando para eliminar elementos de la lista.
El segundo elemento no se eliminó porque la iteración pasa por los índices en orden. El bucle 
anterior se repite dos veces, con los siguientes resultados:
Este problema surge porque los índices cambian mientras se iteran en la dirección del índice 
creciente. Para evitar este problema, puede recorrer el bucle hacia atrás :
    377/1068
    313
alist = [0, 1, 2]
for index, value in enumerate(alist): 
# break to avoid infinite loop:
if index == 20: 
break
alist.insert(index, 'a') 
print(alist)
# Out (abbreviated): ['a', 'a', ..., 'a', 'a', 0, 1, 2]
alist = [1,2,3,4] 
for item in alist:
if item % 2 == 0: 
item = 'even'
print(alist)
# Out: [1,2,3,4]
alist = [1,2,3,4]
for index, item in enumerate(alist): 
if item % 2 == 0:
alist[index] = 'even' 
print(alist)
# Out: [1, 'even', 3, 'even']
Al recorrer el bucle que comienza al final, a medida que se eliminan (o agregan) los elementos, no 
afecta a los índices de los elementos que aparecen anteriormente en la lista. Por lo tanto, este 
ejemplo eliminará correctamente todos los elementos que sean pares de alist .
Un problema similar surge cuando se insertan o agregan elementos a una lista sobre la que 
está iterando , lo que puede dar lugar a un bucle infinito:
Sin la condición de break , el bucle insertaría 'a' siempre que la computadora no se quede sin 
memoriayelprogramapuedacontinuar.Enunasituacióncomoesta,generalmenteseprefiere 
crearuna nuevalista y agregar elementos alanuevalista a medida que recorre lalistaoriginal.
Cuando se utiliza un bucle for , no puede modificar los elementos de la lista con la variable 
de marcador de posición :
Enel ejemploanterior,cambiar el item no cambia realmente nada en la lista original .Debe 
usar el índice de alist[2] ( alist[2] ), y enumerate() funciona bien para esto:
Un while de bucle podría ser una mejor elección en algunos casos: 
Si va a eliminar todos los elementos de la lista:
zlist = [0, 1, 2] 
while zlist:
alist.pop(index) 
print(alist)
# Out: [1, 3, 5, 7]
    378/1068
    314
zlist = []
zlist = [0, 1, 2]
x = 1
while len(zlist) > x: 
print(zlist[0]) 
zlist.pop(0)
print('After: zlist =', zlist)
# Out: 0
# 1
# After: zlist = [2]
zlist = [1,2,3,4,5]
i = 0
while i < len(zlist):
if zlist[i] % 2 == 0: 
zlist.pop(i)
else:
i += 1
print(zlist)
# Out: [1, 3, 5]
zlist = [1,2,3,4,5]
z_temp = []
Aunque simplemente restablecer zlist logrará el mismo resultado;
El ejemplo anterior también se puede combinar con len() para detenerse después de un cierto 
punto, o para eliminar todos los elementos excepto x en la lista:
O para recorrer una lista mientras elimina elementos que cumplen una determinada 
condición (en este caso, eliminar todos los elementos pares):
Observe que no incrementa i después de eliminar un elemento. Al eliminar el elemento en 
zlist[i],el índicedel siguiente elementoha disminuidoen uno,porloque al marcar zlist[i]con 
el mismo valor para i en la siguiente iteración, estará verificando correctamente el siguiente 
elemento en la lista .
Una forma contraria de pensar en eliminar elementos no deseados de una lista, es agregar 
elementos deseados a una nueva lista . El ejemplo siguiente es una alternativa a este último 
while ejemplo de bucle:
print(zlist[0]) 
zlist.pop(0)
print('After: zlist =', zlist)
# Out: 0
# 1
# 2
# After: zlist = []
    379/1068
    315
zlist = [1,2,3,4,5]
[item for item in zlist if item % 2 != 0] 
# Out: [1, 3, 5]
def foo(li=[]): 
li.append(1) 
print(li)
foo([2])
# Out: [2, 1]
foo([3])
# Out: [3, 1]
foo()
# Out: [1] As expected...
foo()
# Out: [1, 1] Not as expected...
def foo(li=None): 
if not li:
li = [] 
li.append(1) 
print(li)
foo()
# Out: [1]
foo()
Aquí estamos canalizando los resultados deseados en una nueva lista. De manera opcional, 
podemos reasignar la lista temporal a la variable original.
Con esta tendencia de pensamiento, puede invocar una de las funciones más elegantes y 
potentes de Python, listas de comprensión , que elimina las listas temporales y se desvía de la 
ideología de mutación de listas / índices in situ anteriormente discutida.
Argumento predeterminado mutable
Este código se comporta como se espera, pero ¿y si no pasamos un argumento?
Esto se debe a que los argumentos predeterminados de las funciones y los métodos se evalúan 
en el momento de ladefinición en lugardel tiempo de ejecución.Así que solo tenemos una sola 
instancia de la lista li .
La forma de evitarlo es usar solo tipos inmutables para los argumentos predeterminados:
for item in zlist: 
ifitem % 2 != 0:
z_temp.append(item) 
zlist = z_temp
print(zlist)
# Out: [1, 3, 5]
    380/1068
    316
x = []
foo(li=x) 
# Out: [1]
foo(li="")
# Out: [1]
foo(li=0) 
# Out: [1]
def foo(li=None): 
if li is None:
li = [] 
li.append(1) 
print(li)
foo()
# Out: [1]
li = [[]] * 3 
print(li)
# Out: [[], [], []]
li[0].append(1) 
print(li)
# Out: [[1], [1], [1]]
li = [] 
element = [[]]
li=element+element+element 
print(li)
Si bien es una mejora y, if not li se evalúa correctamente como False , muchos otros objetos 
tambiénlohacen,comolas secuenciasdelongitudcero.Los siguientesargumentosde ejemplo 
pueden causar resultados no deseados:
El enfoque idiomático es verificar directamente el argumento en contra del objeto None :
Lista de multiplicación y referencias comunes.
Considere el caso de crear una estructura de lista anidada multiplicando:
A primera vista, podríamos pensar que tenemos una lista que contiene 3 listas anidadas 
diferentes. Intentemos adjuntar 1 al primero:
1 obtuve adjunta a todas las listas de li .
Larazónesque[[]]* 3nocreaunalistde3listdiferentes.Másbien,creaunalistcontiene 
3referenciasalmismoobjetodelist.Comotal,cuandoagregamosali[0]elcambioesvisible 
en todos los subelementos de li . Esto es equivalente a:
# Out: [1]
    381/1068
    317
li = [[]] * 3
print([id(inner_list) for inner_list in li]) 
# Out: [6830760, 6830760, 6830760]
li = [[] for _ in range(3)]
print([id(inner_list) for inner_list in li]) 
# Out: [6331048, 6331528, 6331488]
>>> li = []
>>> li.append([])
>>> li.append([])
>>> li.append([])
>>> for k in li: print(id(k))
... 
4315469256
4315564552
4315564808
for i in range(len(tab)): 
print(tab[i])
for elem in tab: 
print(elem)
for i, elem in enumerate(tab):
Estosepuedecorroboraraúnmássiimprimimoslasdireccionesdememoriadelalistcontenida 
usando id :
La solución es crear las listas internas con un bucle:
En lugar de crear una list única y luego hacer 3 referencias a ella, ahora creamos 3 listas 
distintas diferentes. Esto, de nuevo, puede verificarse usando la función id :
También puedes hacer esto. Hace que se cree una nueva lista vacía en cada llamada append .
No utilice el índice para recorrer una secuencia.
No hagas
Hacer
for automatizará la mayoría de las operaciones de iteración para usted.
Use enumerar si realmente necesita tanto el índice como el elemento .
# Out: [[], [], []]
element.append(1) 
print(li)
# Out: [[1], [1], [1]]
    382/1068
    318
if (var == True):
# this will execute if var is True or 1, 1.0, 1L
if (var != True):
# this will execute if var is neither True nor 1
if (var == False):
# this will execute if var is False or 0 (or 0.0, 0L, 0j)
if (var == None):
# only execute if var is None
if var:
# execute if var is a non-empty string/list/dictionary/tuple, non-0, etc
if not var:
# execute if var is "", {}, [], (), 0, None, etc.
if var is True:
# only execute if var is boolean True, not 1
if var is False:
# only execute if var is boolean False, not 0
if var is None:
# same as var == None
if os.path.isfile(file_path): 
file = open(file_path)
else:
# do something
try:
file = open(file_path) 
except OSError as e:
# do something
with open(file_path) as file:
Tenga cuidado al usar "==" para verificar si es verdadero o falso
No marque si puede, solo hágalo y maneje el error
Los pitonistas usualmente dicen "es más fácil pedir perdón que permiso".
No hagas
Hacer:
O incluso mejor con Python 2.6+ :
Es mucho mejor porque es mucho más genérico. Puede aplicar try/except a casi cualquier cosa.
print((i, elem))
    383/1068
    319
def foo(name):
if isinstance(name, str): 
print(name.lower())
def bar(listing):
if isinstance(listing, list): 
listing.extend((1, 2, 3)) 
return ", ".join(listing)
def foo(name) : 
print(str(name).lower())
def bar(listing) : 
l =list(listing)
l.extend((1, 2, 3))
return ",".join(l)
class Father: 
pass
class Child(Father): 
pass
No necesita preocuparse por lo que debe hacer para evitarlo, solo debe preocuparse por el error 
que está arriesgando.
No comprobar contra tipo
Python se escribe dinámicamente, porlotanto,verificarel tipo hacequepierdas flexibilidad.En su 
lugar, utilicela escritura de patocomprobandoel comportamiento.Si espera una cadena enuna 
función, use str() para convertir cualquier objeto en una cadena. Si espera una lista, use list() 
para convertir cualquier iterable en una lista.
No hagas
Hacer:
Usandola última forma, foo aceptará cualquierobjeto. bar aceptará cadenas, tuplas, conjuntos, 
listas y mucho más. Barato SECO.
No mezclar espacios y pestañas 
Usa el objeto como primer padre
Esto es complicado, pero te morderá a medida que tu programa crezca. Hay clases antiguas y 
nuevas en Python 2.x Los viejos son, bueno, viejos. Carecen de algunas características, y pueden 
tener un comportamiento incómodo conla herencia.Para ser utilizable, cualquiera de su clase 
debe ser del "nuevo estilo". Para ello, hazlo heredar del object .
No hagas
Hacer:
    384/1068
    320
class Car(object): 
color = "red"
wheels = [Wheel(), Wheel(), Wheel(), Wheel()]
class Car(object): 
def init (self):
self.color = "red"
self.wheels = [Wheel(), Wheel(), Wheel(), Wheel()]
>>> -8 is (-7 - 1)
False
>>> -3 is (-2 - 1)
True
>>> (255 + 1) is (255 + 1)
En Python 3.x todas las clases son de estilo nuevo, por lo que no necesitas hacerlo.
No inicialice los atributos de clase fuera del método init
A las personas que vienen de otros idiomas les resulta tentador porque eso es lo que haces en 
Java o PHP. Escribe el nombre de la clase, luego enumera sus atributos y les asigna un valor 
predeterminado. Parece funcionar en Python, sin embargo, esto no funciona como piensas. Al 
hacerlo, se configurarán los atributos de clase (atributos estáticos), luego, cuando intente obtener 
el atributo de objeto, le dará su valor a menos que esté vacío. En ese caso devolverá los atributos 
de la clase. Implica dos grandes peligros:
• Si se cambia el atributo de clase, entonces se cambia el valor inicial.
• Si configura un objeto mutable como un valor predeterminado, obtendrá el mismo objeto 
compartido en todas las instancias.
No (a menos que quieras estática):
Hacer
Identidad entera y de cadena
Python utiliza el almacenamiento en caché interno para un rango de enteros para reducir la 
sobrecarga innecesaria de su creación repetida.
En efecto, esto puede llevar a un comportamiento confuso al comparar identidades enteras:
y, usando otro ejemplo:
class Father(object): 
pass
class Child(Father): 
pass
    385/1068
    321
>>> 'python' is 'py' + 'thon' 
True
>>> 'this is not a common string' is 'this is not' + ' a common string' 
False
>>> 'this is not a common string' == 'this is not' + ' a common string' 
True
¿Esperar lo?
PodemosverquelaoperacióndeidentidadisTrueparaalgunosenteros(-3,256)peronopara 
otros ( -8 , 257 ).
Paraser másespecíficos,losenterosenelrango[-5, 256]sealmacenanencaché internamente 
durante el inicio del intérprete y solo se crean una vez. Como tales, son idénticos y la 
comparación de sus identidades con is rinde True ; los enteros fuera de este rango son 
(generalmente) creados sobre la marcha y sus identidades se comparan con False .
Este es un error común ya que este es un rango común para las pruebas, pero a menudo, el 
código falla en el proceso posterior de estadificación (o peor aún, en la producción) sin una razón 
aparente después de funcionar perfectamente en el desarrollo.
Lasolución es comparar siempre los valores utilizando el operador deigualdad ( == ) y no el 
operador de identidad ( is ).
Python también mantiene referencias a los usados comúnmente cuerdas y pueden resultar en un 
comportamiento de manera similar confuso cuando la comparación de identidades (es decir, 
utilizando is ) de cadenas.
La cadena 'python' se usa comúnmente, por lo que Python tiene un objeto que usan todas las 
referencias a la cadena 'python' .
Para cadenas poco comunes, la comparación de identidad falla incluso cuando las cadenas son 
iguales.
Entonces, al igual que la regla para enteros, siempre compare valores de cadena utilizando el
operador de igualdad ( == ) y no el operador de identidad ( is ).
Accediendo a los atributos de int literals.
Es posible que hayas oído que todo en Python es un objeto, incluso literales. Esto significa, por 
ejemplo, que 7 es un objeto, lo que significa que tiene atributos. Por ejemplo, uno de estos 
atributos es el bit_length . Devuelve la cantidad de bits necesarios para representar el valor al 
que se solicita.
True
>>> (256 + 1) is (256 + 1)
False
    386/1068
    322
# parenthesis 
(7).bit_length() 
# a space
7 .bit_length()
7.2.as_integer_ratio()
# Out: (8106479329266893, 1125899906842624)
if a == 3 or b == 3 or c == 3:
if a or b or c == 3: # Wrong
if a == 3 or b == 3 or c == 3: # Right Way
if any([a == 3, b == 3, c == 3]): # Right
Al ver que el código anteriorfunciona, podría pensarintuitivamente que 7.bit_length() también 
funcionaría,soloparadescubrirquegeneraunSyntaxError.¿Porqué?porqueelintérpretedebe 
diferenciarentreunaccesodeatributoyunnúmeroflotante(porejemplo, 7.2o7.bit_length()). 
No puede, y es por eso que se levanta una excepción.
Hay algunas formas de acceder a los atributos de los literales int :
El uso de dos puntos (como este 7..bit_length() ) no funciona en este caso, porque crea un literal
float y los flotantes no tienen el método bit_length() .
Esteproblemanoexistealaccederalosatributos delosliteralesfloat, yaqueelintérpreteeslo 
suficientemente "inteligente" para saber que un literal float no puede contener dos . , por 
ejemplo:
Encadenamiento de u operador
Al probar para cualquiera de varias comparaciones de igualdad:
es tentador abreviar esto a
Estoestámal;eloperador ortieneunaprioridadmenorque==,porloquelaexpresiónse 
evaluarácomoif(a) or(b) or(c ==3):Laformacorrectaesverificandoexplícitamentetodas 
las condiciones:
Alternativamente, la función any() incorporada se puede usar en lugar de encadenados or
operadores:
O, para hacerlo más eficiente:
x = 7 
x.bit_length() 
# Out: 3
    387/1068
    323
if 3 in (a, b, c): # Right
if a == 1 or 2 or 3:
if a in (1, 2, 3):
# script.py 
import sys
print(sys.argv[0]) 
print(sys.argv)
$ python script.py
=> script.py
=> ['script.py']
$ python script.py fizz
=> script.py
=> ['script.py', 'fizz']
$ python script.py fizz buzz
=> script.py
=> ['script.py', 'fizz', 'buzz']
myDict = {'first': 1, 'second': 2, 'third': 3} 
print(myDict)
# Out: {'first': 1, 'second': 2, 'third': 3}
O, para hacerlo más corto:
Aquí, usamos el operador in para probar si el valor está presente en una tupla que contiene los 
valores con los que queremos comparar.
Del mismo modo, es incorrecto escribir
que debe ser escrito como
sys.argv [0] es el nombre del archivo que se está ejecutando
El primer elemento de sys.argv[0] es el nombre del archivo python que se está ejecutando. Los 
elementos restantes son los argumentos del script.
Los diccionarios están desordenados.
Puede esperar que un diccionario de Python se ordene por claves como, por ejemplo, un C ++
std::map , pero este no es el caso:
if any(x == 3 for x in (a, b, c)): # Right
    388/1068
    324
from collections import OrderedDict
oDict = OrderedDict([('first', 1), ('second', 2), ('third', 3)]) 
print([k for k in oDict])
# Out: ['first', 'second', 'third']
def func(**kw): print(kw.keys())
func(a=1, b=2, c=3, d=4, e=5)
dict_keys(['a', 'b', 'c', 'd', 'e']) # expected order
import math
from threading import Thread
def calc_fact(num): 
math.factorial(num)
num = 600000
t = Thread(target=calc_fact, daemon=True, args=[num]) 
print("About to calculate: {}!".format(num)) 
t.start()
print("Calculating...")
Python no tiene ninguna clase incorporada que ordene automáticamente sus elementos por clave.
Sinembargo, si la ordenación no es obligatoriay solo deseaque sudiccionario recuerde el orden 
de inserción de sus pares clave / valor, puede usar collections.OrderedDict :
Tenga en cuenta que inicializar un OrderedDict con un diccionario estándar no ordenará el 
diccionario por usted. Todo lo que hace esta estructura es preservar el orden de inserción de la 
clave.
La implementación de los diccionarios se cambió en Python 3.6 para mejorar su consumo de 
memoria. Un efecto secundario de esta nueva implementación es que también conserva el orden 
de los argumentos de palabras clave que se pasan a una función:
Python 3.x 3.6
Advertencia : tenga en cuenta que " el aspecto de preservar el orden de esta nueva
implementación se considera un detalle de implementación y no se debe confiar en él
" , ya que puede cambiar en el futuro.
Bloqueo global de intérprete (GIL) y bloqueo de hilos
Se ha escrito mucho sobre GIL de Python . A veces puede causar confusión cuando se trata de 
aplicaciones de subprocesos múltiples (no confundir con multiproceso).
Aquí hay un ejemplo:
print([k for k in myDict])
# Out: ['second', 'third', 'first']
    389/1068
    325
i = 0
a = [i for i in range(3)] 
print(i) # Outputs 2
def calc_fact(num):
""" A slow version of factorial in native Python """ 
res = 1
while num >= 1: 
res = res * num 
num -= 1
return res
def calc_fact(num): 
sleep(0.001) 
math.factorial(num)
i = 0
a = [i for i in range(3)] 
print(i) # Outputs 0
Esperaría ver el Calculating... impreso inmediatamente después de comenzar el hilo, ¡queríamos 
que el cálculo se realizara en un nuevo hilo después de todo! Pero en realidad, usted ve que se 
imprime una vez que se completa el cálculo. Esto se debe a que el nuevo hilo se basa en una 
función C ( math.factorial ) que bloqueará la GIL mientras se ejecuta.
Hay un par de maneras de evitar esto. El primero es implementar tu función factorial en Python 
nativo. Esto permitirá que el hilo principal tome el control mientras estás dentro de tu bucle. El 
inconveniente es que esta solución será mucho más lenta, ya que ya no estamos utilizando la 
función C.
También puede sleep durante un período de tiempo antes de comenzar su ejecución. Nota: esto 
no permitirá que su programa interrumpa el cálculo que ocurre dentro de la función C, pero 
permitirá que su hilo principal continúe después del inicio, que es lo que puede esperar.
Fugas variables en listas de comprensión y para bucles.
Considere la siguiente lista de comprensión 
Python 2.x 2.7
Esto ocurre solo en Python 2 debido a que la comprensión de la lista "filtra" la variable de control 
de bucle en el ámbito circundante ( fuente ). Este comportamiento puede provocar errores difíciles 
de encontrar y se ha corregido en Python 3 .
Python 3.x 3.0
Del mismo modo, para los bucles no tienen ámbito privado para su variable de iteración
t.join() 
print("Calculated")
    390/1068
    326
def xyz(): 
return a, b
t = xyz()
my_var = 'bla'; 
api_key = 'key';
...lots of code here...
params = {"language": "en", my_var: api_key}
{
"language": "en",
"my_var": "key"
}
Este tipo de comportamiento ocurre tanto en Python 2 como en Python 3.
Para evitar problemas con las variables con fugas, use nuevas variables en la lista de 
comprensión y para los bucles, según corresponda.
Retorno múltiple
La función xyz devuelve dos valores a y b:
El código que llama a xyz almacena el resultado en una variable, asumiendo que xyz devuelve 
solo un valor:
Valordetesenrealidadunatupla(a,b)porloquecualquieracciónentsuponiendoquenoes 
una tupla puede fallarprofundoen el código con un un errorinesperado sobre tuplas.
TypeError: el tipo tuple no define ... el método 
La solución sería hacer:
¡Los principiantes tendrán problemas para encontrar el motivo de este mensaje al solo leer el 
mensaje de error de la tupla!
Teclas JSON pitónicas
Siestásacostumbrado aJavaScript,laevaluacióndevariables enlosdiccionarios dePythonno 
será lo que esperas que sea. Esta declaración en JavaScript daría como resultado el objeto 
params siguiente manera:
a, b = xyz()
i = 0
for i in range(3): 
pass
print(i) # Outputs 2
    391/1068
    327
{
"language": "en",
"bla": "key"
}
En Python, sin embargo, daría como resultado el siguiente diccionario:
my_var se evalúa y su valor se utiliza como clave.
    392/1068
    328
import csv
Capítulo 74: Escribiendo a CSV desde String 
o List
Introducción
Escribir en un archivo .csv no es diferente a escribir en un archivo regular en la mayoría de los 
casos, y es bastante sencillo. De la mejor manera posible, cubriré el enfoque más fácil y eficiente 
del problema.
Parámetros
Parámetro Detalles
abierto ( "/ ruta /" , "modo") Especifique la ruta a su archivo CSV
abierto (ruta, "modo" )
Especifique el modo para abrir el archivo en (lectura, 
escritura, etc.)
csv.writer ( archivo , 
delimitador) Pase el archivo CSV abierto aquí
csv.writer (archivo, delimitador
= '' )
Especificar carácter o patrón delimitador
Observaciones
open( path, "wb") 
"wb" - Modo de escritura.
El parámetro b en "wb" que hemos utilizado, es necesario solo si desea abrirlo en modo binario,
que solo se necesita en algunos sistemas operativos como Windows.
csv.writer ( csv_file, delimiter=',' )
Aquíeldelimitadorquehemosutilizadoes,porquequeremosquecadaceldadedatosenuna 
fila,contenga el nombre,el apellidoyla edad respectivamente.Ya que nuestralista está dividida 
a lo largo de , también, resulta bastante conveniente para nosotros.
Examples
Ejemplo básico de escritura
    393/1068
    329
def append_to_csv(input_string):
with open("fileName.csv", "a") as csv_file: 
csv_file.write(input_row + "\n")
Anexando una cadena como nueva línea en un archivo CSV
#------ We will write to CSV in this function ------------
def csv_writer(data, path):
#Open CSV file whose path we passed. 
with open(path, "wb") as csv_file:
writer = csv.writer(csv_file, delimiter=',') 
for line in data:
writer.writerow(line)
#---- Define our list here, and call function ------------
if name == " main ": """
data = our list that we want to write. 
Split it so we get a list of lists. 
"""
data = ["first_name,last_name,age".split(","), 
"John,Doe,22".split(","),
"Jane,Doe,31".split(","),
"Jack,Reacher,27".split(",")
]
# Path to CSV file we want to write to. 
path = "output.csv"
csv_writer(data, path)
    394/1068
    330
@route("/stream") 
def stream():
def event_stream(): 
while True:
if message_to_send: 
yield "data:
{}\n\n".format(message_to_send)"
return Response(event_stream(), mimetype="text/event-stream")
import asyncio 
import sse
class Handler(sse.Handler): 
@asyncio.coroutine
def handle_request(self):
yield from asyncio.sleep(2) 
self.send('foo')
yield from asyncio.sleep(2) 
self.send('bar', event='wakeup')
start_server = sse.serve(Handler, 'localhost', 8888) 
asyncio.get_event_loop().run_until_complete(start_server) 
asyncio.get_event_loop().run_forever()
Capítulo 75: Eventos enviados de Python 
Server
Introducción
Server Sent Events (SSE) es una conexión unidireccional entre un servidor y un cliente 
(generalmente un navegador web) que permite al servidor "enviar" información al cliente. Se 
parece mucho a los websockets y las encuestas largas. La principal diferencia entre SSE y 
websockets es que SSE es unidireccional, solo el servidor puede enviar información al cliente, 
mientras que al igual que con websockets, ambos pueden enviarse información entre ellos.
Generalmente, se considera que SSE es mucho más simple de usar / implementar que 
websockets.
Examples
Frasco SSE
Asyncio SSE
Este ejemplo utiliza la biblioteca SSE de asyncio: https://github.com/brutasse/asyncio-sse
    395/1068
    331
class WrongInputException(Exception): 
pass
def convert2number(random_input): 
try:
my_input = int(random_input) 
except ValueError:
raise WrongInputException("Expected an integer!") 
return my_input
import unittest
class ExceptionTestCase(unittest.TestCase):
Capítulo 76: Examen de la unidad
Observaciones
Hayvariasherramientasdepruebadeunidad paraPython.Estetemadedocumentación describe 
el módulo de unittest básico. Otras herramientas de prueba incluyen py.test y nosetests . Esta 
documentaciónde pythonsobrepruebas comparavariasde estasherramientas sinprofundizar.
Examples
Pruebas de excepciones
Los programas lanzan errores cuando, por ejemplo, se da una entrada incorrecta. Debido a esto, 
uno debe asegurarse de que se produce un error cuando se da una entrada incorrecta real. Por 
eso necesitamos verificar una excepción exacta, para este ejemplo usaremos la siguiente 
excepción:
Esta excepción se genera cuando se proporciona una entrada incorrecta, en el siguiente contexto 
donde siempre esperamos un número como entrada de texto.
Para verificar si se ha generado una excepción, usamos assertRaises para verificar esa excepción.
assertRaises se puede utilizar de dos maneras:
1. Usando la llamada de función regular. El primer argumento toma el tipo de excepción, el 
segundo un llamable (generalmente una función) y el resto de los argumentos se pasan a 
este llamable.
2. Usar una cláusula with , dando solo el tipo de excepción a la función.Esto tiene la ventaja 
de que se puede ejecutar más código, pero se debe usar con cuidado ya que múltiples 
funcionespuedenusarlamismaexcepción,quepuedeserproblemática.Unejemplo: con 
self.assertRaises (WrongInputException): convert2number ("no es un número")
Este primero se ha implementado en el siguiente caso de prueba:
    396/1068
    332
def multiply(a, b): 
return a * b
from custom_math import multiply
def multiples_of(integer, *args, num_multiples=0, **kwargs): 
"""
:rtype: list 
"""
multiples = []
for x in range(1, num_multiples + 1): 
"""
Passing in args and kwargs here will only raise TypeError if values were 
passed to multiples_of function, otherwise they are ignored. This way we can 
test that multiples_of is used correctly. This is here for an illustration 
of how create_autospec works. Not recommended for production code.
"""
multiple = multiply(integer,x, *args, **kwargs) 
multiples.append(multiple)
return multiples
También puede ser necesario verificar si hay una excepción que no debería haberse lanzado. Sin 
embargo, una prueba fallará automáticamente cuando se lance una excepción y, por lo tanto, 
puede que no sea necesaria en absoluto. Solo para mostrar las opciones, el segundo método de 
prueba muestra un caso sobre cómo se puede verificar que no se produzca una excepción.
Básicamente, esto es capturar la excepción y luego fallar la prueba usando el método de fail .
Funciones de simulación con unittest.mock.create_autospec
Una forma de simular una función es utilizar la función create_autospec , que create_autospec un 
objeto de acuerdo con sus especificaciones. Con las funciones, podemos usar esto para 
asegurarnos de que se llamen adecuadamente.
Con una función multiply en custom_math.py :
Y una función multiples_of en process_math.py :
Podemos probar multiples_of solo burlándose de multiply . El siguiente ejemplo utiliza la prueba
de unidad de la biblioteca estándar de Python, pero esto también se puede usar con otros marcos 
de prueba, como pytest o nose:
def test_wrong_input_string(self):
self.assertRaises(WrongInputException, convert2number, "not a number")
def test_correct_input(self): 
try:
result = convert2number("56") 
self.assertIsInstance(result, int)
except WrongInputException: 
self.fail()
    397/1068
    333
import unittest
class SomeTest(unittest.TestCase): 
def setUp(self):
super(SomeTest, self).setUp() 
self.mock_data = [1,2,3,4,5]
def test(self): 
self.assertEqual(len(self.mock_data), 5)
def tearDown(self):
super(SomeTest, self).tearDown() 
self.mock_data = []
if name == 'main ': 
unittest.main()
Configuración de prueba y desmontaje dentro de un unittest.TestCase
Avecesqueremosprepararuncontextoparacadapruebaqueseejecutará.ElmétododesetUp 
seejecuta antesdecada prueba enlaclase.tearDown se ejecutaalfinaldecada prueba.Estos 
métodossonopcionales.RecuerdequelosTestCasesamenudoseusanenherenciamúltiple 
cooperativa, porloquedebetener cuidadodellamarsiempresuperenestosmétodosparaque 
también se tearDown métodos setUp y tearDown la clase base. La implementación básica de TestCase 
proporciona TestCase vacíos de setUp y tearDown para que puedan llamarse sin generar 
excepciones:
Tenga en cuenta que en python2.7 +, también existe el método addCleanup que registra las 
funciones que deben llamarse después de ejecutarla prueba. Adiferencia de tearDown que solo se 
llama si setUp tiene éxito, las funciones registradas a través de addCleanup se addCleanup incluso en 
el caso de una excepción no controlada en setUp . Como ejemplo concreto, con frecuencia se 
puedevereste métodoeliminando varios simulacros que se registraron mientras seejecutabala 
prueba:
from unittest.mock import create_autospec 
import unittest
# we import the entire module so we can mock out multiply 
import custom_math
custom_math.multiply = create_autospec(custom_math.multiply) 
from process_math import multiples_of
class TestCustomMath(unittest.TestCase): 
def test_multiples_of(self):
multiples = multiples_of(3, num_multiples=1) 
custom_math.multiply.assert_called_with(3, 1)
def test_multiples_of_with_bad_inputs(self): 
with self.assertRaises(TypeError) as e:
multiples_of(1, "extra arg", num_multiples=1) # this should raise a TypeError
    398/1068
    334
def division_function(dividend, divisor): 
return dividend / divisor
class MyTestCase(unittest.TestCase): 
def test_using_context_manager(self):
with self.assertRaises(ZeroDivisionError): 
x = division_function(1, 0)
class MyTestCase(unittest.TestCase): 
def test_using_context_manager(self):
with self.assertRaises(ZeroDivisionError) as ex: 
x = division_function(1, 0)
self.assertEqual(ex.message, 'integer division or modulo by zero')
def division_function(dividend, divisor): 
"""
Otra ventaja de registrar las limpiezas de esta manera es que le permite al programador colocar el 
código de limpieza al lado del código de configuración y lo protege en caso de que un subclase 
olvide llamar super en tearDown .
Afirmación de excepciones
Puede probar que una función produce una excepción con la prueba de unidad incorporada a 
través de dos métodos diferentes.
Usando un administrador de contexto
Esto ejecutará el código dentro del administrador de contexto y, si tiene éxito, fallará la prueba 
porque no se generó la excepción. Si el código genera una excepción del tipo correcto, la prueba 
continuará.
También puede obtener el contenido de la excepción generada si desea ejecutar aserciones 
adicionales en su contra.
Al proporcionar una función de llamada
import unittest 
importsome_module
class SomeOtherTest(unittest.TestCase): 
def setUp(self):
super(SomeOtherTest, self).setUp()
# Replace `some_module.method` with a `mock.Mock` 
my_patch = mock.patch.object(some_module, 'method') 
my_patch.start()
# When the test finishes running, put the original method back. 
self.addCleanup(my_patch.stop)
    399/1068
    335
import unittest
class SimplisticTest(unittest.TestCase): 
def test_basic(self):
self.assertTrue(1 + 1 == 2)
self.assertTrue(1 + 1 == 3)
self.assertEqual(1 + 1, 3)
======================================================================
FAIL: test ( main .TruthTest)
La excepción para verificar debe ser el primer parámetro, y una función que se puede llamar debe 
pasarse como el segundo parámetro. Cualquier otro parámetro especificado se pasará 
directamente a la función que se está llamando, lo que le permite especificar los parámetros que 
activan la excepción.
Eligiendo aserciones dentro de unitests
Mientras Python tiene una assert comunicado , el marco de la unidad de pruebas Python tiene 
mejores afirmaciones especializados para las pruebas: son más informativos en los fracasos, y no 
dependen del modo de depuración de la ejecución.
Quizás la aserción más simple es assertTrue , que se puede usar así:
Esto funcionará bien, pero reemplazando la línea anterior con
fallará.
La afirmación assertTrue es bastante probable que sea la afirmación más general, ya que 
cualquier cosa probada puede assertTrue como una condición booleana, pero a menudo hay 
mejores alternativas. Cuando se prueba la igualdad, como arriba, es mejor escribir
Cuando el primero falla, el mensaje es
Dividing two numbers.
:type dividend: int
:type divisor: int
:raises: ZeroDivisionError if divisor is zero (0).
:rtype: int 
"""
return dividend / divisor
class MyTestCase(unittest.TestCase): 
def test_passing_function(self):
self.assertRaises(ZeroDivisionError, division_function, 1, 0)
    400/1068
    336
======================================================================
FAIL: test ( main .TruthTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "stuff.py", line 6, in test 
self.assertEqual(1 + 1, 3)
AssertionError: 2 != 3
pip install pytest
mkdir tests
touch tests/test_docker.py
from subprocess import Popen, PIPE
# this Popen is monkeypatched with the fixture `all_popens`
pero cuando este último falla, el mensaje es
que es más informativo (en realidad evaluó el resultado del lado izquierdo).
Puede encontrar la lista de afirmaciones en la documentación estándar. En general, es una 
buenaideaelegirlaafirmaciónqueseajustemásespecíficamentealacondición.Porlotanto, 
como se muestra arriba, para afirmar que 1 + 1 == 2 es mejor usar assertEqual que assertTrue . De 
manera similar, para afirmar que a is None , es mejor usar assertIsNone que assertEqual .
Tenga en cuenta también que las afirmaciones tienen formas negativas. Por assertEqual tanto, 
assertEqual tiene su contraparte negativa assertNotEqual , y assertIsNone tiene su contraparte 
negativa assertIsNotNone . Una vez más, usar las contrapartes negativas cuando sea apropiado, 
dará lugar a mensajes de error más claros.
Pruebas unitarias con pytest
instalando pytest:
preparando las pruebas:
Funciones para probar en docker_something/helpers.py :
----------------------------------------------------------------------
Traceback (most recent call last):
File "stuff.py", line 6, in test 
self.assertTrue(1 + 1 == 3)
AssertionError: False is not true
    401/1068
    337
import os
from tempfile import NamedTemporaryFile 
import pytest
from subprocess import Popen, PIPE
from docker_something import helpers 
copy_file_to_docker = helpers.copy_file_to_docker 
docker_exec_something = helpers.docker_exec_something
class MockBytes():
'''Usedtocollectbytes 
'''
all_read = [] 
all_write = [] 
all_close = []
def read(self, *args, **kwargs):
# print('read', args, kwargs, dir(self)) 
self.all_read.append((self, args, kwargs))
def write(self, *args, **kwargs): 
# print('wrote', args, kwargs)
self.all_write.append((self, args, kwargs))
def close(self, *args, **kwargs):
# print('closed', self, args, kwargs) 
self.all_close.append((self, args, kwargs))
def get_all_mock_bytes(self):
return self.all_read, self.all_write, self.all_close
La prueba importa test_docker.py :
burlándose de un archivo como objeto en test_docker.py :
def copy_file_to_docker(src, dest): 
try:
result = Popen(['docker','cp', src, 'something_cont:{}'.format(dest)], stdout=PIPE, 
stderr=PIPE)
err = result.stderr.read() 
if err:
raise Exception(err) 
except Exception as e:
print(e) 
return result
def docker_exec_something(something_file_string):
fl = Popen(["docker", "exec", "-i", "something_cont", "something"], stdin=PIPE, 
stdout=PIPE, stderr=PIPE)
fl.stdin.write(something_file_string) 
fl.stdin.close()
err = fl.stderr.read() 
fl.stderr.close()
if err:
print(err) 
exit()
result = fl.stdout.read() 
print(result)
    402/1068
    338
@pytest.fixture
def all_popens(monkeypatch):
'''This fixture overrides / mocks the builtin Popen
and replaces stdin, stdout, stderr with a MockBytes object
note: monkeypatch is magically imported
'''
all_popens = []
class MockPopen(object):
def init (self, args, stdout=None, stdin=None, stderr=None): 
all_popens.append(self)
self.args = args 
self.byte_collection = MockBytes() 
self.stdin = self.byte_collection 
self.stdout = self.byte_collection 
self.stderr = self.byte_collection 
pass
monkeypatch.setattr(helpers, 'Popen', MockPopen)
return all_popens
def test_docker_install():
p = Popen(['which', 'docker'], stdout=PIPE, stderr=PIPE) 
result = p.stdout.read()
assert 'bin/docker' in result
def test_copy_file_to_docker(all_popens):
result = copy_file_to_docker('asdf', 'asdf') 
collected_popen = all_popens.pop()
mock_read, mock_write, mock_close = collected_popen.byte_collection.get_all_mock_bytes() 
assert mock_read
assert result.args == ['docker', 'cp', 'asdf', 'something_cont:asdf']
def test_docker_exec_something(all_popens): 
docker_exec_something(something_file_string)
collected_popen = all_popens.pop()
mock_read, mock_write, mock_close = collected_popen.byte_collection.get_all_mock_bytes() 
assert len(mock_read) == 3
something_template_stdin = mock_write[0][1][0]
these = [os.environ['USER'], os.environ['password_prod'], 'table_name_here', 'test_vdm', 
'col_a', 'col_b', '/tmp/test.tsv']
assert all([x in something_template_stdin for x in these])
py.test -k test_docker_install tests 
py.test -k test_copy_file_to_docker tests 
py.test -k test_docker_exec_something tests
Parches de mono con pytest en test_docker.py :
Ejemplos de pruebas, deben comenzar con el prefijo test_ en el archivo test_docker.py :
ejecutando las pruebas una a la vez:
    403/1068
    339
py.test -k test_ tests
ejecutando todas las pruebas en la carpeta de tests :
    404/1068
    340
def even_the_odds(odds): 
if odds % 2 != 1:
raise ValueError("Did not get an odd number")
return odds + 1
try:
x = 5 / 0
except ZeroDivisionError as e:
# `e` is the exception object
print("Got a divide by zero! The exception was:", e) 
# handle exceptional case
x = 0
Capítulo 77: Excepciones
Introducción
Los errores detectados durante la ejecución se denominan excepciones y no son 
incondicionalmentefatales.Lamayoríadelasexcepcionesnosonmanejadasporlosprogramas; 
es posible escribir programas que manejen excepciones seleccionadas. Hay características 
específicas enPython para lidiar con las excepciones y la lógica de excepciones.Además, las 
excepcionestienenunajerarquía de tiposenriquecidos, todosheredados del tipo BaseException .
Sintaxis
• levantar excepción
• elevar # re-elevar una excepción que ya ha sido planteada
• generar excepción de causa # Python 3 - establecer causa de excepción
• generar excepción desde Ninguna # Python 3 - suprimir todo el contexto de excepción
• tratar:
• excepto [tipos de excepción] [ como identificador ] :
• más:
• finalmente:
Examples
Levantando excepciones
Si su código encuentra una condición que no sabe cómo manejar, como un parámetro incorrecto, 
debe generar la excepción apropiada.
Atrapar excepciones
Utilicetry...except:paradetectarexcepciones.Debeespecificarunaexcepcióntanprecisacomo 
pueda:
    405/1068
    341
>>> ZeroDivisionError. bases
(<class 'ArithmeticError'>,)
try:
5 / 0
except ArithmeticError: 
print("Got arithmetic error")
resource = allocate_some_expensive_resource() 
try:
do_stuff(resource) 
except SomeException as e:
log_error(e)
raise # re-raise the error 
finally:
free_expensive_resource(resource)
try:
5 / 0
except ZeroDivisionError: 
print("Got an error")
La clase de excepción que se especifica, en este caso, ZeroDivisionError , captura cualquier 
excepción que sea de esa clase o de cualquier subclase de esa excepción.
Por ejemplo, ZeroDivisionError es una subclase de ArithmeticError :
Y así, lo siguiente seguirá ZeroDivisionError :
Ejecutando código de limpieza con finalmente
A veces, es posible que desee que ocurra algo, independientemente de la excepción que haya 
ocurrido, por ejemplo, si tiene que limpiar algunos recursos.
Elbloquefinallydeunacláusuladetryocurriráindependientementedesi seprodujeron 
excepciones.
Estepatróna menudo se maneja mejor conlosadministradoresdecontexto (usandola
declaración with ).
Re-elevando excepciones
A veces desea capturar una excepción solo para inspeccionarla, por ejemplo, para fines de 
registro. Después de la inspección, desea que la excepción continúe propagándose como lo hizo 
antes.
En este caso, simplemente use la instrucción raise sinparámetros.
finally:
print "The END"
# it runs no matter what execute.
    406/1068
    342
try:
5 / 0
except ZeroDivisionError as e:
raise ZeroDivisionError("Got an error", e)
>>> try:
5 / 0
except ZeroDivisionError as e:
raise ValueError("Division failed") from e
Traceback (most recent call last): 
File "<stdin>", line 2, in<module>
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception: 
Traceback (most recent call last):
File "<stdin>", line 4, in <module> 
ValueError: Division failed
Sin embargo, tenga en cuenta que alguien que se encuentre más arriba en la pila de personas 
que llaman todavía puede detectar la excepción y manejarla de alguna manera. La salida 
realizada podría ser una molestia en este caso porque ocurrirá en cualquier caso (capturado o no 
capturado). Por lo tanto, podría ser una mejor idea plantear una excepción diferente, que 
contenga su comentario sobre la situación, así como la excepción original:
Pero esto tiene el inconveniente de reducir la traza de excepción exactamente a este raise
mientras que la raise sin argumento conserva la traza de excepción original. 
EnPython 3 puedes mantenerla pila original usando la sintaxis de raise -from :
Cadena de excepciones con aumento de
En el proceso de manejar una excepción, es posible que desee plantear otra excepción. Por 
ejemplo, si obtiene un IOError mientras lee un archivo, es posible que desee plantear un error 
específico de la aplicación para que se presente a los usuarios de su biblioteca.
Python 3.x 3.0
Puede encadenar excepciones para mostrar cómo procedió el manejo de las excepciones:
Jerarquía de excepciones
El manejo de excepciones se produce en función de una jerarquía de excepciones, determinada 
por la estructura de herencia de las clases de excepciones.
Por ejemplo, IOError y OSError son subclases de EnvironmentError . El código que captura un
raise ZeroDivisionError("Got an error") from e
raise
    407/1068
    343
IOError nodetectaráunOSError .Sinembargo,elcódigoqueatrapaunEnvironmentError detectará 
tanto IOError s como OSError s.
La jerarquía de las excepciones incorporadas: 
Python 2.x 2.3
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +--IOError
| | +-- OSError
| | +-- WindowsError(Windows)
| | +-- VMSError (VMS)
| +-- EOFError
| +--ImportError
| +-- LookupError
| | +-- IndexError
| | +-- KeyError
| +-- MemoryError
| +-- NameError
| | +-- UnboundLocalError
| +-- ReferenceError
| +-- RuntimeError
| | +-- NotImplementedError
| +-- SyntaxError
| | +-- IndentationError
| | +-- TabError
| +-- SystemError
| +-- TypeError
| +-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
Python 3.x 3.0
    408/1068
    344
BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIteration +-- StopAsyncIteration +-- ArithmeticError | +-- FloatingPointError | +-- OverflowError | +-- ZeroDivisionError +-- AssertionError +-- AttributeError +-- BufferError +-- EOFError +-- ImportError +-- LookupError | +-- IndexError | +-- KeyError +-- MemoryError +-- NameError | +-- UnboundLocalError +-- OSError | +-- BlockingIOError | +-- ChildProcessError | +-- ConnectionError | | +-- BrokenPipeError | | +-- ConnectionAbortedError | | +-- ConnectionRefusedError | | +-- ConnectionResetError | +-- FileExistsError | +-- FileNotFoundError | +-- InterruptedError | +-- IsADirectoryError | +-- NotADirectoryError | +-- PermissionError | +-- ProcessLookupError | +-- TimeoutError +-- ReferenceError +-- RuntimeError | +-- NotImplementedError | +-- RecursionError +-- SyntaxError | +-- IndentationError | +-- TabError +-- SystemError +-- TypeError +-- ValueError | +-- UnicodeError | +-- UnicodeDecodeError | +-- UnicodeEncodeError | +-- UnicodeTranslateError +-- Warning +-- DeprecationWarning +-- PendingDeprecationWarning +-- RuntimeWarning +-- SyntaxWarning +-- UserWarning +-- FutureWarning +-- ImportWarning +-- UnicodeWarning
    409/1068
    345
>>> def failing_function():
... raise ValueError('Example error!')
>>> failing_function()
Traceback (most recent call last): 
File "<stdin>", line 1, in<module>
File "<stdin>", line 2, in failing_function 
ValueError: Example error!
>>> try:
... failing_function()
... except ValueError:
... print('Handledtheerror') 
Handled the error
>>> try:
... failing_function()
... except ValueError as e:
... print('Caught exception', repr(e)) 
Caught exception ValueError('Example error!',)
class FooException(Exception): 
pass
try:
raise FooException("insert description here")
Las excepciones son objetos también
Las excepciones son solo objetos de Python normales que heredan de la BaseException . Una 
secuenciadecomandos dePython puede usarla instrucción raise para interrumpirla ejecución,
lo que hace que Python imprima un seguimiento de pila de la pila de llamadas en ese punto y una 
representación de la instancia de excepción. Por ejemplo:
que dice que un ValueError con el mensaje 'Example error!' fue planteado por nuestro
failing_function() , que fue ejecutado en el intérprete.
El código de llamada puede elegir manejar cualquier excepción de todo tipo que una llamada 
pueda generar:
Puede obtener los objetos de excepción asignándolos en la parte except... del código de manejo 
de excepciones:
Puede encontrar una lista completa de las excepciones de Python incorporadas junto con sus 
descripciones en la Documentación de Python: https://docs.python.org/3.5/library/exceptions.html
. Y aquí está la lista completa organizada jerárquicamente: Jerarquía de excepciones .
Creación de tipos de excepción personalizados
Crea una clase heredada de Exception :
+-- BytesWarning
+-- ResourceWarning
    410/1068
    346
class NegativeError(ValueError): 
pass
def foo(x):
# function that only accepts positive values of x 
if x < 0:
raise NegativeError("Cannot process negative numbers")
... #rest offunction body 
try:
result = foo(int(input("Enter a positive integer: "))) # raw_input inPython 2.x 
except NegativeError:
print("You entered a negative number!") 
else:
print("The result was " + str(result))
try:
very_difficult_function() 
except Exception:
# log / try to reconnect / exit gratiously 
finally:
print "The END"
# it runs no matter what execute.
try:
even_more_difficult_function() 
except:
pass # do whatever needed
u otro tipo de excepción:
No atrapes todo!
Aunque a menudo es tentador atrapar todas las Exception :
O incluso todo (que incluye BaseException y todos sus hijos, incluida la Exception ):
En la mayoría de los casos es una mala práctica. Es posible que SystemExit más de lo previsto, 
como SystemExit , KeyboardInterrupt y MemoryError , cada uno de los cuales generalmente debe 
manejarsede maneradiferentealoserroreshabituales del sistemaolalógica.Tambiénsignifica 
queno hay una comprensión clara dequépuedehacer mal el códigointerno y cómo recuperarse 
adecuadamente de esa condición.Si está detectando cada error, no sabrá qué error ocurrió o 
cómo solucionarlo.
Esto se conoce más comúnmente como "enmascaramiento de errores" y debe evitarse. Deje que 
su programa se bloquee en lugar de fallar silenciosamente o incluso peor, fallando en un nivel 
más profundo de ejecución. (Imagina que es un sistema transaccional)
Por lo general, estas construcciones se usan en el nivel más externo del programa, y registrarán 
los detalles del error para que el error se pueda corregir, o el error se pueda manejar más
except FooException:
print("A FooException was raised.")
    411/1068
    347
try:
d = {}
a = d[1]
b = d.non_existing_field
except (KeyError, AttributeError) as e:
print("A KeyError or an AttributeError exception has been caught.")
try:
d = {}
a = d[1]
b = d.non_existing_field 
except KeyError as e:
print("A KeyError has occurred. Exception message:", e) 
except AttributeError as e:
print("An AttributeError has occurred. Exception message:", e)
while True: 
try:
nb = int(input('Enter a number: ')) 
break
except ValueError:
print('This is not a number, try again.')
específicamente.
Atrapando múltiples excepciones
Hay algunas maneras de atrapar múltiples excepciones .
Laprimeraescreandounatupladelostiposdeexcepciónquedeseacapturarymanejardela 
misma manera. Este ejemplo hará que el código ignore las excepciones KeyError y AttributeError
.
Sidesea manejardiferentesexcepcionesde diferentesmaneras,puedeproporcionarunbloque 
de excepción separado para cada tipo. En este ejemplo, todavía KeyError y AttributeError , pero 
manejamos las excepciones de diferentesmaneras.
Ejemplos prácticos de manejo de excepciones.
Entrada del usuario
Imaginaquequieresqueunusuarioingreseunnúmeroatravésdeunainput .Deseaasegurarse 
de que la entrada es un número. Puedes usar try / except de esto:
Python 3.x 3.0
Nota: Python 2.x usaría raw_input en raw_input lugar; la input la función existe en Python 2.x pero 
tiene una semántica diferente. En el ejemplo anterior, la input también aceptaría expresiones 
como 2 + 2 que se evalúan como un número.
    412/1068
    348
d = [{7: 3}, {25: 9}, {38: 5}]
for i in range(len(d)): 
do_stuff(i)
try:
dic = d[i] 
i += dic[i]
except KeyError: 
i += 1
try:
data = {1: 'one', 2: 'two'} 
print(data[1])
except KeyError as e: 
print('key not found')
else:
raise ValueError() 
# Output: one
# Output: ValueError
try:
...
except ...:
...
else:
if ...:
Si la entrada no se pudo convertir en un entero, se ValueError un ValueError . Puedes atraparlo 
con except . Si se plantea no es una excepción, break salta fuera del bucle. Después del bucle, nb 
contiene un entero.
Los diccionarios
Imagine que está iterando sobre una lista de enteros consecutivos, como el range(n) , y tiene una 
lista de diccionarios d que contiene información sobre cosas que hacer cuando encuentra algunos 
enteros en particular, por ejemplo, omita los d[i] siguientes .
Se KeyError un KeyError cuando intente obtener un valor de un diccionario para una clave queno 
existe.
Más
El código en un bloque else solo se ejecutará si el código en el bloque try no genera 
excepciones.Esto es útil si tiene algún código que no desea ejecutar si selanza una excepción, 
pero no quiere que se detecten excepciones lanzadas por ese código.
Por ejemplo:
Tengaencuentaqueestetipo deelse: nosepuedecombinarcon if inicia la cláusulaelse en un 
elif.Siustedtieneunsiguienteifquenecesitaparamantenerseconsangríadebajodeesa 
else: :
    413/1068
    349
...
elif ...:
...
else:
...
    414/1068
    350
print "This line is ok"
print "This line isn't ok"
print("This line is ok") 
print("This line isn't ok")
print "This line is ok" 
print "This line isn't ok"
Capítulo 78: Excepciones del Commonwealth
Introducción
Aquí en Stack Overflow a menudo vemos duplicados que hablan de los mismos errores:
"ImportError: No module named '??????' , SyntaxError: invalid syntax o NameError: name '???' is 
not defined .Esteesunesfuerzo parareducirlos yparateneralguna documentaciónconlacual 
enlazar.
Examples
IndentationErrors (o indentation SyntaxErrors)
En la mayoría de los otros idiomas, la sangría no es obligatoria, pero en Python (y otros idiomas: 
versiones anteriores de FORTRAN, Makefiles, Whitespace (lenguaje esotérico), etc.) no es el 
caso, lo que puede ser confuso si viene de otro idioma. si estaba copiando el código de un 
ejemplo a su propio, o simplemente si es nuevo.
IndentationError / SyntaxError: sangría 
inesperada
Esta excepción se produce cuando el nivel de sangrado aumenta sin razón.
Ejemplo
No hay razón para aumentar el nivel aquí:
Python 2.x 2.0 2.7
Python 3.x 3.0
Aquí hay dos errores: el último y que la sangría no coincide con ningún nivel de sangría. Sin 
embargo solo se muestra una:
Python 2.x 2.0 2.7
    415/1068
    351
print("This line is ok") 
print("This line isn't ok")
def foo():
print "This should be part of foo()" 
print "ERROR!"
print "This is not a part of foo()"
print("This line is ok") 
print("This line isn't ok")
if ok: 
doStuff()
def foo():
pass
Python 3.x 3.0
IndentationError / SyntaxError: unindent no 
coincide con ningún nivel de sangría externa
Parece que no te diste por completo.
Ejemplo
Python 2.x 2.0 2.7
Python 3.x 3.0
Error Tabulación: Se esperaba un bloque 
tabulado
Después de dos puntos (y luego una nueva línea) el nivel de sangrado tiene que aumentar. Este 
error surge cuando eso no sucedió.
Ejemplo
Nota:Useelpasspalabraclave(quenohaceabsolutamentenada)parasimplementeponerun 
if , else , except , class , method o definition pero no diga lo que sucederá si la condición de 
llamadaes verdadera(perohágalo mástarde,oenel caso deexcept : simplementenohacer 
nada):
    416/1068
    352
def foo():
if ok:
return "Two != Four != Tab"
return "i dont care i do whatever i want"
def foo(a): return a
foo(a,b,c,d) #And a,b,c,d are defined
def foo(a,b,c,d): return a += b + c + d 
foo(a) #And a is defined
IndentationError: uso incoherente de 
tabulaciones y espacios en sangría
Ejemplo
Cómo evitar este error
No uses pestañas. Se desalienta por PEP8 , la guía de estilo para Python.
1. Configure su editor para usar 4 espacios para la sangría.
2. Haga una búsqueda y reemplace para reemplazar todas las pestañas con 4 espacios.
3. Asegúrese de que su editor esté configurado para mostrar las pestañas en 8espacios, 
para que pueda darse cuenta fácilmente de ese error y corregirlo.
Vea esta pregunta si desea aprender más.
TypeErrors
Estas excepciones se producen cuando el tipo de algún objeto debe ser diferente
TypeError: [definición / método] toma? 
argumentos posicionales pero? se le dio
Se llamó a una función o método con más (o menos) argumentos que los que puede aceptar.
Ejemplo
Si se dan más argumentos:
Si se dan menos argumentos:
    417/1068
    353
set1, tuple1 = {1,2}, (3,4) 
a = set1 + tuple1
b = 400 + 'foo'
c = ["a","b"] - [1,2]
d = 1 + 1.0
Nota : si desea usar un número desconocido de argumentos, puede usar *args o **kwargs . Ver *
args y ** kwargs
TypeError: tipo (s) de operando no 
compatibles para [operando]: '???' y '???'
Algunos tipos no se pueden operar juntos, dependiendo del operando.
Ejemplo
Por ejemplo: + se usa para concatenar y agregar, pero no puede usar ninguno de ellos para 
ambos tipos. Por ejemplo, al intentar crear un set concatenando ( + ing)'set1' y 'tuple1' el error. 
Código:
Algunos tipos (por ejemplo: int y string ) usan ambos + pero para diferentes cosas:
O puede que ni siquiera se utilicen para nada:
Pero puedes, por ejemplo, agregar un float a un int :
Error de tecleado: '???' El objeto no es 
iterable / subscriptible:
Paraqueunobjeto sea iterable,puede tomaríndices secuencialesdesdecero hasta quelos 
índices ya no sean válidos y se IndexError un IndexError (más técnicamente: debe tener un 
método iter que devuelveun iterator , o que defina un método getitem que sílo 
mencionado anteriormente).
Ejemplo
Aquí estamos diciendo que la bar es el elemento cero de 1. Tonterías:
    418/1068
    354
amount = 10
for x in amount: print(x)
foo = "notAFunction" 
foo()
foo # This variable is not defined 
bar() # This function is not defined
baz()
def baz():
pass
Esta es una versión más discreta: En este ejemplo for intenta establecer x a amount[0] , el primer 
elemento en un iterable pero no puede porque cantidad es un int:
Error de tecleado: '???' el objeto no es 
llamable
Está definiendo una variable y llamándola más tarde (como lo que hace con una función o 
método)
Ejemplo
NameError: name '???' no está definido
Se genera cuando intenta utilizar una variable, método o función que no está inicializada (al 
menos no antes). En otras palabras, se genera cuando no se encuentra un nombre local o global 
solicitado. Es posible que haya escrito mal el nombre del objeto o se haya olvidado de import 
algo. También tal vez esté en otro ámbito. Los cubriremos con ejemplos separados.
Simplemente no está definido en ninguna parte en el código
Es posible que haya olvidado inicializarlo, especialmente si es una constante.
Tal vez se define más adelante:
foo = 1
bar = foo[0]
    419/1068
    355
#needs import math
def sqrt():
x = float(input("Value: ")) 
return math.sqrt(x)
Local → Enclosed → Global → Built-in.
for i in range(4): 
d = i * 2
print(d)
def noaccess():
for i in range(4): 
d = i * 2
noaccess() 
print(d)
assert condition
O no fue import
Los alcances de Python y la Regla LEGB:
La llamada Regla de LEGB habla sobre los alcances de Python. Su nombre se basa en los 
diferentes ámbitos, ordenados por las prioridades correspondientes:
• L ocal: Variables no declaradas globalmente o asignadas en una función.
• E nclosing: Variables definidas en una función que está envuelta dentro de otra función.
• Ondoparael: Las variables declaradas globales, o asignados en el nivel superior de un 
archivo.
• B uilt-in: variables preasignadas en el módulo de nombres incorporado.
Como ejemplo:
d es accesible porque el bucle for no marca un nuevo ámbito, pero si lo hiciera, tendríamos un 
error y su comportamiento sería similar a:
Python dice NameError: name 'd' is not defined
Otros errores
AssertError
Laassert declaración existe en casi todos los lenguajes deprogramación. Cuando tulo hagas:
    420/1068
    356
div = float(raw_input("Divisors of: "))
for x in xrange(1,div+1): #includes the number itself but not zero 
if div/x == div//x:
print x, "is a divisor of", div
div = float(raw_input("Divisors of: "))
for x in xrange(div+1): #includes the number itself and zero 
if div/x == div//x:
print x, "is a divisor of", div
assert condition, message
if debug :
if not condition: raise AssertionError(message)
div = int(input("Divisors of: "))
for x in range(div+1): #includes the number itself and zero 
if div/x == div//x:
print(x, "is a divisor of", div)
o:
Es equivalente a esto:
Las aserciones pueden incluir un mensaje opcional, y puedes deshabilitarlas cuando hayas 
terminado la depuración.
Nota : la depuración de la variable incorporada es Verdadero en circunstancias normales, Falso 
cuando se solicita la optimización (opción de línea de comando -O). Las asignaciones a 
depuración son ilegales. El valor de la variable incorporada se determina cuando se inicia el 
intérprete.
Teclado interrumpir
Se produjo un error cuando el usuario presiona la tecla de interrupción, normalmente Ctrl + C o
del .
ZeroDivisionError
1/0 calcular 1/0 que no está definido. Vea este ejemplo para encontrar los divisores de un número: 
Python 2.x 2.0 2.7
Python 3.x 3.0
ZeroDivisionError porque el bucle for asigna ese valor a x . En su lugar debería ser: 
Python 2.x 2.0 2.7
    421/1068
    357
>>> print "hello world"
File "<stdin>", line 1
print "hello world"
^ 
SyntaxError: invalid syntax
div = int(input("Divisors of: "))
for x in range(1,div+1): #includes the number itself but not zero 
if div/x == div//x:
print(x, "is a divisor of", div)
def my_print(): 
x = (1 + 1
print(x)
File "<input>", line 3 
print(x)
^
SyntaxError: invalid syntax
print("hello world") # Note this is valid for both Py2 & Py3
Python 3.x 3.0
Error de sintaxis en buen código
La gran mayoría de las veces que un SyntaxError que apunta a una línea sin interés significa que 
hay un problema en la línea anterior (en este ejemplo, es un paréntesis que falta):
Devoluciones
La razón más común para este problema son paréntesis / paréntesis que no coinciden, como 
muestra el ejemplo.
Hay una advertencia importante para las declaraciones impresas en Python 3: 
Python 3.x 3.0
Debido a que la declaración de print fuereemplazada con la función print() , entonces usted 
quiere:
    422/1068
    358
import logging
logger = logging.getLogger() 
handler = logging.StreamHandler() 
formatter = logging.Formatter(
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s') 
handler.setFormatter(formatter)
logger.addHandler(handler) 
logger.setLevel(logging.DEBUG)
logger.debug('this is a %s test', 'debug')
2016-07-26 18:53:55,332 root DEBUG this is a debug test
[loggers] 
keys=root
[handlers] 
keys=stream_handler
[formatters] 
keys=formatter
[logger_root] 
level=DEBUG 
handlers=stream_handler
Capítulo 79: Explotación florestal
Examples
Introducción al registro de Python
Este módulo define funciones y clases que implementan un sistema flexible de registro de 
eventos para aplicaciones y bibliotecas.
El beneficio clave de tener la API de registro proporcionada por un módulo de biblioteca estándar 
es que todos los módulos de Python pueden participar en el registro, por lo que el registro de su 
aplicación puede incluir sus propios mensajes integrados con mensajes de módulos de terceros.
Entonces, comencemos:
Ejemplo de configuración directamente en el código
Ejemplo de salida:
Ejemplo de configuración a través de un archivo INI
Suponiendo que el archivo se llama logging_config.ini. Más detalles sobre el formato de archivo 
se encuentran en la sección de configuración de registro del tutorial de registro .
    423/1068
    359
import logging
from logging.config import fileConfig
fileConfig('logging_config.ini') 
logger = logging.getLogger()
logger.debug('often makes a very good meal of %s', 'visiting tourists')
import logging
from logging.config import dictConfig
logging_config = dict( 
version = 1, 
formatters = {
'f': {'format':
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s'}
},
handlers = {
'h': {'class':'logging.StreamHandler', 
'formatter': 'f',
'level': logging.DEBUG}
},
root = {
'handlers': ['h'], 
'level': logging.DEBUG,
},
)
dictConfig(logging_config) 
logger = logging.getLogger()
logger.debug('often makes a very good meal of %s', 'visiting tourists')
>>> import logging
>>> logging.basicConfig()
>>> try:
... raise Exception('foo')
Luego use logging.config.fileConfig() en el código:
Ejemplo de configuración a través de un diccionario
A partir de Python 2.7, puede usar un diccionario con detalles de configuración. PEP 391 contiene 
una lista de los elementos obligatorios y opcionales en el diccionario de configuración.
Excepciones de registro
Si desea registrar excepciones, puede y debe hacer uso del método logging.exception(msg) :
[handler_stream_handler] 
class=StreamHandler 
level=DEBUG 
formatter=formatter 
args=(sys.stderr,)
[formatter_formatter]
format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s
    424/1068
    360
>>> try:
... raise Exception('foo')
... except Exception as e:
... logging.exception(e)
...
ERROR:root:foo
Traceback (most recent call last): 
File "<stdin>", line 2, in<module>
Exception: foo
>>> try:
... raise Exception(u'föö')
... except Exception as e:
... logging.exception(e)
...
Traceback (most recent call last):
File "/.../python2.7/logging/ init .py", line 861, in emit 
msg = self.format(record)
File "/.../python2.7/logging/ init .py", line 734, in format 
return fmt.format(record)
File "/.../python2.7/logging/ init .py", line 469, in format 
s = self._fmt % record. dict
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-2: ordinal not in 
range(128)
Logged from file <stdin>, line 4
No pase la excepción como argumento:
Como logging.exception(msg) espera un msg arg, es un error común para aprobar la excepción en 
el registro de llamadas de esta manera:
Si bien puede parecer que esto es lo correcto al principio, en realidad es problemático debido a la 
forma en que las excepciones y las distintas codificaciones funcionan juntas en el módulo de 
registro:
Intentarregistraruna excepción que contengacaracteresUnicode,de esta manera fallará
miserablemente .Ocultaráel seguimientode piladelaexcepciónoriginal al anularlacon una 
nueva que se logging.exception(e) durante el formateo de su logging.exception(e) .
Obviamente, en su propio código, podría estar al tanto de la codificación en las excepciones. Sin 
embargo, las bibliotecas de terceros pueden manejar esto de una manera diferente.
Uso Correcto:
Si en lugar de la excepción simplemente pasa un mensaje y deja que Python haga su magia, 
funcionará:
ERROR:root:bar
Traceback (most recent call last): 
File "<stdin>", line 2, in <module>
Exception: foo
... logging.exception('bar')
...
...except:
    425/1068
    361
logging.debug('exception occurred', exc_info=1) 
logging.info('exception occurred', exc_info=1) 
logging.warning('exception occurred', exc_info=1)
>>> try:
... raise Exception(u'föö')
... except Exception as e:
... logging.exception('received this exception: %r' % e)
...
ERROR:root:received this exception: Exception(u'f\xf6\xf6',) 
Traceback (most recent call last):
File "<stdin>", line 2, in <module> 
Exception: f\xf6\xf6
Como puede ver, en realidad no usamos e en ese caso, la llamada alogging.exception(...)
formatea mágicamente la excepción más reciente.
Registro de excepciones con niveles de registro que no sean ERROR
Si desea registrar una excepción con un nivel de registro diferente al ERROR, puede usar el 
argumento exc_info de los registradores predeterminados:
Accediendo al mensaje de la excepción.
Tenga en cuenta que las bibliotecas podrían generar excepciones con los mensajes como 
Unicode o (utf-8 si tiene suerte) de cadenas de bytes. Si realmente necesita acceder a un texto de 
excepción, la única forma confiable, que siempre funcionará, es usar repr(e) o el formato de 
cadena %r :
>>> try:
... raise Exception(u'föö')
... except Exception as e:
... logging.exception('bar')
...
ERROR:root:bar
Traceback (most recent call last): 
File "<stdin>", line 2, in <module>
Exception: f\xf6\xf6
    426/1068
    362
math.sqrt(-10)
import cmath
cmath.sqrt(4) # 2+0j 
cmath.sqrt(-4) # 2j
Capítulo 80: Exposiciónción
Sintaxis
• valor1 ** valor2
• pow (valor1, valor2 [, valor3])
• value1 . pow (value2 [, value3])
• valor2 . rpow (valor1)
• operator.pow (valor1, valor2)
• operador . pow (valor1, valor2)
• math.pow (value1, value2)
• math.sqrt (valor1)
• math.exp (value1)
• cmath.exp (valor1)
• math.expm1 (value1)
Examples
Raíz cuadrada: math.sqrt () y cmath.sqrt
Elmódulo math contienelafunción math.sqrt()quepuedecalcularlaraízcuadradadecualquier 
número (que se puede convertir en un float ) y el resultado siempre será un float :
import math
math.sqrt(9) # 3.0
math.sqrt(11.11) # 3.3331666624997918
math.sqrt(Decimal('6.25')) # 2.5
La función math.sqrt() genera un ValueError si el resultado seríacomplex :
ValueError: error de dominio matemático
math.sqrt(x) es más rápido que math.pow(x, 0.5) o x ** 0.5 pero la precisión de los resultados es 
lamisma.El módulocmathesextremadamentesimilaral módulo math ,exceptoporelhechode 
quepuede calcular números complejos y todos sus resultados tienen la formade a+bi.También 
puede usar .sqrt() :
¿Quépasaconlaj?jeselequivalentealaraízcuadradade-1.Todoslosnúmerossepueden
    427/1068
    363
pow(2, 3) # 8
2 ** 3 # 8
2 ** -3
# Out: 0.125 (result is a float)
(-2) ** (0.5) # also (-2.) ** (0.5)
# Out: (8.659560562354934e-17+1.4142135623730951j) (result is complex)
operator. pow (4, 3) # 64
# 16
import operator 
operator.pow(4, 2)
# in-place power operation isn't supported by immutable classes like int, float, complex: 
# val1. ipow (val2)
# 16
# 16
val1, val2 = 4, 2 
val1. pow (val2)
val2. rpow (val1)
poner en la forma a+ bi, o en este caso, a+ bj. a es la parte real del número como el 2 en 2+0j . 
Comonotieneunaparteimaginaria,bes0.brepresentapartedelaparteimaginariadelnúmero 
como el 2 en 2j . Como no hay una parte real en esto, 2j también puede escribirse como 0 + 2j .
Exposiciónción utilizando builtins: ** y pow ()
Exponenciación se puede utilizar mediante el uso de la orden interna pow -Función o el **
operador:
Para la mayoría de las operaciones aritméticas (todas en Python 2.x), el tipo de resultado será el 
del operando más amplio. Esto no es cierto para ** ; Los siguientes casos son excepciones a esta 
regla:
• Base: int , exponente: int < 0 :
• Esto también es válido para Python 3.x.
• Antes de Python 2.2.0, esto ValueError un ValueError .
• Base: int < 0 o float < 0 , exponente: float !=int
• Antes de Python 3.0.0, esto ValueError un ValueError .
El módulo operator contiene dos funciones que son equivalentes al operador ** :
o uno podría llamar directamente al método pow :
Exposiciónción utilizando el módulo matemático: math.pow ()
El módulo math contiene otra función math.pow() . La diferencia con el operador incorporado pow() -
    428/1068
    364
import math
math.pow(2, 2) # 4.0
math.pow(-2., 2) # 4.0
math.pow(2, 2+0j)
function o ** es que el resultado es siempre un float :
Lo que excluye los cálculos con entradas complejas:
TypeError: no se puede convertir complejo a flotar 
y cálculos que conducirían a resultados complejos:
ValueError: error de dominio matemático
Función exponencial: math.exp () y cmath.exp ()
Tanto el módulo math como el módulo cmath contienen el número de Euler: e, y usarlo con la 
función pow() incorporada o el operador ** funciona principalmente como math.exp() :
import math
math.e ** 2 # 7.3890560989306495
math.exp(2) # 7.38905609893065
import cmath 
cmath.e ** 2 # 7.3890560989306495
cmath.exp(2) # (7.38905609893065+0j)
Sinembargo,elresultadoesdiferente yusarlafunciónexponencial directamente es más 
confiable que la exponenciación math.e con base math.e :
print(math.e ** 10) # 22026.465794806703
print(math.exp(10)) # 22026.465794806718
print(cmath.exp(10).real) 
# difference starts he
#
re
22026.465794806718
------------------- ^
Función exponencial menos 1: math.expm1 ()
El módulo math contiene la función expm1() que puede calcular la expresión math.e ** x - 1 para x
muy pequeña con mayor precisión que math.exp(x) o cmath.exp(x) permitiría:
import math
print(math.e ** 1e-3 - 1) # 0.0010005001667083846
print(math.exp(1e-3) - 1) # 0.0010005001667083846
print(math.expm1(1e-3)) 
#
# 0.0010005001667083417
------------------^
math.pow(-2, 0.5)
    429/1068
    365
print(math.e ** 1e-15 - 1) # 1.1102230246251565e-15 
print(math.exp(1e-15) - 1) # 1.1102230246251565e-15
print(math.expm1(1e-15)) # 1.0000000000000007e-15 
# ^-------------------
def planks_law(lambda_, T):
from scipy.constants import h, k, c # If no scipy installed hardcode these! 
return 2 * h * c ** 2 / (lambda_ ** 5 * math.expm1(h * c / (lambda_ * k * T)))
def planks_law_naive(lambda_, T):
from scipy.constants import h, k, c # If no scipy installed hardcode these! 
return 2 * h * c ** 2 / (lambda_ ** 5 * (math.e ** (h * c / (lambda_ * k * T)) - 1))
planks_law(100, 5000) # 4.139080074896474e-19
planks_law_naive(100, 5000) # 4.139080073488451e-19 
# ^----------
planks_law(1000, 5000) # 4.139080128493406e-23
planks_law_naive(1000, 5000) # 4.139080233183142e-23 
# ^------------
class Integer(object):
def init (self, value):
self.value = int(value) # Cast to an integer
def repr (self):
return '{cls}({val})'.format(cls=self. class . name ,
val=self.value)
def pow (self, other, modulo=None): 
if modulo is None:
print('Using pow ')
return self. class (self.value ** other) 
else:
print('Using pow with modulo')
return self. class (pow(self.value, other, modulo))
def float (self): 
print('Using float ') 
return float(self.value)
def complex (self): 
print('Using complex ') 
return complex(self.value, 0)
Para x muy pequeño la diferencia se hace más grande:
La mejora es significativa en la computación científica. Por ejemplo, la ley de Planck contiene una 
función exponencial menos 1:
Métodos mágicos y exponenciales: incorporados, matemáticos y 
matemáticos.
Suponiendo que tienes una clase que almacena valores puramente enteros:
Usando la función pow incorporada o el operador ** siempre llama a pow :
    430/1068
    366
# Prints: Using pow with modulo
Integer(2). pow (3, 4) # Integer(0)
# Prints: Using pow with modulo
pow(Integer(2), 3, 4) # Integer(0)
import math
math.pow(Integer(2), 0.5) # 1.4142135623730951 
# Prints: Using float
# Prints: Using complex
del Integer. complex # Deleting complex method - instances cannot be cast to complex 
cmath.exp(Integer(2)) # (7.38905609893065+0j)
# Prints: Using float
# (7.38905609893065+0j)
import cmath
cmath.exp(Integer(2))
del Integer. float # Deleting complex method
math.sqrt(Integer(2)) # also cmath.exp(Integer(2))
pow(3, 4, 17) # 13
El segundo argumento del método pow () solo se puede suministrar usando la función 
builtinpow pow() o llamando directamente al método:
Mientras que las funciones math siempre lo convierten en un float y usan el cálculo de flotación:
cmath funciones intentan convertirlo en complex pero también pueden retroceder a float si no hay 
una conversión explícita a complex :
Ni math ni cmath funcionarán si también float () el float () :
TypeError: se requiere un flotador
Exponenciación modular: pow () con 3 argumentos.
Al suministrar pow() con 3 argumentos pow(a, b, c) evalúa la exponenciación modular a b mod c :
operator. pow (Integer(3), 3) # Integer(27) 
# Prints: Using pow
# Integer(8)
# Integer(1)
# Integer(5)
Integer(2) ** 2 # Integer(4)
# Prints: Using pow
Integer(2) ** 2.5
# Prints: Using pow
pow(Integer(2), 0.5)
# Prints: Using pow
operator.pow(Integer(2), 3)
# Prints: Using pow
    431/1068
    367
def modular_inverse(x, p):
"""Find a such as a·x ≡ 1 (mod p), assuming p is prime.""" 
return pow(x, p-2, p)
[modular_inverse(x, 13) for x in range(1,13)] 
# Out: [1, 7, 9, 10, 8, 11, 2, 5, 3, 4, 6, 12]
>>> x = 3
>>> y = x ** 3
>>> y 
27
>>> z = y ** (1.0 / 3)
>>> z 
3.0
>>> z == x
True
x = 2 ** 100 
cube = x ** 3
Para los tipos incorporados, el uso de exponenciación modular solo es posible si:
• El primer argumento es unint
• El segundo argumento es un int >= 0
• El tercer argumento es un int != 0
Estas restricciones también están presentes en Python 3.x
Por ejemplo, uno puede usar la forma de 3 argumentos de pow para definir una función inversa
modular :
Raíces: raíz nth con exponentes fraccionarios
Si bien la función math.sqrt se proporciona para el caso específico de raíces cuadradas, a 
menudo es conveniente usar el operador de exponenciación ( ** ) con exponentes fraccionarios 
para realizar operaciones de raíz nth, como las raíces cúbicas.
La inversa de una exponenciación es la exponenciación por el recíproco del exponente. Entonces, 
si puedes calcular un número colocándolo en el exponente de 3, puedes encontrar la raíz cúbica 
de un número poniéndolo en el exponente de 1/3.
Cálculo de grandes raíces enteras
A pesar de que Python admite de forma nativa grandes enteros, tomar la raíz n de números muy 
grandes puede fallar en Python.
# 81
# 13
# steps: 
3 ** 4
81 % 17
# equivalent unoptimized expression: 
3 ** 4 % 17 # 13
    432/1068
    368
def nth_root(x, n):
# Start with some reasonable bounds around the nth root. 
upper_bound = 1
while upper_bound ** n <= x: 
upper_bound *= 2
lower_bound = upper_bound // 2
# Keep searching for a better result as long as the bounds make sense. 
while lower_bound < upper_bound:
mid = (lower_bound + upper_bound) // 2 
mid_nth = mid ** n
if lower_bound < mid and mid_nth < x: 
lower_bound = mid
elif upper_bound > mid and mid_nth > x: 
upper_bound = mid
else:
# Found perfect nth root. 
return mid
return mid + 1
x = 2 ** 100 
cube = x ** 3
root = nth_root(cube, 3) 
x == root
# True
OverflowError: largo int demasiado grande para convertirlo en flotante
Cuando trate con enteros tan grandes, necesitará usar una función personalizada para calcular la 
enésima raíz de un número.
root = cube ** (1.0 /3)
    433/1068
    369
Capítulo 81: Expresiones Regulares (Regex)
Introducción
Python hace que las expresiones regulares estén disponibles a través del módulo re .
Lasexpresiones regularessoncombinacionesdecaracteresqueseinterpretancomoreglaspara 
hacer coincidir subcadenas. Por ejemplo, la expresión 'amount\D+\d+' coincidirá con cualquier 
cadenacompuestaporlaamountpalabramásunnúmerointegral,separadosporunoomásno 
dígitos, como: amount=100 , amount is 3 , amount is equal to: 33 , etc.
Sintaxis
• Expresiones regulares directas
• re.match (patrón, cadena, marca = 0) # Fuera: coincide con el patrón al principio de la 
cadena o Ninguno
• re.search (patrón, cadena, marca = 0) # Fuera: coincide con el patrón dentro de la cadena o 
Ninguno
• re.findall (pattern, string, flag = 0) # Out: lista de todas las coincidencias de pattern en string 
o []
• re.finditer (patrón, cadena, flag = 0) # Out: igual que re.findall, pero devuelve el objeto 
iterador
• re.sub (patrón, reemplazo, cadena, marca = 0) # Out: cadena con reemplazo (cadena o 
función) en lugar de patrón
• Expresiones regulares precompiladas
• precompiled_pattern = re.compile (patrón, flag = 0)
• precompiled_pattern.match (string) # Out: coincide al principio de string o Ninguno
• precompiled_pattern.search (string) # Out: coincide en cualquier lugar con string o None
• precompiled_pattern.findall (string) # Out: lista de todas las subcadenas coincidentes
• precompiled_pattern.sub (cadena / patrón / función, cadena) # Fuera: cadena reemplazada
Examples
Coincidiendo con el comienzo de una cadena
El primer argumento de re.match() es la expresión regular, el segundo es la cadena que debe
    434/1068
    370
import re
pattern = r"123" 
string = "123zzb"
re.match(pattern, string)
# Out: <_sre.SRE_Match object; span=(0, 3), match='123'> 
match = re.match(pattern, string)
match.group() 
# Out: '123'
# matches '\\t123'
pattern = r"\\t123"
re.match(pattern, string).group()
string = "\\t123zzb" # here the backslash is escaped, so there's no tab, just '\' and 't' 
pattern = "\\t123" # this will match \t (escaping the backslash) followed by 123 
re.match(pattern, string).group() # no match
re.match(pattern, "\t123zzb").group() # matches '\t123'
match = re.match(r"(123)", "a123zzb")
match is None 
# Out: True
match = re.search(r"(123)", "a123zzb") 
match.group()
# Out: '123'
coincidir:
Puede observar que la variable de patrón es una cadena con el prefijo r , que indica que la 
cadena es un literal de cadena sin formato.
Una cadena prima literal tiene una sintaxis ligeramente diferente de una cadena literal, es decir, 
una barra invertida \ en un medio literal de cadena en bruto "sólo una barra invertida" y no hay 
necesidad de duplicar los juegos de escapar "secuencias de escape", tales como saltos de línea (
\n),tabulaciones(\t),espaciosenblanco(\),feedsdeformularios(\r),etc.Enlosliterales 
decadena normales, cada barrainvertida debeduplicarse paraevitarque se tome como el inicio 
de una secuencia deescape.
Por lo tanto, r"\n" es una cadena de 2 caracteres: \ y n . Los patrones Regex también usan 
barras invertidas, por ejemplo, \d refiere a cualquier carácter dedígito.Podemos evitartenerque 
doble escape de nuestras cadenas ( "\\d" ) mediante el uso de cadenas sin formato (r"\d" ).
Por ejemplo:
Lacoincidenciase realizadesde el principiodelacadena solamente.Siquieres hacer coincidiren 
cualquier lugar, usa re.search en re.search lugar:
    435/1068
    371
pattern = r"(your base)"
sentence = "All your base are belong to us."
match = re.search(pattern, sentence) 
match.group(1)
# Out: 'your base'
match = re.search(r"(belong.*)", sentence) 
match.group(1)
# Out: 'belong to us.'
match = re.search(r"^123", "123zzb") 
match.group(0)
# Out: '123'
match = re.search(r"^123", "a123zzb") 
match is None
# Out: True
match = re.search(r"123$", "zzb123") 
match.group(0)
# Out: '123'
match = re.search(r"123$", "123zzb") 
match is None
# Out: True
match = re.search(r"^123$", "123") 
match.group(0)
# Out: '123'
match.group() # Group without argument returns the entire match found 
# Out: '123'
match.group(0) # Specifying 0 gives the same result as specifying no argument 
# Out: '123'
buscando
Labúsquedaserealizaencualquierpartedelacadenaadiferenciadere.match .También 
puedes usar re.findall .
También puede buscar al principio de la cadena (use ^ ),
al final de la cadena (use $ ),
o ambos (use ambos ^ y $ ):
Agrupamiento
La agrupación se realiza entre paréntesis. El group() llamada group() devuelve una cadena 
formada por los subgrupos paréntesis coincidentes.
    436/1068
    372
# Out: ('phone', '672-123-456-9910')
m.group(1, 2) # Multiple arguments give us a tuple.
# Out: '672-123-456-9910'
m.group(2) # The second parenthesized subgroup.
m.group(1) # The first parenthesized subgroup.
# Out: 'phone'
# Out: 'This is a phone number 672-123-456-9910'
m.group(0) # The entire match as a string
# Out: 'This is a phone number 672-123-456-9910'
m.group() # The entire match as a string
sentence= "Thisis a phonenumber 672-123-456-9910" 
pattern = r".*(phone).*?([\d-]+)"
match = re.match(pattern, sentence)
match.groups() # The entire match as a list of tuples of the paranthesized subgroups 
# Out: ('phone', '672-123-456-9910')
match = re.search(r'My name is (?P<name>[A-Za-z ]+)', 'My name is John Smith') 
match.group('name')
# Out: 'John Smith'
match.group(1)
# Out: 'John Smith'
re.match(r'(\d+)(\+(\d+))?', '11+22').groups() 
# Out: ('11', '+22', '22')
También se pueden proporcionar argumentos a group() para obtener un subgrupo en particular. 
De la documentación :
Si hay un solo argumento, el resultado es una sola cadena; Si hay varios argumentos, 
el resultado es una tupla con un elemento por argumento.
Al llamar a groups() por otro lado, devuelve una lista de tuplas que contienen los subgrupos.
Grupos nombrados
Crea un grupo de captura al que se puede hacer referencia por nombre y por índice.
Grupos no capturadores
Usar (?:) crea un grupo, pero el grupo no se captura. Esto significa que puede usarlo como 
grupo, pero no contaminará su "espacio grupal".
    437/1068
    373
match = re.search(r'[b]', 'a[b]c') 
match.group()
# Out: 'b'
match = re.search(r'\[b\]', 'a[b]c') 
match.group()
# Out: '[b]'
re.escape('a[b]c')
# Out: 'a\\[b\\]c'
match = re.search(re.escape('a[b]c'), 'a[b]c') 
match.group()
# Out: 'a[b]c'
username = 'A.C.' # suppose this came from the user 
re.findall(r'Hi {}!'.format(username), 'Hi A.C.! Hi ABCD!') 
# Out: ['Hi A.C.!', 'Hi ABCD!']
re.findall(r'Hi {}!'.format(re.escape(username)), 'Hi A.C.! Hi ABCD!') 
# Out: ['Hi A.C.!']
re.sub(r"t[0-9][0-9]", "foo", "my name t13 is t44 what t99 ever t44") 
# Out: 'my name foo is foo what foo ever foo'
Este ejemplo coincide con 11+22 u 11 , pero no con 11+ . Esto se debe a que el signo + y el 
segundo término están agrupados. Por otro lado, el signo + no es capturado.
Escapar de personajes especiales
Loscaracteresespeciales(comoloscorchetesdelaclasedecaracteres[ y] continuación)nose 
corresponden literalmente:
Al escapar de los caracteres especiales, pueden emparejarse literalmente:
La función re.escape() se puede utilizar para hacer esto por usted:
La función re.escape() escapa a todos los caracteres especiales, por lo que es útil si está 
componiendo una expresión regular basada en la entrada del usuario:
Reemplazo
Los reemplazos se pueden hacer en cadenas usando re.sub .
Reemplazo de cuerdas
re.match(r'(\d+)(?:\+(\d+))?', '11+22').groups() 
# Out: ('11', '22')
    438/1068
    374
re.sub(r"t([0-9])([0-9])", r"t\2\1", "t13 t19 t81 t25") 
# Out: 't31 t91 t18 t52'
re.sub(r"t([0-9])([0-9])", r"t\g<2>\g<1>", "t13 t19 t81 t25") 
# Out: 't31 t91 t18 t52'
items = ["zero", "one", "two"]
re.sub(r"a\[([0-3])\]", lambda match: items[int(match.group(1))], "Items: a[0], a[1], 
something, a[2]")
# Out: 'Items: zero, one, something, two'
re.findall(r"[0-9]{2,3}", "some 1 text 12 is 945 here 4445588899")
# Out: ['12', '945', '444', '558', '889']
results = re.finditer(r"([0-9]{2,3})", "some 1 text 12 is 945 here 4445588899") 
print(results)
# Out: <callable-iterator object at 0x105245890> 
for result in results:
print(result.group(0)) 
''' Out:
12
945
444
558
889 
'''
import re
Usando referencias de grupo
Los reemplazos con un pequeño número de grupos se pueden hacer de la siguiente manera:
Sin embargo, si crea una ID de grupo como '10', esto no funciona : \10 se lee como 'ID número 1 
seguido de 0'. Por lo tanto, debe ser más específico y usar la notación \g<i> :
Usando una función de reemplazo
Encontrar todos los partidos no superpuestos
Tengaencuentaquelarantesde "[0-9]{2,3}" lediceapythonqueinterpretelacadenacomo 
está; como una cadena "sinprocesar".
Tambiénpuedeusarre.finditer()quefunciona dela misma manera quere.findall() pero 
devuelve uniterador con objetos SRE_Match lugar de una lista de cadenas:
Patrones precompilados
    439/1068
    375
import re
precompiled_pattern = re.compile(r"(.*\d+)")
matches = precompiled_pattern.match("The answer is 41!") 
print(matches.group(1))
# Out: The answer is 41
matches = precompiled_pattern.match("Or was it 42?") 
print(matches.group(1))
# Out: Or was it 42
import re
def is_allowed(string):
characherRegex = re.compile(r'[^a-zA-Z0-9.]') 
string = characherRegex.search(string)
return not bool(string)
print (is_allowed("abyzABYZ0099")) 
# Out: 'True'
print (is_allowed("#*@#$%^")) 
# Out: 'False'
La compilación de un patrón permite su reutilización posterior en un programa. Sin embargo, 
tenga en cuenta que Python almacena en caché las expresiones utilizadas recientemente ( docs , 
SO answer ), por lo que "los programas que usan solo unas pocas expresiones regulares a la vez 
no tienen que preocuparse de compilar expresiones regulares" .
Se puede utilizar con re.match ().
Comprobación de caracteres permitidos
Si desea comprobar que una cadena contiene solo un determinado conjunto de caracteres, en 
este caso az, AZ y 0-9, puede hacerlo así:
También puede adaptar la línea de expresión de [^a-zA-Z0-9.] [^a-z0-9.] , Por ejemplo, para no 
permitir letras en mayúsculas.
Crédito parcial: http://stackoverflow.com/a/1325265/2697955
Dividir una cadena usando expresiones regulares
También puedes usar expresiones regulares para dividir una cadena. Por ejemplo,
precompiled_pattern = re.compile(r"(\d+)")
matches = precompiled_pattern.search("The answer is 41!") 
matches.group(1)
# Out: 41
matches = precompiled_pattern.search("Or was it 42?") 
matches.group(1)
# Out: 42
    440/1068
    376
m = re.search("b", "ABC") 
m is None
# Out: True
m = re.search("b", "ABC", flags=re.IGNORECASE) 
m.group()
# Out: 'B'
m =re.search("a.b", "A\nBC", flags=re.IGNORECASE) 
m is None
# Out: True
m = re.search("a.b", "A\nBC", flags=re.IGNORECASE|re.DOTALL) 
m.group()
# Out: 'A\nB'
Banderas
Para algunos casos especiales, necesitamos cambiar el comportamiento de la Expresión regular, 
esto se hace usando indicadores. Los indicadores se pueden establecer de dos maneras, a través 
de la palabra clave de flags o directamente en la expresión.
Bandera de palabras clave
Debajo de un ejemplo para re.search pero funciona para la mayoría de las funciones en el módulo
re .
Banderas comunes
Bandera Breve descripción
re.IGNORECASE ,re.I Hace que el patrón ignore el caso.
re.DOTALL , re.S Hace . combina todo, incluyendo nuevas líneas
re.MULTILINE , re.M Hace ^ coincida con el comienzo de una línea y $ el final de una línea
re.DEBUG Activa la información de depuración
Para la lista completa de todas las banderas disponibles verifique los documentos
Banderas en linea
De la documentación :
(?iLmsux)
import re
data = re.split(r'\s+', 'James 94 Samantha 417 Scarlett 74') 
print( data )
# Output: ['James', '94', 'Samantha', '417', 'Scarlett', '74']
    441/1068
    377
import re
text = 'You can try to find anant in this string'
pattern = 'an?\w' # find 'an' either with or without a following word character
for match in re.finditer(pattern, text): 
# Start index of match (integer) 
sStart = match.start()
# Final index of match (integer) 
sEnd = match.end()
# Complete match (string) 
sGroup = match.group()
# Print match
print('Match "{}" found at: [{},{}]'.format(sGroup, sStart,sEnd))
Match "an" found at: [5,7] 
Match "an" found at: [20,22] 
Match "ant" found at: [23,26]
An apple a day keeps the doctor away (I eat an apple everyday).
(Una o más letras del conjunto 'i', 'L', 'm', 's', 'u', 'x'.)
El grupo coincide con la cadena vacía; las letras establecen los indicadores 
correspondientes: re.I (ignorar mayúsculas y minúsculas), re.L (dependiente del 
entorno local), re.M (multilínea), re.S (punto corresponde a todos), re.U (dependiente 
de Unicode) y re.X (verbose), para toda la expresión regular. Esto es útil si desea 
incluir las banderas como parte de la expresión regular, en lugar de pasar un 
argumento de bandera a la función re.compile ().
Tenga en cuenta que el indicador (? X) cambia la forma en que se analiza la 
expresión. Debe usarse primero en la cadena de expresión o después de uno o más 
caracteres de espacio en blanco. Si hay caracteres que no son espacios en blanco 
antes de la bandera, los resultados no están definidos.
Iterando sobre los partidos usando `re.finditer`
Puede usar re.finditer para iterar sobre todas las coincidencias en una cadena. Esto le 
proporciona (en comparación con re.findall información adicional, como información sobre la 
ubicación de coincidencia en la cadena (índices):
Resultado:
Unir una expresión solo en lugares específicos
A menudo, usted quiere hacer coincidir una expresión solo en lugares específicos (dejándolos 
intactos en otros, es decir). Considera la siguiente oración:
Aquí, la "manzana" aparece dos veces, lo que se puede resolver con los llamados verbos de
    442/1068
    378
import regex as re
string = "An apple a day keeps the doctor away (I eat an apple everyday)." 
rx = re.compile(r'''
\([^()]*\) (*SKIP)(*FAIL) # match anything in parentheses and "throw it away"
| # or
apple # match an apple
''', re.VERBOSE)
apples = rx.findall(string) 
print(apples)
# only one
forget_this | or this | and this as well | (but keepthis)
control de seguimiento inverso que son compatibles con el módulo de regex más nuevo. La idea 
es:
Con nuestro ejemplo de manzana, esto sería:
Esto coincide con "manzana" solo cuando se puede encontrar fuera de los paréntesis. 
Así es como funciona:
• Mientras miradeizquierda a derecha ,el motorde expresiones regulares consume todoa 
la izquierda, (*SKIP) actúa como una "afirmación de siempre verdadera". Después, falla 
correctamente en (*FAIL) y retrocede.
• Ahora llega al punto de (*SKIP) de derecha a izquierda (también conocido como retroceso) 
en el que está prohibido ir más hacia la izquierda. En su lugar, se le dice al motor que tire 
cualquier cosa a la izquierda y salte al punto donde se invocó (*SKIP) .
    443/1068
    379
#include <Python.h> 
#include <stdio.h>
#if PY_MAJOR_VERSION >= 3
#define IS_PY3K 
#endif
static PyObject *hello_greet(PyObject *self, PyObject *args)
{
const char *input;
if (!PyArg_ParseTuple(args, "s", &input)) {
return NULL;
}
printf("%s", input); 
Py_RETURN_NONE;
}
static PyMethodDef HelloMethods[] = {
{ "greet", hello_greet, METH_VARARGS, "Greet the user" },
{ NULL, NULL, 0, NULL }
};
#ifdef IS_PY3K
static struct PyModuleDef hellomodule = { 
PyModuleDef_HEAD_INIT, "hello", NULL, -1, HelloMethods
};
PyMODINIT_FUNC PyInit_hello(void)
{
return PyModule_Create(&hellomodule);
}
#else
PyMODINIT_FUNC inithello(void)
{
(void) Py_InitModule("hello", HelloMethods);
}
#endif
Capítulo 82: Extensiones de escritura
Examples
Hola mundo con extensión C
ElsiguientearchivofuentedeC(quellamaremoshello.c parapropósitosdedemostración) 
produceunmódulodeextensiónllamadohello quecontieneunafunciónsimplegreet() :
Para compilar el archivo con el compilador gcc , ejecute el siguiente comando en su terminal 
favorito:
gcc /path/to/your/file/hello.c -o /path/to/your/file/hello
Paraejecutarlafuncióngreet()queescribimosanteriormente,creeunarchivoenelmismo 
directorio y hello.py
    444/1068
    380
PyObject *fobj;
int fd = PyObject_AsFileDescriptor(fobj); 
if (fd < 0){
return NULL;
}
int fd; /* Existing file descriptor */
PyObject *fobj = PyFile_FromFd(fd, "filename","r",-1,NULL,NULL,NULL,1);
#include <boost/python/module.hpp> 
#include <boost/python/list.hpp> 
#include <boost/python/class.hpp> 
#include <boost/python/def.hpp>
// Return a hello world string. 
std::string get_hello_function()
{
return "Hello world!";
}
// hello classthat can return a list of count hello world strings. 
class hello_class
{
public:
// Taking the greeting message in the constructor. 
hello_class(std::string message) : _message(message) {}
// Returns the message count times in a python list. 
boost::python::list as_list(int count)
{
Pasando un archivo abierto a C Extensions
Pase un objeto de archivo abierto de Python a código de extensión C.
Puede convertir el archivo a un descriptor de archivo entero usando la función
PyObject_AsFileDescriptor :
Para convertir un descriptor de archivo entero de nuevo en un objeto de Python, use PyFile_FromFd
.
Extensión C usando c ++ y Boost
Este es un ejemplo básico de una extensión C que usa C ++ y Boost .
Código C ++
Código C ++ puesto en hello.cpp:
hello.greet("Hello!") # runs the greet() function with "Hello!" as an argument
import hello # imports the compiled library
    445/1068
    381
sudo apt-get install gcc libboost-dev libpython3.4-dev
gcc -shared -o hello.so -fPIC -I/usr/include/python3.4 hello.cpp -lboost_python-py34 -
lboost_system -l:libpython3.4m.so
import hello 
print(hello.get_hello())
h = hello.Hello("World hello!") 
print(h.as_list(3))
Hello world!
['World hello!', 'World hello!', 'World hello!']
Para compilar esto en un módulo de python, necesitarás los encabezados de python y las 
bibliotecas boost. Este ejemplo se hizo en Ubuntu 12.04 usando python 3.4 y gcc. Boost es 
compatible con muchas plataformas. En el caso de Ubuntu, los paquetes necesarios se instalaron 
usando:
Compilando el archivo fuente en un archivo .so que luego se puede importar como un módulo 
siempre que esté en la ruta de acceso de python:
El código de python en el archivo example.py:
Entonces python3 example.py dará el siguiente resultado:
boost::python::list res;
for (int i = 0; i < count; ++i) { 
res.append(_message);
}
return res;
}
private:
std::string _message;
};
// Defining a python module naming it to "hello". 
BOOST_PYTHON_MODULE(hello)
{
// Here you declare what functions and classes that should be exposed on the module.
// The get_hello_function exposed to python as a function. 
boost::python::def("get_hello", get_hello_function);
// The hello_class exposed to python as a class. 
boost::python::class_<hello_class>("Hello", boost::python::init<std::string>())
.def("as_list", &hello_class::as_list)
;
}
    446/1068
    382
escritura
    447/1068
    383
import datetime
dt = datetime.datetime.strptime("2016-04-15T08:27:18-0500", "%Y-%m-%dT%H:%M:%S%z")
import dateutil.parser
dt = dateutil.parser.parse("2016-04-15T08:27:18-0500")
datetime.datetime(2016, 4, 15, 8, 27, 18, tzinfo=tzoffset(None, -18000))
import datetime
today = datetime.date.today() 
print('Today:', today)
yesterday = today - datetime.timedelta(days=1) 
print('Yesterday:', yesterday)
tomorrow = today + datetime.timedelta(days=1) 
print('Tomorrow:', tomorrow)
Capítulo 83: Fecha y hora
Observaciones
Python proporciona métodos integrados y bibliotecas externas para crear, modificar, analizar y 
manipular fechas y horas.
Examples
Análisis de una cadena en un objeto de fecha y hora compatible con la zona 
horaria
Python 3.2+ admite el formato %z al analizar una cadena en un objeto de datetime y datetime .
+HHMM UTC en la forma +HHMM o -HHMM (cadena vacía si el objeto es ingenuo).
Python 3.x 3.2
ParaotrasversionesdePython,puedeusarunabibliotecaexternacomodateutil,quehaceque 
el análisis de una cadena con zona horaria en un objeto de datetime y datetime sea rápido.
La variable dt ahora es un objeto de datetime y datetime con el siguiente valor:
Aritmética de fecha simple
Las fechas no existen de forma aislada. Es común que necesite encontrar la cantidad de tiempo 
entre las fechas o determinar cuál será la fecha de mañana. Esto se puede lograr usando objetos
timedelta
    448/1068
    384
Today: 2016-04-15
Yesterday: 2016-04-14
Tomorrow: 2016-04-16
Difference between tomorrow and yesterday: 2 days, 0:00:00
import datetime
# Date object
today = datetime.date.today()
new_year = datetime.date(2017, 01, 01) #datetime.date(2017, 1, 1)
# Time object
noon = datetime.time(12, 0, 0) #datetime.time(12, 0)
# Current datetime
now = datetime.datetime.now()
# Datetime object
millenium_turn = datetime.datetime(2000, 1, 1, 0, 0, 0) #datetime.datetime(2000, 1, 1, 0, 0)
# subtraction of noon from today 
noon-today
Traceback (most recent call last): 
File "<stdin>", line 1, in<module>
TypeError:unsupportedoperandtype(s)for-:'datetime.time' and'datetime.date' 
However, it is straightforward to convert between types.
# Do this instead
print('Time since the millenium at midnight: ',
datetime.datetime(today.year, today.month, today.day) - millenium_turn)
# Or this
print('Time since the millenium at noon: ', 
datetime.datetime.combine(today, noon) - millenium_turn)
import datetime
Esto producirá resultados similares a:
Uso básico de objetos datetime
El módulo datetime contiene tres tipos principales de objetos: fecha, hora y fecha y hora.
Las operaciones aritméticas para estos objetos solo se admiten dentro del mismo tipo de datos y 
realizar una aritmética simple con instancias de diferentes tipos resultará en un error de tipo.
Iterar sobre fechas
Aveces desea iterar en un rango de fechas desde una fecha de inicio hasta una fecha de 
finalización. Puedes hacerlo usando la biblioteca datetime y el objeto timedelta :
print('Time between tomorrow and yesterday:', tomorrow - yesterday)
    449/1068
    385
2016-07-21
2016-07-22
2016-07-23
2016-07-24
2016-07-25
2016-07-26
2016-07-27
from dateutil import tz
from dateutil.parser import parse
ET = tz.gettz('US/Eastern') 
CT = tz.gettz('US/Central') 
MT = tz.gettz('US/Mountain') 
PT = tz.gettz('US/Pacific')
us_tzinfos = {'CST': CT, 'CDT': CT,
'EST': ET, 'EDT': ET,
'MST': MT, 'MDT': MT,
'PST': PT, 'PDT': PT}
dt_est = parse('2014-01-02 04:00:00 EST', tzinfos=us_tzinfos) 
dt_pst = parse('2016-03-11 16:00:00 PST', tzinfos=us_tzinfos)
dt_est
# datetime.datetime(2014, 1, 2, 4, 0, tzinfo=tzfile('/usr/share/zoneinfo/US/Eastern')) 
dt_pst
Lo que produce:
Analizar una cadena con un nombre de zona horaria corto en un objeto de 
fecha y hora con fecha horaria
Al usar la biblioteca dateutil como en el ejemplo anterior en el análisis de las marcas de tiempo
dateutil en la zona horaria , también es posible analizar las marcas de tiempo con un nombre de 
zona horaria "corto" especificado.
Para fechas formateadas con nombres de zonas horarias cortas o abreviaturas, que 
generalmente son ambiguas (p. Ej., CST, que podrían ser la Hora estándar central, la Hora 
estándar de China, la Hora estándar de Cuba, etc.) o puede encontrar más información aquí o no 
necesariamente están disponibles en una base de datos estándar , es necesario especificar una 
asignación entre la abreviatura de zona horaria y el objeto tzinfo .
Después de ejecutar esto:
# The size of each step in days 
day_delta = datetime.timedelta(days=1)
start_date = datetime.date.today() 
end_date = start_date + 7*day_delta
for i in range((end_date - start_date).days): 
print(start_date + i*day_delta)
    450/1068
    386
from dateutil.parser import parse 
import pytz
EST = pytz.timezone('America/New_York')
dt = parse('2014-02-03 09:17:00 EST', tzinfos={'EST': EST})
dt.tzinfo # Will be in Local Mean Time!
# <DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>
dt_fixed = dt.tzinfo.localize(dt.replace(tzinfo=None)) 
dt_fixed.tzinfo # Now it's EST.
# <DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)
from datetime import datetime, timedelta, timezone 
JST = timezone(timedelta(hours=+9))
dt = datetime(2015, 1, 1, 12, 0, 0, tzinfo=JST) 
print(dt)
# 2015-01-01 12:00:00+09:00
print(dt.tzname()) 
# UTC+09:00
dt = datetime(2015, 1, 1, 12, 0, 0, tzinfo=timezone(timedelta(hours=9), 'JST')) 
print(dt.tzname)
# 'JST'
Vale la pena señalar que si utiliza una zona horaria de pytz con este método, no se localizará 
correctamente:
Esto simplemente adjunta la zona horaria de pytz a la fecha y hora:
Siutilizaestemétodo,probablementedeberíavolveralocalize laparteingenuadelafechay 
hora después del análisis:
Construyendo tiempos de datos conscientes de la zona horaria
Por defecto, todos los objetos de datetime y datetime son ingenuos. Para que sean conscientes de 
la zona horaria, debe adjuntar un objeto tzinfo , que proporciona el desplazamiento UTC y la 
abreviatura de la zona horaria en función de la fecha y la hora.
Zonas horarias de compensación
Para las zonas horarias que son un desplazamiento fijo de UTC, en Python 3.2+, el módulo 
datetime proporciona la clase de timezone , una implementación concreta de tzinfo , que toma un 
timedelta y un parámetro de nombre (opcional):
Python 3.x 3.2
Para versiones de Python anteriores a 3.2, es necesario usar una biblioteca de terceros, como
# datetime.datetime(2016, 3, 11, 16, 0, tzinfo=tzfile('/usr/share/zoneinfo/US/Pacific'))
    451/1068
    387
from datetime import datetime, timedelta 
from dateutil import tz
JST = tz.tzoffset('JST', 9 * 3600) # 3600 seconds per hour 
dt = datetime(2015, 1, 1, 12, 0, tzinfo=JST)
print(dt)
# 2015-01-01 12:00:00+09:00
print(dt.tzname) 
# 'JST'
from datetime import datetime 
from dateutil import tz
local = tz.gettz() # Local time
PT = tz.gettz('US/Pacific') # Pacific time
dt_l = datetime(2015, 1, 1, 12, tzinfo=local) # I am in EST 
dt_pst = datetime(2015, 1, 1, 12, tzinfo=PT)
dt_pdt = datetime(2015, 7, 1, 12, tzinfo=PT) # DST is handled automatically 
print(dt_l)
# 2015-01-01 12:00:00-05:00
print(dt_pst)
# 2015-01-01 12:00:00-08:00
print(dt_pdt)
# 2015-07-01 12:00:00-07:00
from datetime import datetime, timedelta
dateutil. dateutilproporciona unaclaseequivalente, tzoffset, que(apartir delaversión 2.5.3) 
toma argumentos de la forma dateutil.tz.tzoffset(tzname, offset) , donde el offset se especifica
en segundos:
Python 3.x 3.2
Python 2.x 2.7
Zonas con horario de verano.
Para las zonas con horario de verano, las bibliotecas estándar de Python no proporcionan una 
clase estándar, por lo que es necesario utilizar una biblioteca de terceros. pytz y dateutil son 
bibliotecas populares que proporcionan clases de zona horaria.
Además de las zonas horarias estáticas, dateutil proporciona clases de zonas dateutil que 
utilizan el horario de verano (consulte la documentación del módulo tz ).Puede usar el método 
tz.gettz()para obtener un objeto de zona horaria, que luego se puede pasar directamente al 
constructor de datetime :
PRECAUCIÓN : A partir de la versión 2.5.3, dateutil no maneja dateutil ambiguos 
correctamente, ysiempreseestableceráde formapredeterminadaenlafechaposterior.Nohay 
formadeconstruir unobjetoconunadateutilrepresente lazona horaria,porejemplo, 2015-11-01 
1:30 EDT-4 , ya que esto es durante una transición de horario deverano.
Todosloscasosdebordesemanejan correctamente cuandoseusapytz , perolas zonas 
horariasdepytz nosedebenpytzdirectamentealaszonashorariasa travésdel constructor.En 
su lugar, se debe adjuntar una zona horaria de pytz usando el método de localize la zona horaria:
    452/1068
    388
dt_new = dt_pdt + timedelta(hours=3) # This should be 2:30 AM PST
print(dt_new)
# 2015-11-01 03:30:00-07:00
dt_corrected = PT.normalize(dt_new) 
print(dt_corrected)
# 2015-11-01 02:30:00-08:00
from dateutil.parser import parse
dt = parse("Today isJanuary 1, 2047 at 8:21:00AM",fuzzy=True) 
print(dt)
from datetime import datetime 
from dateutil import tz
utc = tz.tzutc() 
local = tz.tzlocal()
utc_now = datetime.utcnow() 
utc_now # Not timezone-aware.
utc_now = utc_now.replace(tzinfo=utc) 
utc_now # Timezone-aware.
local_now = utc_now.astimezone(local) 
local_now # Converted to local time.
Tenga en cuenta que si realiza aritmética de fecha y hora en una pytz horaria de pytz -aware, 
debe realizarlos cálculos en UTC (si desea un tiempo transcurrido absoluto), o debe llamar a 
normalize() en el resultado:
Análisis de fecha y hora difuso (extracción de fecha y hora de un texto)
Es posible extraer una fecha de un texto usando el analizador de dateutil en un modo "borroso", 
donde los componentes de la cadena que no se reconocen como parte de una fecha se ignoran.
dt ahora es un objeto datetime y vería datetime.datetime(2047, 1, 1, 8, 21) impreso.
Cambio entre zonas horarias
Para cambiar entre zonas horarias, necesita objetos de fecha y hora que tengan en cuenta la 
zona horaria.
import pytz
PT = pytz.timezone('US/Pacific')
dt_pst = PT.localize(datetime(2015, 1, 1, 12))
dt_pdt = PT.localize(datetime(2015, 11, 1, 0, 30)) 
print(dt_pst)
# 2015-01-01 12:00:00-08:00
print(dt_pdt)
# 2015-11-01 00:30:00-07:00
    453/1068
    389
str(datetime.datetime(2016, 7, 22, 9, 25, 59, 555555))
# '2016-07-22 09:25:59.555555'
str(datetime.datetime(2016, 7, 22, 9, 25, 59, 0))
# '2016-07-22 09:25:59'
import iso8601
iso8601.parse_date('2016-07-22 09:25:59')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
iso8601.parse_date('2016-07-22 09:25:59+03:00')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<FixedOffset '+03:00' ...>) 
iso8601.parse_date('2016-07-22 09:25:59Z')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>) 
iso8601.parse_date('2016-07-22T09:25:59.000111+03:00')
# datetime.datetime(2016, 7, 22, 9, 25, 59, 111, tzinfo=<FixedOffset '+03:00' ...>)
iso8601.parse_date('2016-07-22T09:25:59', default_timezone=None) 
# datetime.datetime(2016, 7, 22, 9, 25, 59) iso8601.parse_date('2016-
07-22T09:25:59Z', default_timezone=None) # 
datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
Análisis de una marca de tiempo ISO 8601 arbitraria con bibliotecas mínimas
Python solo tiene soporte limitado para analizar las marcas de tiempo ISO 8601. Para strptime 
necesitasaberexactamenteenquéformatoseencuentra.Comocomplicación,laclasificaciónde 
una datetime y datetime es una marca de tiempo ISO 8601, con espacio como separador y 
fracción de 6 dígitos:
pero si la fracción es 0, no se genera ninguna parte fraccionaria
Peroestas2formasnecesitanunformatodiferenteparastrptime.Además,strptime'doesnot 
support at all parsing minute timezones that have a : in it, thus can be parsed, but the standard 
format2016-07-2209:25:59+0300canbeparsed,butthestandardformat2016-07-2209:25:59
+03: 00` no puedo.
Hay una biblioteca de un solo archivo llamada iso8601 que analiza correctamente las marcas de 
tiempo ISO 8601 y solo ellas.
Admite fracciones y zonas horarias, y el separador en T todo con una sola función:
Si no se establece una zona horaria, iso8601.parse_date se establece de iso8601.parse_date 
predeterminadaenUTC.Lazonapredeterminadasepuedecambiar conel argumentodepalabra 
clave default_zone . En particular, si esto es None lugar del predeterminado, entonces las marcas
de tiempo que no tienen una zona horaria explícita se devuelven como tiempos de referencia
ingenuos:
Convertir la marca de tiempo a datetime
El módulo datetime puede convertir una timestamp de timestamp POSIX en un objeto datetime ITC.
    454/1068
    390
import time
from datetime import datetime 
seconds_since_epoch=time.time() #1469182681.709
utc_date=datetime.utcfromtimestamp(seconds_since_epoch) #datetime.datetime(2016, 7, 22, 10,
18, 1, 709000)
import calendar
from datetime import date
def monthdelta(date, delta):
m, y = (date.month+delta) % 12, date.year + ((date.month)+delta-1) // 12 
if not m: m = 12
d = min(date.day, calendar.monthrange(y, m)[1]) 
return date.replace(day=d,month=m, year=y)
next_month = monthdelta(date.today(), 1) #datetime.date(2016, 10, 23)
import datetime
import dateutil.relativedelta
d = datetime.datetime.strptime("2013-03-31", "%Y-%m-%d")
d2 = d - dateutil.relativedelta.relativedelta(months=1) #datetime.datetime(2013, 2, 28, 0, 0)
from datetime import datetime, timedelta 
now = datetime.now()
then = datetime(2016, 5, 23) # datetime.datetime(2016, 05, 23, 0, 0, 0)
delta = now-then
print(delta.days) 
# 60
print(delta.seconds) 
# 40826
La época es el 1 de enero de 1970 a medianoche.
Restar meses de una fecha con precisión
Usando el módulo de calendar
Usando el módulo dateutils
Calcular las diferencias de tiempo
timedelta módulo timedelta es útil para calcular las diferencias entre los tiempos:
Especificar el tiempo es opcional al crear un nuevo objeto de datetime
delta es de tipo timedelta
Para obtener n día después y n día antes de la fecha podríamos usar:
    455/1068
    391
def get_n_days_after_date(date_format="%d %B %Y", add_days=120):
date_n_days_after = datetime.datetime.now() + timedelta(days=add_days) 
return date_n_days_after.strftime(date_format)
def get_n_days_before_date(self, date_format="%d %B %Y", days_before=120):
date_n_days_ago = datetime.datetime.now() - timedelta(days=days_before) 
return date_n_days_ago.strftime(date_format)
from datetime import datetime
datetime.now().isoformat()
# Out: '2016-07-31T23:08:20.886783'
from datetime import datetime 
from dateutil.tz import tzlocal
datetime.now(tzlocal()).isoformat()
# Out: '2016-07-31T23:09:43.535074-07:00'
from datetime import datetime 
from dateutil.tz import tzlocal
datetime.now(tzlocal()).replace(microsecond=0).isoformat() 
# Out: '2016-07-31T23:10:30-07:00'
día después de la fecha:
n día anterior a la fecha:
Obtener una marca de tiempo ISO 8601
Sin zona horaria, con microsegundos.
Con zona horaria, con microsegundos.
Con zona horaria, sin microsegundos.
Consulte ISO 8601 para obtener más información sobre el formato ISO 8601.
    456/1068
    392
names = ['Fred', 'Wilma', 'Barney']
def long_name(name): 
return len(name) > 5
filter(long_name, names) 
# Out: ['Barney']
[name for name in names if len(name) > 5] # equivalent list comprehension 
# Out: ['Barney']
from itertools import ifilter
ifilter(long_name, names) # as generator (similar to python 3.x filter builtin)
Capítulo 84: Filtrar
Sintaxis
• filtro (función, iterable)
• itertools.ifilter (función, iterable)
• future_builtins.filter (función, iterable)
• itertools.ifilterfalse (función, iterable)
• itertools.filterfalse (función, iterable)
Parámetros
Parámetro Detalles
función llamable que determina la condición o None luego use la función de identidad 
para el filtrado ( solo de posición )
iterable iterable que será filtrado ( solo posicional )
Observaciones
Enla mayoríadelos casos, una expresión de comprensióno generador es más legible, más 
potente y más eficiente que filter() o ifilter() .
Examples
Uso básico del filtro.
Para filter descartan elementos de una secuencia en función de algunos criterios:
Python 2.x 2.0
    457/1068
    393
# Besides the options for older python 2.x versions there is a future_builtin function: 
from future_builtins import filter
filter(long_name, names) # identical to itertools.ifilter 
# Out: <itertools.ifilter at 0x3eb0ba8>
# Out: <filter at 0x1fc6e443470> 
list(filter(long_name, names)) # cast to list 
# Out: ['Barney']
(name for name in names if len(name) > 5) # equivalent generator expression 
# Out: <generator object <genexpr> at 0x000001C6F49BF4C0>
filter(long_name, names) # returns a generator
list(filter(None, [1, 0, 2, [], '', 'a'])) # discards 0, [] and ''
# Out: [1, 2, 'a']
[i for i in [1, 0, 2, [], '', 'a'] if i] # equivalent list comprehension
(i for i in [1, 0, 2, [], '', 'a'] if i) # equivalent generator expression
#notrecommendedin real use but keepsthe example short: 
from itertools import ifilter as filter
from future_builtins import filter
Python 2.x 2.6
Python 3.x 3.0
Filtro sin función
Si el parámetro de la función es None , se utilizará la función de identidad:
Python 2.x 2.0.1
Python 3.x 3.0.0
Filtrar como comprobación de cortocircuito.
filter(3.xpitón)yifilter(Python2.x)devuelveungenerador,asíquepuedesermuyútil 
cuando se crea un ensayo de cortocircuito como or o and :
Python 2.x 2.0.1
Python 2.x 2.6.1
# Out: <itertools.ifilter at 0x4197e10>
list(ifilter(long_name, names)) # equivalent to filter with lists 
# Out: ['Barney']
(name for name in names if len(name) > 5) # equivalent generator expression 
# Out: <generator object <genexpr> at 0x0000000003FD5D38>
    458/1068
    394
# not recommended in real use but keepsthe example valid for python 2.x and python 3.x 
from itertools import ifilterfalse as filterfalse
car_shop = [('Toyota', 1000), ('rectangular tire', 80), ('Porsche', 5000)] 
def find_something_smaller_than(name_value_tuple):
print('Check {0}, {1}$'.format(*name_value_tuple) 
return name_value_tuple[1] < 100
next(filter(find_something_smaller_than, car_shop)) 
# Print: Check Toyota, 1000$
# Check rectangular tire,80$ 
# Out: ('rectangular tire', 80)
from itertools import filterfalse
# Usage without function (None):
list(filterfalse(None, [1, 0, 2, [], '', 'a'])) # discards 1, 2, 'a' 
# Out: [0, [], '']
# Usage with function
names = ['Fred', 'Wilma', 'Barney']
def long_name(name): 
return len(name) > 5
list(filterfalse(long_name, names)) 
# Out: ['Fred', 'Wilma']
# Short-circuit useage with next:
car_shop = [('Toyota', 1000), ('rectangular tire', 80), ('Porsche', 5000)] 
def find_something_smaller_than(name_value_tuple):
print('Check {0}, {1}$'.format(*name_value_tuple) 
return name_value_tuple[1] < 100
next(filterfalse(find_something_smaller_than, car_shop)) 
# Print: Check Toyota, 1000$
# Out: ('Toyota', 1000)
Para encontrar el primer elemento que es más pequeño que 100:
La next función proporciona el siguiente elemento (en este caso, primero) y es, por lo tanto, la 
razón por la que es un cortocircuito.
Función complementaria: filterfalse, ifilterfalse
Hayunafuncióncomplementaria para el filter en elmódulo itertools : 
Python 2.x 2.0.1
Python 3.x 3.0.0
quefuncionaexactamenteigualqueelfilter delgeneradorperomantienesololoselementos 
que son False :
    459/1068
    395
# Using an equivalent generator:
car_shop = [('Toyota', 1000), ('rectangular tire', 80), ('Porsche', 5000)] 
generator = (car for car in car_shop if not car[1] < 100)
next(generator)
    460/1068
    396
foo = 1
bar = 'bar' 
baz = 3.14
print('{}, {} and {}'.format(foo, bar, baz)) 
# Out: "1, bar and 3.14"
print('{0}, {1}, {2}, and {1}'.format(foo, bar, baz))
Capítulo 85: Formato de cadena
Introducción
Cuando se almacenan y transforman datos para que los humanos los vean, el formato de cadena 
puede ser muy importante. Python ofrece una amplia variedad de métodos de formato de 
cadenas que se describen en este tema.
Sintaxis
• "{}". formato (42) ==> "42"
• "{0}". Formato (42) ==> "42"
• "{0: .2f}". Formato (42) ==> "42.00"
• "{0: .0f}". Formato (42.1234) ==> "42"
• "{answer}". formato (no_answer = 41, respuesta = 42) ==> "42"
• "{answer: .2f}". format (no_answer = 41, answer = 42) ==> "42.00"
• "{[clave]}". formato ({'clave': 'valor'}) ==> "valor"
• "{[1]}". Formato (['cero', 'uno', 'dos']) ==> "uno"
• "{answer} = {answer}". formato (respuesta = 42) ==> "42 = 42"
• '' .join (['stack', 'overflow']) ==> "stack overflow"
Observaciones
• Debería visitar PyFormat.info para una introducción / explicación muy completa y suave de 
cómo funciona.
Examples
Conceptos básicos de formato de cadena
Puedes usar str.format para formatear la salida. Los pares de corchetes se reemplazan con 
argumentos en el orden en que se pasan los argumentos:
Los índices también se pueden especificar dentro de los corchetes. Los números corresponden a 
los índices de los argumentos pasados a la función str.format (basado en 0).
    461/1068
    397
print("X value is: {x_val}. Y value is: {y_val}.".format(x_val=2, y_val=3)) 
# Out: "X value is: 2. Y value is: 3."
class AssignValue(object): 
def init (self, value):
self.value = value 
my_value=AssignValue(6)
print('My value is: {0.value}'.format(my_value)) # "0" is optional 
# Out: "My value is: 6"
my_dict = {'key': 6, 'other_key': 7}
print("My other keyis: {0[other_key]}".format(my_dict)) # "0" is optional 
# Out: "My other key is: 7"
my_list = ['zero', 'one', 'two']
print("2nd element is: {0[2]}".format(my_list)) # "0" is optional 
# Out: "2nd element is: two"
'{:~^20}'.format('centered')
# Out: '~~~~~~centered~~~~~~'
t = (12, 45, 22222, 103, 6)
print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*t)
# Out: 12 22222 45 22222 103 22222 6 22222
Los argumentos con nombre también se pueden utilizar:
Se puede hacer referencia a los atributos de los objetos cuando se pasan a str.format :
Las claves del diccionario se pueden utilizar también:
Lo mismo se aplica a los índices de lista y tupla:
Nota: Además de str.format , Python también proporciona el operador de módulo % 
también conocido como operador de formateo o interpolación de cadenas (ver PEP
3101 ), para el formato de cadenas. str.format es un sucesor de % y ofrece una mayor 
flexibilidad, por ejemplo, al facilitar la realización de múltiples sustituciones.
Además de los índices de argumentos, también puede incluir una especificación de formato 
dentro de los corchetes. Esta es una expresión que sigue reglas especiales y debe ser precedido 
por dos puntos ( : ). Consulte la documentación para obtener una descripción completa de la 
especificación de formato. Un ejemplo de especificación de formato es la directiva de alineación
:~^20 ( ^ significa alineación central, ancho total 20, relleno con ~ carácter):
format permite un comportamiento no posible con % , por ejemplo, la repetición de argumentos:
# Out: "1, bar, 3.14, and bar"
print('{0}, {1}, {2}, and {3}'.format(foo, bar, baz)) 
# Out: index out of range error
    462/1068
    398
number_list = [12,45,78]
print map('the number is {}'.format, number_list)
#Out:['the numberis 12', 'the numberis 45', 'the numberis 78']
from datetime import datetime,timedelta
once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0) 
delta = timedelta(days=13, hours=8, minutes=20)
gen = (once_upon_a_time + x * delta for x in xrange(5)) 
print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))
'{:~<9s}, World'.format('Hello') 
# 'Hello~~~~, World'
'{:~>9s}, World'.format('Hello') 
# '~~~~Hello, World'
'{:~^9s}'.format('Hello') 
# '~~Hello~~'
'{:0=6d}'.format(-123) 
# '-00123'
Como el format es una función, se puede usar como un argumento en otras funciones:
#Out: 2010-07-01 12:00:00
# 2010-07-14 20:20:00
# 2010-07-28 04:40:00
# 2010-08-10 13:00:00
# 2010-08-23 21:20:00
Alineación y relleno.
Python 2.x 2.6
El métodoformat() sepuedeusarparacambiarlaalineación delacadena. Tienesquehacerlo 
con una expresión de formato del formulario :[fill_char][align_operator][width] donde 
align_operator es uno de los siguientes:
• < obliga al campo aalinearse ala izquierda dentrodel width .
• > obliga al campoa alinearse aladerechadentro del width .
• ^ obliga al campo a centrarse dentro de la width .
• = obliga a que el relleno se coloque después del signo (solo tipos numéricos).
fill_char (si se omite, el valor predeterminado es el espacio en blanco) es el carácter utilizado 
para el relleno.
Nota: puede obtener los mismos resultados utilizando las funciones de cadena ljust() , rjust() ,
center() , zfill() , sin embargo, estas funciones están en desuso desde la versión 2.5.
Formato literales (f-string)
    463/1068
    399
>>> foo = 'bar'
>>> f'Foo is {foo}' 
'Foo is bar'
>>> f'{foo:^7s}' 
' bar '
>>> price = 478.23
>>> f"{f'${price:0.2f}':*>20s}" 
'*************$478.23'
>>> def fn(l, incr):
... result = l[0]
... l[0] += incr
... return result
...
>>> lst = [0]
>>>f'{fn(lst,2)}{fn(lst,3)}' 
'0 2'
>>>f'{fn(lst,2)}{fn(lst,3)}' 
'5 7'
>>> lst 
[10]
>>> from datetime import datetime
>>> 'North America: {dt:%m/%d/%Y}. ISO: {dt:%Y-%m-%d}.'.format(dt=datetime.now()) 
'North America: 07/21/2016. ISO: 2016-07-21.'
Las cadenas de formato literal se introdujeron en PEP 498 (Python3.6 y versiones posteriores), lo 
que le permite anteponer f al comienzo de un literal de cadena para aplicar efectivamente el
.format con todas las variables en el alcance actual.
Esto también funciona con cadenas de formato más avanzadas, incluida la alineación y la 
notación de puntos.
Nota:Laf''nodenotauntipoparticularcomob''parabytes ouu''paraunicode enpython2.El 
formateo se aplica inmediatamente, lo que resulta en una agitación normal.
Las cadenas de formato también se pueden anidar :
Las expresiones en una cadena-f se evalúan en orden de izquierda a derecha. Esto es detectable 
solo si las expresiones tienen efectos secundarios:
Formato de cadena con fecha y hora
Cualquier clase puede configurar su propia sintaxis de formato de cadena a través del método
 format .UntipoenlabibliotecaestándardePythonquehaceunusoprácticodeestoesel 
tipo datetime , donde se pueden usar códigos de formato similares a strftime directamente dentro 
de str.format :
Se puede encontrar una lista completa de la lista de formateadores de fecha y hora en la
    464/1068
    400
person = {'first': 'Arthur', 'last': 'Dent'}
'{p[first]} {p[last]}'.format(p=person) 
# 'Arthur Dent'
class Person(object): 
first = 'Zaphod' 
last = 'Beeblebrox'
'{p.first} {p.last}'.format(p=Person()) 
# 'Zaphod Beeblebrox'
>>> '{0:.0f}'.format(42.12345) 
'42'
>>> '{0:.1f}'.format(42.12345) 
'42.1'
>>> '{0:.3f}'.format(42.12345) 
'42.123'
>>> '{0:.5f}'.format(42.12345) 
'42.12345'
>>> '{0:.7f}'.format(42.12345) 
'42.1234500'
>>>'{:.3f}'.format(42.12345) 
'42.123'
>>>'{answer:.3f}'.format(answer=42.12345) 
'42.123'
>>> '{0:.3e}'.format(42.12345) 
'4.212e+01'
>>> '{0:.0%}'.format(42.12345) 
'4212%'
documentación oficial .
Formato utilizando Getitem y Getattr
Cualquier estructura de datos que admita getitem puede tener su estructura anidada 
formateada:
A los atributos de los objetos se puede acceder usando getattr() :
Formato flotante
Lo mismo vale para otra forma de referenciar:
Los números de punto flotante también se pueden formatear en notación científica o como 
porcentajes:
    465/1068
    401
>>> s = 'Hello'
>>> a, b, c = 1.12345, 2.34567, 34.5678
>>> digits = 2
>>> '{0}! {1:.{n}f}, {2:.{n}f}, {3:.{n}f}'.format(s, a, b, c, n=digits) 
'Hello! 1.12, 2.35, 34.57'
>>> '{0:x}'.format(10) # base 16, lowercase - Hexadecimal 
'a'
>>> '{0:X}'.format(10) # base 16, uppercase - Hexadecimal 
'A'
>>> '{:o}'.format(10) # base 8 - Octal 
'12'
>>> '{:b}'.format(10) # base 2 - Binary 
'1010'
>>> '{0:#b}, {0:#o}, {0:#x}'.format(42) # With prefix 
'0b101010, 0o52, 0x2a'
>>> '8 bit: {0:08b}; Three bytes: {0:06x}'.format(42) # Add zero padding 
'8 bit: 00101010; Three bytes: 00002a'
>>> r, g, b = (1.0, 0.4, 0.0)
>>> '#{:02X}{:02X}{:02X}'.format(int(255 * r), int(255 * g), int(255 * b)) 
'#FF6600'
>>> '{:x}'.format(42.0)
Traceback (most recent call last): 
File "<stdin>", line 1, in<module>
También puede combinar las notaciones {0} y {name} . Esto es especialmente útil cuando desea 
redondear todas las variables a un número de decimales preespecificado con 1 declaración :
Formato de valores numéricos
El método .format() puede interpretar un número en diferentes formatos, tales como:
>>> '{:c}'.format(65) 
'A'
# Unicode character
>>> '{:d}'.format(0x0a) 
'10'
# base 10
>>> '{:n}'.format(0x0a) 
'10'
# base 10 using current locale for separators
Formato de enteros a diferentes bases (hex, oct, binario)
Use el formato para convertir una tupla flotante RGB en una cadena hexadecimal de color:
Solo se pueden convertir enteros:
    466/1068
    402
object. format (self, format_spec)
# Example in Python 2 - but can be easily applied to Python 3
class Example(object): 
def init (self,a,b,c):
self.a, self.b, self.c = a,b,c
def format (self, format_spec):
""" Implement special semantics for the 's' format specifier """ 
# Reject anything that isn't an s
if format_spec[-1] != 's':
raise ValueError('{} format specifier not understood for this object', 
format_spec[:-1])
# Output in this example will be (<a>,<b>,<c>)
raw = "(" + ",".join([str(self.a), str(self.b), str(self.c)]) + ")" 
# Honor the format language by using the inbuilt string format
# Since we know the original format_spec ends in an 's'
# we can take advantage of the str.format method with a 
# string argument we constructed above
return "{r:{f}}".format( r=raw, f=format_spec )
inst = Example(1,2,3)
print "{0:>20s}".format(inst) 
# out : (1,2,3)
# Note how the right align and field width of 20 has been honored.
Formato personalizado para una clase
Nota:
Todo lo siguiente se aplica al método str.format , así como a la función de format . En 
el texto de abajo, los dos sonintercambiables.
Para cada valor que se pasa a la función de format , Python busca un método format para ese 
argumento. Por lo tanto, su propia clase personalizada puede tener su propio método format 
para determinar cómo la función de format mostrará y formateará su clase y sus atributos.
Esto es diferente al método str , ya que en el método format puede tener en cuenta el 
idioma del formato, incluida la alineación, el ancho del campo, etc. e incluso (si lo desea) 
implementar sus propios especificadores de formato y sus propias extensiones de lenguaje de 
formato. 1
Por ejemplo :
Nota:
Si su clase personalizada no tiene un método format personalizado y se format
una instancia de la clase a la función de format , Python2 siempre usará el valor de 
retorno del método str o el método repr para determinar qué imprimir (y si no
ValueError: Unknown format code 'x' for object of type 'float'
    467/1068
    403
>>> '{:.>10}'.format('foo')
'.......foo'
>>>'{:.>{}}'.format('foo',10) 
'....... foo'
'{:{}{}{}}'.format('foo', '*', '^', 15) 
'******foo******'
>>> data = ["a", "bbbbbbb", "ccc"]
>>> m = max(map(len, data))
>>> for d in data:
... print('{:>{}}'.format(d, m)) 
a
bbbbbbb
ccc
existe ninguno, entonces se utilizará la repr predeterminada), y deberá usar el 
especificador de formato s para formatearesto.ConPython3 , para pasar su clase 
personalizada a la función de format , necesitará definir el método format en su 
clase personalizada.
Formateo anidado
Algunos formatos pueden tomar parámetros adicionales, como el ancho de la cadena con formato 
o la alineación:
También se pueden proporcionar como parámetros para format anidando más {} dentro de {} :
Enelúltimo ejemplo,la cadenade formato'{:{}{}{}}'se modificaa '{:*^15}'(esdecir,"centroy 
pad con * a una longitud total de 15") antes de aplicarla a la cadena real 'foo' para ser 
formateada de esa manera.
Esto puede ser útil en casos en que los parámetros no se conocen de antemano, por ejemplo al 
alinear datos tabulares:
Acolchado y cuerdas truncantes, combinadas.
Digamos que quieres imprimir variables en una columna de 3 caracteres. 
Nota: doblando { y } se les escapa.
:{a:>3.3}:
:{a:3.3}:
combined
{{:>3.3}}
{{:3.3}}
:{e:.3}:
truncate
{{:.3}}
:{a:3}:
s = """
pad
{{:3}}
    468/1068
    404
>>> data = {'first': 'Hodor', 'last': 'Hodor!'}
>>> '{first} {last}'.format(**data) 
'Hodor Hodor!'
>>> '{first} {last}'.format_map(data) 
'Hodor Hodor!'
>>> '{first} {last}'.format(first='Hodor', last='Hodor!') 
'Hodor Hodor!'
Salida:
pad
{:3} :1 :
truncate
{:.3} :555:
combined
{:>3.3} : 1:
{:3.3} :1 :
{:3.3} :333:
{:3.3} :555:
Marcadores de posición nombrados
Las cadenas de formato pueden contener marcadores de posición con nombre que se interpolan 
usando argumentos de palabras clave para dar format .
Usando un diccionario (Python 2.x)
Usando un diccionario (Python 3.2+)
str.format_map permiteusardiccionariossintenerquedescomprimirlosprimero.Tambiénseusa 
la clase de data (que podría ser un tipo personalizado) en lugar de un dict recién llenado.
Sin un diccionario:
print (s.format(a="1"*1, c="3"*3, e="5"*5))
:{c:3.3}:
:{e:3.3}:
{{:3.3}}
{{:3.3}}
"""
    469/1068
    405
from datetime import datetime
a = datetime(2016,10,06,0,0,0) 
b =datetime(2016,10,01,23,59,59)
a-b
# datetime.timedelta(4, 1)
(a-b).days 
# 4
(a-b).total_seconds() 
# 518399.0
from datetime import datetime 
datetime_string = 'Oct 1 2016, 00:00:00'
datetime_string_format = '%b %d %Y, %H:%M:%S' 
datetime.strptime(datetime_string, datetime_string_format) 
# datetime.datetime(2016, 10, 1, 0, 0)
from datetime import datetime 
datetime_for_string = datetime(2016,10,1,0,0) 
datetime_string_format = '%b %d %Y, %H:%M:%S'
datetime.strftime(datetime_for_string,datetime_string_format) 
# Oct 01 2016, 00:00:00
Capítulo 86: Formato de fecha
Examples
Tiempo entre dos fechas
Analizando la cadena al objeto datetime
Utiliza códigos de formato estándar C
Salida de objetos de fecha y hora a cadena
Utiliza códigos de formato estándar C
    470/1068
    406
list(map(abs, [-1,-2,-3])) # [1, 2,3]
[abs(i) for i in [-1,-2,-3]] # [1, 2, 3]
import operator 
alist = [1,2,3]
list(map(operator.add, alist, alist)) # [2, 4, 6] 
[i + j for i, j in zip(alist, alist)] # [2, 4,6]
Capítulo 87: Función de mapa
Sintaxis
• mapa (función, iterable [, * additional_iterables])
• future_builtins.map (función, iterable [, * additional_iterables])
• itertools.imap (función, iterable [, * additional_iterables])
Parámetros
Parámetro Detalles
función función de mapeo (debe tomar tantos parámetros como haya iterables) 
( solo de posición )
iterable la función se aplica a cada elemento de lo iterable ( solo posicional )
*
vea iterable, pero tantos como desee ( opcional , solo posicional ) adicional_iterables
Observaciones
Todo lo que se puede hacer con el map también se puede hacer con comprehensions :
Aunque necesitarías zip si tienes múltiples iterables:
Las comprensiones de listas son eficientes y pueden ser más rápidas que el map en muchos 
casos, así que pruebe los tiempos de ambos enfoques si la velocidad es importante para usted.
Examples
Uso básico de map, itertools.imap y future_builtins.map
La función de mapa es la más simple entre las incorporaciones de Python utilizadas para la 
programación funcional. map() aplica una función específica a cada elemento en un iterable:
    471/1068
    407
map(len, names) # map() returns a list 
# Out: [4, 5, 6]
from itertools import imap
imap(len, names) # itertools.imap() returns a generator 
# Out: <itertools.imap at 0x405ea20>
from future_builtins import map # contains a Python 3.x compatible map() 
map(len, names) # see below
# Out: <itertools.imap instance at 0x3eb0a20>
map(len, names) # map in Python 3.x is a class; its instances are iterable 
# Out: <map object at 0x00000198B32E2CF8>
list(map(len, names)) 
# Out: [4, 5, 6]
[len(item) for item in names] # equivalent to Python 2.x map() 
# Out: [4, 5, 6]
(len(item) for item in names) # equivalent to Python 3.x map() 
# Out: <generator object <genexpr> at 0x00000195888D5FC0>
list(map(abs, (1, -1, 2, -2, 3, -3))) # the call to `list` is unnecessary in 2.x
# Out: [1, 1, 2, 2, 3, 3]
map(lambda x:x*2, [1, 2, 3, 4, 5])
# Out: [2, 4, 6, 8, 10]
Python 3.x 3.0
Seincluyeun map compatibleconPython3enel módulofuture_builtins: 
Python 2.x 2.6
Alternativamente, en Python 2 se puede usar imap de itertools para obtener un generador 
Python 2.x 2.3
Elresultadosepuedeconvertirexplícitamenteenunalist paraeliminarlasdiferenciasentre 
Python 2 y 3:
map() puede reemplazarse por una lista equivalente de comprensión o expresión de generador :
Mapeando cada valor en una iterable
Por ejemplo, puedes tomar el valor absoluto de cada elemento:
Función anónima también soporte para mapear una lista:
names = ['Fred', 'Wilma', 'Barney']
    472/1068
    408
def average(*args):
return float(sum(args)) / len(args) # cast to float - only mandatory for python 2.x
list(map(average, measurement1, measurement2, measurement3)) 
# Out: [102.0, 110.0, 95.0, 100.0]
def to_percent(num): 
return num * 100
list(map(to_percent, [0.95, 0.75, 1.01, 0.1]))
# Out: [95.0, 75.0, 101.0, 10.0]
from functools import partial 
from operator import mul
rate = 0.9 # fictitious exchange rate, 1 dollar = 0.9 euros 
dollars = {'under_my_bed': 1000,
'jeans': 45,
'bank': 5000}
sum(map(partial(mul, rate), dollars.values())) 
# Out: 5440.5
def median_of_three(a, b, c): 
return sorted((a, b, c))[1]
list(map(median_of_three, measurement1, measurement2))
list(map(median_of_three, measurement1, measurement2, measurement3, measurement3))
o convirtiendo valores decimales a porcentajes:
o convertir dólares a euros (dado un tipo de cambio):
functools.partial es una forma conveniente de corregir los parámetros de las funciones para que 
puedan usarse con map lugar de usar lambda o crear funciones personalizadas.
Mapeo de valores de diferentes iterables.
Por ejemplo, calculando el promedio de cada elemento i -ésimo de múltiples iterables:
measurement1 = [100, 111, 99, 97]
measurement2 = [102, 117, 91, 102]
measurement3 = [104, 102, 95, 101]
Hay diferentes requisitos si se pasa más de un iterable al map dependiendo de la versión de 
python:
• La función debe tener tantos parámetros como sean iterables:
TypeError: median_of_three () falta 1 argumento posicional requerido: 'c'
TypeError: median_of_three () toma 3 argumentos posicionales pero se dieron 4
    473/1068
    409
from itertools import imap
from future_builtins import map as fmap # Different name to highlight differences
import operator
measurement1 = [100, 111, 99, 97]
measurement2 = [102, 117]
# Calculate difference between elements 
list(map(operator.sub, measurement1, measurement2))
import operator
from itertools import imap
measurement1 = [100, 111, 99, 97]
measurement2 = [102, 117]
# Calculate difference between elements 
list(imap(operator.sub, measurement1, measurement2)) 
# Out: [-2, -6]
list(imap(operator.sub, measurement2, measurement1)) 
# Out: [2, 6]
import operator
measurement1 = [100, 111, 99, 97]
measurement2 = [102, 117]
# Calculate difference between elements 
list(map(operator.sub, measurement1, measurement2)) 
# Out: [-2, -6]
list(map(operator.sub, measurement2, measurement1)) 
# Out: [2, 6]
Python 2.x 2.0.1
• map : el mapeo se repite siempre y cuando un iterable aún no esté completamente 
consumido, pero no asuma None de los iterables totalmente consumidos:
TypeError: tipo (s) de operando no compatibles para -: 'int' y 'NoneType'
• itertools.imap y future_builtins.map : la asignación se detiene tan pronto como se detiene 
una iterable:
Python 3.x 3.0.0
• La asignación se detiene tan pronto como se detiene una iterable:
Transposición con mapa: uso de "Ninguno" como argumento de función 
(solo python 2.x)
image = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
    474/1068
    410
list(map(None, *image))
insects = ['fly', 'ant', 'beetle', 'cankerworm'] 
f = lambda x: x + ' is an insect'
print(list(map(f, insects))) # the function defined by f is executed on each item of the 
iterable insects
list(map(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(fmap(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(imap(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
image2 = [[1, 2, 3],
[4, 5],
[7, 8, 9]]
list(map(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8), (3, None, 9)]
list(fmap(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8)]
list(imap(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8)]
# Fill missing values with None
# ignore columns with missing values 
# dito
Python 3.x 3.0.0
TypeError: el objeto 'NoneType' no se puede llamar 
Pero hay una solución para tener resultados similares:
Series y mapeo paralelo
map () es una función incorporada, lo que significa que está disponible en todas partes sin la 
necesidad de usar una declaración de 'importación'. Está disponible en todas partes, como print () 
Si observa el Ejemplo 5, verá que tuve que usar una declaración de importación antes de que 
pudiera usar una impresión bonita (pprint de importación). Así pprint no es una función 
incorporada
Mapeo en serie
En este caso, cada argumento de lo iterable se suministra como argumento a la función de 
mapeo en orden ascendente. Esto surge cuando solo tenemos un iterable para mapear y la 
función de mapeo requiere un solo argumento.
Ejemplo 1
resultados en
def conv_to_list(*args): 
return list(args)
list(map(conv_to_list, *image))
# Out: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
    475/1068
    411
print(list(map(len, insects))) # the len function is executed each item in the insect list
[3, 3, 6, 10]
carnivores = ['lion', 'tiger', 'leopard', 'arctic fox'] 
herbivores = ['african buffalo', 'moose', 'okapi', 'parakeet'] 
omnivores = ['chicken', 'dove', 'mouse', 'pig']
def animals(w, x, y, z):
return '{0}, {1}, {2}, and {3} ARE ALL ANIMALS'.format(w.title(), x, y, z)
# Too many arguments
# observe here that map is trying to pass one item each from each of the four iterables to 
len. This leads len to complain that
# it is being fed too many arguments
print(list(map(len, insects, carnivores, herbivores, omnivores)))
TypeError: len() takes exactly one argument (4 given)
# Too few arguments
# observe here that map is suppose to execute animal on individual elements of insects one-byone. But animals complain when
# it only gets one argument, whereas it was expecting four. 
print(list(map(animals, insects)))
TypeError: animals() missing 3 required positional arguments: 'x', 'y', and 'z'
# here map supplies w, x, y, z with one value from across the list
Ejemplo 2
resultados en
Mapeo paralelo
En este caso, cada argumento de la función de mapeo se extrae de todos los iterables (uno de 
cada iterable) en paralelo. Por lo tanto, el número de iterables suministrados debe coincidir con el 
número de argumentos requeridos por la función.
Ejemplo 3
resultados en
Ejemplo 4
resultados en
Ejemplo 5
['fly is an insect', 'ant is an insect', 'beetle is an insect', 'cankerworm is an insect']
    476/1068
    412
['Fly, lion, african buffalo, and chicken ARE ALL ANIMALS', 
'Ant, tiger, moose, and dove ARE ALL ANIMALS',
'Beetle, leopard, okapi, and mouse ARE ALL ANIMALS', 
'Cankerworm, arctic fox, parakeet, and pig ARE ALL ANIMALS']
resultados en
import pprint
pprint.pprint(list(map(animals, insects, carnivores, herbivores, omnivores)))
    477/1068
    413
def f(): 
print(20)
y = f 
y()
# Output: 20
Capítulo 88: Funciones
Introducción
Las funciones en Python proporcionan un código organizado, reutilizable y modular para realizar 
un conjunto de acciones específicas. Las funciones simplifican el proceso de codificación, evitan 
la lógica redundante y hacen que el código sea más fácil de seguir. Este tema describe la 
declaración y la utilización de funciones en Python.
Python tiene muchas funciones integradas como print() , input() , len() . Además de las 
funcionesintegradas,tambiénpuedecrearsuspropiasfuncionespararealizartrabajosmás 
específicos, que se denominan funciones definidas por el usuario .
Sintaxis
• def function_name ( arg1, ... argN, * args, kw1, kw2 = predeterminado, ..., ** kwargs ):
declaraciones
• lambda arg1, ... argN, * args, kw1, kw2 = predeterminado, ..., ** kwargs : expresión
Parámetros
Parámetro Detalles
arg1 , ..., argN Argumentos regulares
* args Argumentos posicionales sin nombre
kw1 , ..., kwN Argumentos solo de palabra clave
** kwargs El resto de argumentos de palabras clave.
Observaciones
5 cosas básicas que puedes hacer con las funciones:
• Asignar funciones a variables
• Definir funciones dentro de otras funciones ( funciones anidadas )
    478/1068
    414
return "Hello "+ name + "!" 
return inner_fun
greet = outer_fun("Sophia")
print(greet()) # Output: Hello Sophia!
# the variable name is available to the inner function
def outer_fun(name): 
def inner_fun():
def function_name(parameters): 
statement(s)
• Las funciones pueden devolver otras funciones.
def f(y):
def nth_power(x): 
return x ** y
return nth_power # returns a function
squareOf = f(2) 
cubeOf = f(3) 
squareOf(3) 
cubeOf(2)
# function that returns the square of a number 
# function that returns the cube of a number 
# Output: 9
# Output: 8
• Las funciones se pueden pasar como parámetros a otras funciones.
def a(x, y):
print(x, y) 
def b(fun, str):
fun('Hello',str)
b(a, 'Sophia')
# b has two arguments: a function and a string 
# Output: Hello Sophia
• Las funciones internas tienen acceso al ámbito de cierre ( Cierre )
Recursos adicionales
• Más sobre funciones y decoradores:https://www.thecodeship.com/patterns/guide-to-pythonfunction-decorators/
Examples
Definiendo y llamando funciones simples.
Usar la instrucción def es la forma más común de definir una función en python. Esta declaración 
es una declaración compuesta llamada cláusula única con la siguiente sintaxis:
function_name se conoce como el identificador de la función. Dado que la definición de una función 
es una sentencia ejecutable, su ejecución vincula el nombre de la función con el objeto de la
def f(a, b, y):
def inner_add(a, b): # inner_add is hidden from outer code 
return a + b
return inner_add(a, b)**y
    479/1068
    415
def greet():
print("Hello")
greet()
# Out: Hello
def greet_two(greeting): 
print(greeting)
greet_two("Howdy") 
# Out: Howdy
def greet_two(greeting="Howdy"): 
print(greeting)
greet_two()
# Out: Howdy
def many_types(x): 
if x < 0:
función que se puede llamar más adelante utilizando el identificador.
parameters es una lista opcional de identificadores que se unen a los valores proporcionados como 
argumentos cuando se llama a la función. Una función puede tener un número arbitrario de 
argumentos separados por comas.
statement(s) también conocidas como el cuerpo de la función ) son una secuencia no vacía de 
sentencias que se ejecutan cada vez que se llama a la función. Esto significa que el cuerpo de 
una función no puede estar vacío, como cualquier bloque con sangría .
Este es un ejemplo de una definición de función simple cuyo propósito es imprimir Hello cada vez 
que se llama:
Ahora llamemos a la función de greet() definida:
Ese es otro ejemplo de una definición de función que toma un solo argumento y muestra el valor 
pasado cada vez que se llama a la función:
Después de eso, la función greet_two() debe llamarse con un argumento:
También puede dar un valor predeterminado a ese argumento de función:
Ahora puedes llamar a la función sin dar un valor:
Notaráque,adiferenciademuchosotros idiomas,nonecesitadeclararexplícitamenteun tipode 
devolución de la función. Las funcionesdePython pueden devolver valores de cualquier tipo a 
través de la palabra clave return . ¡Una función puede devolver cualquier número de tipos 
diferentes!
    480/1068
    416
def do_nothing(): 
pass
print(do_nothing()) 
# Out: None
def give_me_five(): 
return 5
print(give_me_five()) # Print the returned value 
# Out: 5
# Print the saved returned value
num =give_me_five() 
print(num)
# Out: 5
print(give_me_five() + 10)
# Out: 15
Mientras la persona que llama maneje esto correctamente, este es un código de Python 
perfectamente válido.
Una función que llega al final de la ejecución sin una declaración de retorno siempre devolverá
None :
Como se mencionó anteriormente, una definición de función debe tener un cuerpo de función, una 
secuencia de sentencias no vacía. Por lo tanto, la instrucción de pass se utiliza como cuerpo de la 
función, que es una operación nula: cuando se ejecuta, no sucede nada. Hace lo que significa, 
salta. Es útil como marcador de posición cuando se requiere una declaración sintácticamente, 
pero no es necesario ejecutar ningún código.
Devolviendo valores desde funciones
Las funciones pueden return un valor que puede utilizardirectamente:
o guarda el valor para su uso posterior:
o use el valor para cualquier operación:
Si se encuentra return en la función, la función se cerrará inmediatamente y las operaciones
return "Hello!" 
else:
return 0
print(many_types(1)) 
print(many_types(-1))
# Output:
0
Hello!
    481/1068
    417
def give_me_another_five(): 
return 5
print('This statement will not be printed. Ever.')
print(give_me_another_five()) 
# Out: 5
def give_me_two_fives():
return 5, 5 # Returns two 5
first, second = give_me_two_fives() 
print(first)
# Out: 5 
print(second) 
# Out: 5
def divide(dividend, divisor): # The names ofthe function and its arguments 
# The arguments are available by name in the body of the function 
print(dividend / divisor)
divide(10, 2)
# output: 5
divide(divisor=2, dividend=10) 
# output: 5
def make(action='nothing'): 
return action
subsiguientes no se evaluarán:
También puede return varios valores (en forma de tupla):
Una función sin una declaración de return devuelve implícitamente None . De manera similar, una 
función con una declaración de return , pero sin valor de retorno o variable devuelve None .
Definiendo una función con argumentos.
Los argumentos se definen entre paréntesis después del nombre de la función:
El nombre de la función y su lista de argumentos se denominan la firma de la función. Cada 
argumento nombrado es efectivamente una variable local de la función.
Al llamar a la función, dé valores para los argumentos enumerándolos en orden
o especifíquelos en cualquier orden usando los nombres de la definición de función:
Definiendo una función con argumentos opcionales.
Los argumentos opcionales se pueden definir asignando (usando = ) un valor predeterminado al 
nombre de argumento:
    482/1068
    418
make("fun") 
# Out: fun
make(action="sleep") 
# Out: sleep
#The argument is optionalso the functionwill use the default value if the argument is 
# not passed in.
make()
# Out: nothing
def func(value1, value2, optionalvalue=10):
return '{0} {1} {2}'.format(value1, value2, optionalvalue1)
print(func(1, 'a', 100))
# Out: 1 a 100
print(func('abc', 14))
# abc 14 10
print(func('This', optionalvalue='StackOverflow Documentation', value2='is')) 
# Out: This is StackOverflow Documentation
Llamar a esta función es posible de 3 maneras diferentes:
Advertencia
Los tipos mutables (list, dict ,set ,etc.) deben tratarse con cuidado cuando se dan 
como atributopredeterminado .Cualquier mutación del argumento por defectolo 
cambiarápermanentemente.ConsulteDefinirunafunciónconargumentosmutables
opcionales .
Definiendo una función con múltiples argumentos.
Uno puede dar a la función tantos argumentos como quiera, las únicas reglas fijas son que cada 
nombre de argumento debe ser único y que los argumentos opcionales deben estar después de 
los no opcionales:
Al llamar a la función, puede dar cada palabra clave sin el nombre, pero el orden importa:
O combinar dando los argumentos con nombre y sin. Entonces los que tienen nombre deben 
seguir a los que no tienen, pero el orden de los que tienen nombre no importa:
Definiendo una función con un número arbitrario de argumentos.
Número arbitrario de argumentos
    483/1068
    419
def func(*args):
# args will be a tuple containing all valuesthat are passed in 
for i in args:
print(i)
func(1, 2, 3) # Calling it with 3 arguments
# Out: 1
# 2
# 3
list_of_arg_values = [1, 2, 3]
func(*list_of_arg_values) # Calling it with list of values, * expands the list 
# Out: 1
# 2
# 3
func() # Calling it withoutarguments 
# No Output
def func(**kwargs):
# kwargs will be a dictionary containing the names as keys and the values as values 
for name, value in kwargs.items():
print(name, value)
func(value1=1, value2=2, value3=3) # Calling it with 3 arguments 
# Out: value1 1
# value2 2
posicionales:
La definición de una función capaz de tomar un número arbitrario de argumentos se puede hacer 
prefijando uno de los argumentos con un *
No puede proporcionar un valor predeterminado para args , por ejemplo func(*args=[1, 2, 3])
generará un error de sintaxis (ni siquiera compilará).
No puede proporcionarlos por nombre al llamar a la función, por ejemplo, func(*args=[1, 2, 3])
generará un TypeError .
Pero si yatienesusargumentosenuna matriz (o cualquierotroIterable ),puede invocar su 
función así: func(*my_stuff) .
Se puede acceder a estos argumentos ( *args ) por índice, por ejemplo, args[0] devolverá el 
primer argumento
Número arbitrario de argumentos de palabras 
clave
Puede tomar un número arbitrario de argumentos con un nombre definiendo un argumento en la 
definición con dos * delante:
    484/1068
    420
deffunc(arg1, arg2=10 , *args, kwarg1, kwarg2=2, **kwargs): 
pass
# |-positional-|-optional-|---keyword-only--|-optional-|
No puede proporcionarlos sin nombres, por ejemplo, func(1, 2, 3) generará un TypeError .
kwargses un simple diccionario nativo de python. Por ejemplo, args['value1'] dará el valor para el 
argumentovalue1.AsegúresedeverificardeantemanoqueexistatalargumentooseKeyErrorun 
KeyError .
Advertencia
Puede combinar estos con otros argumentos opcionales y requeridos, pero el orden dentro de la 
definición es importante.
Losargumentosposicionales/palabrasclavesonloprimero.(Argumentosrequeridos). 
Luego vienen los argumentos arbitrarios *arg .(Opcional).
Luego vienen los argumentos de palabra clave . (Necesario). 
Finalmente lapalabra clave arbitraria **kwargs viene.(Opcional).
• arg1 debe darse, de lo contrario se TypeError un TypeError . Se puede dar como argumento 
posicional ( func(10) ) o de palabra clave ( func(arg1=10) ).
• kwarg1 debe proporcionar kwarg1 , pero solo se puede proporcionar como palabra claveargumento: func(kwarg1=10) .
• arg2 y kwarg2 son opcionales. Si se va a cambiar el valor, se aplican las mismas reglas que 
para arg1 (posicional o palabra clave) y kwarg1 (solo palabra clave).
• *args capturaparámetros posicionalesadicionales.Perotenga encuentaquearg1 yarg2 
deben proporcionarse como argumentos posicionales para pasar argumentos a *args : 
func(1, 1, 1, 1) .
• **kwargs captura todos los parámetros de palabras clave adicionales. En este caso, 
cualquier parámetro que no sea arg1 , arg2 , kwarg1 o kwarg2 . Por ejemplo: func(kwarg3=10) .
• EnPython3,puedeusar* soloparaindicarquetodoslosargumentosposterioresdeben 
especificarse como palabras clave. Por ejemplo, la función math.isclose en Python 3.5 y 
superior se define usando def math.isclose (a, b, *, rel_tol=1e-09, abs_tol=0.0) , lo que 
significaquelosprimerosdosargumentosse puedensuministrardemaneraposicional pero 
el opcional Los parámetros terceroy cuarto solose pueden suministrar comoargumentos 
de palabras clave.
# bar 2
# Calling it with a dictionary
my_dict = {'foo': 1, 'bar': 2} 
func(**my_dict)
# Out: foo 1
func() # Calling it without arguments
# No Out put
# value3 3
    485/1068
    421
def func(arg1, arg2=10, **kwargs): 
try:
kwarg1 = kwargs.pop("kwarg1") 
except KeyError:
raise TypeError("missing required keyword-only argument: 'kwarg1'")
kwarg2 = kwargs.pop("kwarg2", 2) 
# function body ...
def fn(**kwargs): 
print(kwargs) 
f1(**kwargs)
def f1(**kwargs): 
print(len(kwargs))
fn(a=1, b=2) 
# Out:
# {'a': 1, 'b': 2}
# 2
Python 2.x no admite parámetros de palabras clave solamente. Este comportamiento puede ser 
emulado con kwargs :
Nota sobre nombrar
Laconvención de nombrar argumentos opcionales posicionales args y opcionales de palabras 
clave kwargs es solo una convención que puede usar cualquier nombre que desee, pero es útil 
seguirla convención para que otros sepan lo que está haciendo,o incluso usted mismo más 
adelante, así que hágalo.
Nota sobre la singularidad
Cualquier función se puede definir con ninguno o un *args y ninguno o uno **kwargs pero no 
con más de uno de cada uno. También *args debe ser el último argumento posicional y **kwargs 
debe ser el último parámetro. El intento de utilizar más de uno de ambos dará lugar a una 
excepción de error de sintaxis.
Nota sobre funciones de anidamiento con argumentos 
opcionales
Es posible anidar dichas funciones y la convención habitual es eliminar los elementos que el 
código ya ha manejado, pero si está pasando los parámetros, debe pasar argumentos opcionales 
posicionales con un prefijo * y argumentos de palabras clave opcionales con un prefijo ** , de lo 
contrario, los argumentos se pueden pasar como una lista o tupla y los kwargs como un solo 
diccionario. p.ej:
Definiendo una función con argumentos mutables opcionales.
    486/1068
    422
def f(a, b=42, c=[]): 
pass
print(f. defaults ) 
# Out: (42,[])
def append(elem, to=[]):
to.append(elem) # This call to append() mutates the default variable "to" 
return to
append(1) 
# Out: [1]
append(2) # Appends it to the internally stored list 
# Out: [1, 2]
append(3, []) #Using a new created list givesthe expected result 
# Out: [3]
# Calling it again without argument will append to the internally stored list again 
append(4)
# Out: [1, 2, 4]
Existe un problema cuando se usan argumentos opcionales con un tipo predeterminado 
mutable (descrito en Definición de una función con argumentos opcionales ), lo que puede 
conducir a un comportamiento inesperado.
Explicación
Este problema surge porque los argumentos predeterminados de una función se inicializan una 
vez , en el momento en que se define la función y no (como en muchos otros idiomas) cuando se 
llama a la función. Los valores predeterminados se almacenan dentro de la variable miembro
 defaults del objetode defaults .
Para los tipos inmutables (ver Pasar argumento y mutabilidad ) esto no es un problema porque 
no hay manera de mutar la variable; solo se puede reasignar, sin cambiar el valor original. Por lo 
tanto, se garantiza que los subsiguientes tengan el mismo valor predeterminado. Sin embargo, 
para un tipo mutable , el valor original puede mutar, haciendo llamadas a sus diversas funciones 
miembro. Por lo tanto, no se garantiza que las llamadas sucesivas a la función tengan el valor 
predeterminado inicial.
Nota: Algunos IDE como PyCharm emitirán una advertencia cuando se especifique un 
tipo mutable como atributo predeterminado.
Solución
Si desea asegurarse de que el argumento predeterminado sea siempre el que especifique en la 
definición de la función, entonces la solución es usar siempre un tipo inmutable como su 
argumento predeterminado.
    487/1068
    423
def append(elem, to=None): 
if to is None:
to = []
to.append(elem) 
return to
def greeting(): 
return "Hello"
print(greeting())
Hello
greet_me = lambda: "Hello"
print(greet_me())
Hello
Un modismo común para lograr esto cuando se necesita un tipo mutable como predeterminado, 
es utilizar None (inmutable) como argumento predeterminado y luego asignar el valor 
predeterminado real a la variable de argumento si es igual a None .
Funciones Lambda (Inline / Anónimo)
La palabra clave lambda crea una función en línea que contiene una sola expresión. El valor de 
esta expresión es lo que la función devuelve cuando se invoca.
Considere la función:
el cual, cuando es llamado como:
huellas dactilares:
Esto se puede escribir como una función lambda de la siguiente manera:
Vea la nota al final de esta sección con respecto a la asignación de lambdas a las 
variables. En general, no lo hagas.
Estocrea una funciónenlíneaconel nombregreet_me que devuelve Hello .Tengaencuentaque 
no escribe return cuando crea una función con lambda. El valor después de : se devuelve 
automáticamente.
Una vez asignada a una variable, se puede usar como una función regular:
huellas dactilares:
lambda
    488/1068
    424
strip_and_upper_case = lambda s: s.strip().upper()
strip_and_upper_case(" Hello ")
HELLO
greeting = lambda x, *args, **kwargs: print(x, args, kwargs) 
greeting('hello', 'world', world='world')
hello ('world',) {'world': 'world'}
# ['BaZ ', ' bAR', 'foo ']
sorted( [" foo ", " bAR", "BaZ "], key=lambda s:s.strip())
# Out:
sorted( map( lambda s: s.strip(), [" foo ", " bAR", "BaZ "]))
# Out:
# ['BaZ', 'bAR', 'foo']
sorted( map( lambda s: s.strip().upper(), [" foo ", " bAR", "BaZ "]))
# Out:
# ['BAR', 'BAZ', 'FOO']
my_list = [3, -4, -2, 5, 1, 7]
sorted( my_list, key=lambda x: abs(x))
s puede tomar argumentos, también:
devuelve la cadena:
También pueden tomar un número arbitrario de argumentos / argumentos de palabras clave, 
como las funciones normales.
huellas dactilares:
lambda se usan comúnmente para funciones cortas que son convenientes para definir en el punto 
donde se llaman (típicamente con sorted , filter y map ).
Por ejemplo, esta línea ordena una lista de cadenas que ignoran su caso e ignoran los espacios 
en blanco al principio y al final:
sorted( [" foo ", " bAR", "BaZ "], key=lambda s: s.strip().upper())
# Out:
# [' bAR', 'BaZ ', ' foo ']
Ordenar la lista simplemente ignorando espacios en blanco:
Ejemplos con map :
Ejemplos con listas numéricas:
    489/1068
    425
def foo(msg):
print(msg)
greet = lambda x = "hello world": foo(x) 
greet()
hello world
def f(x): return 2*x
f = lambda x: 2*x
Uno puede llamar a otras funciones (con / sin argumentos) desde dentro de una función lambda.
huellas dactilares:
Esto es útil porque lambda puede contener solo una expresión y al usar una función subsidiaria se 
pueden ejecutar varias declaraciones.
NOTA
Tenga en cuenta que PEP-8 (la guía de estilo oficial de Python) no recomienda asignar lambdas a 
las variables (como hicimos en los dos primeros ejemplos):
Siempre use una instrucción def en lugar de una instrucción de asignación que vincule 
una expresión lambda directamente a un identificador.
Sí:
No:
La primera forma significa que el nombre del objeto de función resultante es 
específicamente f lugar del genérico <lambda> . Esto es más útil para las trazas y 
representaciones de cadenas en general. El uso de la declaración de asignación 
elimina el único beneficio que puede ofrecer una expresión lambda sobre una 
declaración explícita de def (es decir, que se puede incrustar dentro de una expresión 
más grande).
# Out:
# [1, -2, 3, -4, 5, 7]
list( filter( lambda x: x>0, my_list)) 
# Out:
# [3, 5, 1, 7]
list( map( lambda x: abs(x), my_list)) 
# Out:
[3, 4, 2, 5, 1, 7]
    490/1068
    426
# list labelled by y has been mutated too
# call foo with y as argument
# list labelled by x has been mutated
y = [4, 5, 6]
foo(y)
# Out: [9, 5, 6]
print(y)
# Out: [9, 5, 6]
# here x is the parameter
# This mutates the list labelled by both x and y
def foo(x):
x[0] = 9
print(x)
# y is the argument, x is the parameter
# Pretend that we wrote "x = y", then go to line 1
y = [4, 5, 6]
foo(y) 
y
# Out: [9, 5, 6]
def foo(x): # here x is the parameter, when we call foo(y) we assign y tox 
x[0] = 9 # This mutates the list labelled by both x and y
x = [1, 2, 3] # x is now labeling a different list (y isunaffected)
x[2] = 8 # This mutates x's list, not y's list
x = [3, 1, 9]
y = x
x.append(5) # Mutatesthe list labelled by x and y, both x and y are bound to [3, 1, 9] 
x.sort() # Mutatesthe list labelled by x and y (in-place sorting)
x = x+ [4] # Does not mutate the list (makes a copy for x only, not y) 
z = x # z is x ([1, 3, 9, 4])
x += [6] # Mutates the list labelled by both x and z (uses the extend function). 
x = sorted(x) # Does not mutate the list (makes a copy for x only).
x
# Out: [1, 3, 4, 5, 6, 9]
y
# Out: [1, 3, 5, 9]
z
# Out: [1, 3, 5, 9, 4, 6]
Argumento de paso y mutabilidad.
Primero, alguna terminología:
• argumento (parámetro real ): la variable real que se pasa a una función;
• parámetro (parámetro formal ): la variable de recepción que se utiliza en una función.
En Python, los argumentos se pasan por asignación (a diferencia de otros idiomas, donde los 
argumentos pueden pasarse por valor / referencia / puntero).
• Mutar un parámetro mutará el argumento (si el tipo del argumento es mutable).
• Reasignar el parámetro no reasignará el argumento.
En Python, realmente no asignamos valores a las variables, en lugar de eso, vinculamos
(es decir, asignamos, adjuntamos) variables (consideradas como nombres ) a los objetos.
• Inmutable: enteros, cadenas, tuplas, etc. Todas las operaciones hacen copias.
• Mutable: listas, diccionarios, conjuntos, etc. Las operaciones pueden o no mutar.
    491/1068
    427
def makeInc(x): 
def inc(y):
# x is "attached" in the definition of inc 
return y + x
return inc
incOne = makeInc(1) 
incFive = makeInc(5)
incOne(5) # returns 6 
incFive(5) # returns 10
def makeInc(x): 
def inc(y):
# incrementing x is not allowed 
x += y
return x 
return inc
incOne = makeInc(1)
incOne(5) # UnboundLocalError: local variable 'x' referenced before assignment
def makeInc(x): 
def inc(y):
nonlocal x
# now assigning a value to x is allowed 
x += y
return x 
return inc
incOne = makeInc(1) 
incOne(5) # returns 6
Cierre
Los cierres en Python son creados por llamadas a funciones. Aquí, la llamada a makeInc crea un 
enlace para x que se hace referencia dentro de la función inc . Cada llamada a makeInc crea una 
nueva instancia de esta función, pero cada instancia tiene un enlace a un enlace diferente dex .
Observe que, mientras que en un cierre regular, la función encerrada hereda completamente 
todas las variables de su entorno envolvente, en esta construcción, la función encerrada solo 
tiene acceso de lectura a las variables heredadas, pero no puede asignárselas.
Python 3 ofrece la declaración no nonlocal ( variables no locales ) para realizar un cierre completo 
con funciones anidadas.
Python 3.x 3.0
Funciones recursivas
Una función recursiva es una función que se llama a sí misma en su definición. Por ejemplo, la
    492/1068
    428
def factorial(n):
#n here should be an integer 
if n == 0:
return 1 
else:
return n*factorial(n-1)
factorial(0) 
#out 1 
factorial(1) 
#out 1 
factorial(2) 
#out 2 
factorial(3) 
#out 6
factorial = lambda n: 1 if n == 0 else n*factorial(n-1)
def cursing(depth): 
try:
cursing(depth + 1) # actually, re-cursing 
except RuntimeError as RE:
print('I recursed {} times!'.format(depth))
cursing(0)
# Out: I recursed 1083 times!
sys.setrecursionlimit(2000) 
cursing(0)
# Out: I recursed 1997 times!
función matemática,factorial,definidaporfactorial(n) = n*(n-1)*(n-2)*...*3*2*1 . se puede 
programar como
Las salidas aquí son:
como se esperaba. Observe que esta función es recursiva porque el segundo return factorial(n1) , donde la función se llama a sí mismo en su definición.
Algunas funciones recursivas pueden implementarse usando lambda , la función factorial que usa 
lambda sería algo como esto:
La función produce la misma salida que la anterior.
Límite de recursión
Hay un límite a la profundidad de la posible recursión, que depende de la implementación de 
Python. Cuando se alcanza el límite, se genera una excepción RuntimeError:
Es posible cambiar el límite de profundidad de recursión usando sys.setrecursionlimit(limit) y 
verificar este límite por sys.getrecursionlimit() .
    493/1068
    429
def fibonacci(n): 
def step(a,b):
return b, a+b 
a, b = 0, 1
for i in range(n): 
a, b =step(a, b)
return a
def make_adder(n): 
def adder(x):
return n + x 
return adder
add5 = make_adder(5) 
add6 = make_adder(6) 
add5(10)
#Out: 15
add6(10) 
#Out: 16
defrepeatedly_apply(func,n,x): 
for i in range(n):
x = func(x) 
return x
repeatedly_apply(add5, 5, 1)
#Out: 26
def unpacking(a, b, c=45, d=60, *args, **kwargs): 
print(a, b, c, d, args, kwargs)
>>> unpacking(1, 2)
1 2 45 60 () {}
>>> unpacking(1, 2, 3, 4)
1 2 3 4 () {}
>>> unpacking(1, 2, c=3, d=4) 
1 2 3 4 () {}
>>> unpacking(1, 2, d=4, c=3) 
1 2 3 4 () {}
Desde Python 3.5, la excepción es un RecursionError , que se deriva de RuntimeError .
Funciones anidadas
Las funciones en python son objetos de primera clase. Se pueden definir en cualquier ámbito.
Las funciones que capturan su ámbito de distribución pueden transmitirse como cualquier otro 
tipo de objeto
Iterable y desempaquetado del diccionario.
Las funciones le permiten especificar estos tipos de parámetros: posicionales, nombrados, 
variables posicionales, Argumentos de palabras clave (kwargs). Aquí hay un uso claro y conciso 
de cada tipo.
    494/1068
    430
>>> pair = (3,)
>>> unpacking(1, 2, *pair, d=4) 
1 2 3 4 () {}
>>> unpacking(1, 2, d=4, *pair) 
1 2 3 4 () {}
>>> unpacking(1, 2, *pair, c=3) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'
>>> unpacking(1, 2, c=3, *pair) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'
>>> args_list = [3]
>>> unpacking(1, 2, *args_list, d=4) 
1 2 3 4 () {}
>>> unpacking(1, 2, d=4, *args_list) 
1 2 3 4 () {}
>>> unpacking(1, 2, c=3, *args_list) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'
>>> unpacking(1, 2, *args_list, c=3) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'
>>> pair = (3, 4)
>>> unpacking(1, 2, *pair) 
1 2 3 4 () {}
>>> unpacking(1, 2, 3, 4, *pair)
1 2 3 4 (3, 4) {}
>>> unpacking(1, 2, d=4, *pair) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'
>>> unpacking(1, 2, *pair, d=4) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'
>>> args_list = [3, 4]
>>> unpacking(1, 2, *args_list) 
1 2 3 4 () {}
>>> unpacking(1, 2, 3, 4, *args_list)
1 2 3 4 (3, 4) {}
>>> unpacking(1, 2, d=4, *args_list) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'
>>> unpacking(1, 2, *args_list, d=4) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'
>>> arg_dict = {'c':3, 'd':4}
    495/1068
    431
def f(*a, b): 
pass
f(1, 2, 3)
# TypeError: f() missing 1 required keyword-only argument: 'b'
def f(a, b, *, c): 
pass
f(1, 2, 3)
# TypeError: f() takes 2 positional arguments but 3 were given 
f(1, 2, c=3)
# No error
Forzando el uso de parámetros nombrados
Todos los parámetros especificados después del primer asterisco en la firma de función son solo 
palabras clave.
En Python 3 es posible poner un solo asterisco en la firma de la función para garantizar que los 
argumentos restantes solo puedan pasarse utilizando argumentos de palabras clave.
Lambda recursiva utilizando variable asignada
Un método para crear funciones lambda recursivas implica asignar la función a una variable y 
luego hacer referencia a esa variable dentro de la misma función. Un ejemplo común de esto es el 
cálculo recursivo del factorial de un número, como se muestra en el siguiente código:
>>> unpacking(1, 2, **arg_dict) 
1 2 3 4 () {}
>>> arg_dict = {'d':4, 'c':3}
>>> unpacking(1, 2, **arg_dict) 
1 2 3 4 () {}
>>> arg_dict = {'c':3, 'd':4, 'not_a_parameter': 75}
>>> unpacking(1, 2, **arg_dict)
1 2 3 4 () {'not_a_parameter': 75}
>>> unpacking(1, 2, *pair, **arg_dict) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'
>>> unpacking(1, 2, 3, 4, **arg_dict) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'd'
# Positional arguments take priority over any other form of argument passing
>>> unpacking(1, 2, **arg_dict, c=3) 
1 2 3 4 () {'not_a_parameter': 75}
>>> unpacking(1, 2, 3, **arg_dict, c=3) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unpacking() got multiple values for argument 'c'
    496/1068
    432
Descripción del código
A la función lambda, a través de su asignación variable, se le pasa un valor (4) que evalúa y 
devuelve 1 si es 0 o, de lo contrario, devuelve el valor actual ( i ) * otro cálculo realizado porla 
función lambda del valor - 1 ( i-1 ). Esto continúa hasta que el valor pasado se reduce a 0 ( return 
1 ). Un proceso que se puede visualizar como:
lambda_factorial = lambda i:1 if i==0 else i*lambda_factorial(i-1) 
print(lambda_factorial(4)) # 4 * 3 * 2 * 1 = 12 * 2 = 24
    497/1068
    433
Capítulo 89: Funciones parciales
Introducción
Como probablemente sepa si vino de la escuela de OOP, especializarse en una clase abstracta y 
usarla es una práctica que debe tener en cuenta al escribir su código.
¿Qué pasaría si pudieras definir una función abstracta y especializarla para crear diferentes 
versiones de ella? Piensa que es una especie de función de herencia donde se vinculan 
parámetros específicos para que sean confiables para un escenario específico.
Sintaxis
• parcial (función, ** params_you_want_fix)
Parámetros
Param detalles
X el número a elevar
y el exponente
aumento La función a especializarse.
Observaciones
Como se indica en el documento de Python, functools.partial :
Devuelva un nuevo objeto parcial que, cuando se le llame, se comportará como una 
función llamada con los argumentos posicionales, argumentos y palabras clave de 
palabras clave. Si se proporcionan más argumentos a la llamada, se anexan a args. Si 
se proporcionan argumentos de palabras clave adicionales, amplían y anulan las 
palabras clave.
Consulte este enlace para ver cómo se puede implementar parcial .
Examples
Elevar el poder
Supongamos que queremos elevar x a un número y . 
Escribirías esto como:
    498/1068
    434
def raise(x, y):
if y in (3,4,5): 
return x**y
raise NumberNotInRangeException("You should provide a valid exponent")
from functors import partial 
raise_to_three = partial(raise, y=3) 
raise_to_four = partial(raise, y=4) 
raise_to_five = partial(raise, y=5)
¿Qué pasa si su valor y puede asumir un conjunto finito de valores?
Supongamos que y puede ser uno de [3,4,5] y digamos que no quiere ofrecer al usuario final la 
posibilidad de usar dicha función, ya que es muy computacional. De hecho, verificará si se 
proporciona y asume un valor válido y reescribirá su función como:
¿Sucio? Usemos el formulario abstracto y lo especialicemos en los tres casos: implementémoslo
parcialmente .
¿Qué pasa aquí? Hemos fijado los parametros y y definimos tres funciones diferentes.
No es necesario usar la función abstracta definida anteriormente (puede hacerla privada ), pero 
puede usar funciones aplicadas parciales para tratar de elevar un número a un valor fijo.
def raise_power(x, y): 
return x**y
    499/1068
    435
# naive partial implementation of the Python 2.x xrange() 
def xrange(n):
i = 0
while i < n:
yield i 
i += 1
# looping
for i in xrange(10):
print(i) # prints the values 0, 1, ..., 9
# unpacking
a, b, c = xrange(3) # 0, 1, 2
# building a list
l = list(xrange(10)) # [0, 1, ..., 9]
def nums():
Capítulo 90: Generadores
Introducción
Losgeneradoressoniteradoresperezososcreadosporlasfuncionesdelgenerador(queutilizan 
el yield ) o las expresiones del generador (que usan (an_expression for x in an_iterator) ).
Sintaxis
• rendimiento <expr>
• rendimiento de <expr>
• <var> = rendimiento <expr>
• siguiente ( <iter> )
Examples
Iteración
Un objeto generador soporta el protocolo iterador . Es decir, proporciona un método next() (
 next () en Python 3.x), que se utiliza para avanzar en su ejecución, y su método iter
devuelve.Estosignificaquesepuedeusarun generadorencualquier construccióndelenguaje 
que admita objetos iterablesgenéricos.
La siguiente función ()
El next() incorporado es un envoltorio conveniente que se puede usar para recibir un valor de 
cualquieriterador(incluidouniteradorgenerador)yparaproporcionarunvalorpredeterminadoen 
caso de que se agote el iterador.
    500/1068
    436
def accumulator(): 
total = 0
value = None 
while True:
# receive sent value 
value = yield total
if value is None: break 
# aggregate values 
total += value
generator = accumulator()
# advance until the first "yield" 
next(generator) # 0
# from this point on, the generator aggregates values
# Calling next(generator) is equivalent to calling generator.send(None) 
next(generator) # StopIteration
La sintaxis es la next(iterator[, default]) . Si el iterador finaliza y se pasa un valor 
predeterminado,sedevuelve.Sinoseproporcionóningúnvalorpredeterminado,seStopIteration
.
Enviando objetos a un generador.
Además de recibir valores de un generador, es posible enviar un objeto a un generador utilizando 
el método send() .
generator.send(1) # 1
generator.send(10) # 11
generator.send(100) # 111
# ...
Lo que pasa aquí es lo siguiente:
• Cuando llama por primera vez al next(generator) , el programa avanza a la primera 
declaración de yield y devuelve el valor del totalenese punto, que es0.La ejecución del 
generador se suspende en estepunto.
• Cuando llama a generator.send(x) , el intérprete toma el argumento x y lo convierte en el 
valor de retorno de la última declaración de yield , que se asigna al value .El generador 
continúa como de costumbre, hasta que da el siguiente valor.
• Cuando finalmente llama a next(generator) , el programa trata esto como si estuviera
yield 1
yield 2
yield 3 
generator = nums()
next(generator, None) # 1 
next(generator, None) # 2 
next(generator, None) # 3 
next(generator, None) #None 
next(generator, None) #None 
# ...
    501/1068
    437
generator = (i * 2 for i in range(3))
next(generator) # 0
next(generator) # 2
next(generator) # 4
next(generator) # raises StopIteration
sum(i ** 2 for i in range(4)) # 0^2 + 1^2 + 2^2 + 3^2 = 0 + 1 + 4 + 9 = 14
expression = (x**2 for x in range(10))
def function():
for x in range(10): 
yield x**2
enviando None al generador. No hay nada especial en None , sin embargo, este ejemplo utiliza
None como un valor especial para pedirle al generador que se detenga.
Expresiones generadoras
Es posible crear iteradores de generador utilizando una sintaxis similar a la comprensión.
Si a una función no necesariamente se le debe pasar una lista, puede guardar caracteres (y 
mejorar la legibilidad) colocando una expresión de generador dentro de una llamada de función. 
El paréntesis de la llamada a la función hace implícitamente que su expresión sea una expresión 
generadora.
Además, guardará en la memoria porque en lugar de cargarla lista completa sobre la que está 
iterando ( [0, 1, 2, 3] en el ejemplo anterior), el generador permite que Python use los valores 
según sea necesario.
Introducción
Las expresiones de los generadores son similares a las listas, diccionarios y conjuntos de 
comprensión, pero están entre paréntesis. Los paréntesis no tienen que estar presentes cuando 
se usan como el único argumento para una llamada de función.
Este ejemplo genera los 10 primeros cuadrados perfectos, incluido 0 (en el que x = 0).
Lasfuncionesdelgenerador sonsimilares alas funciones regulares,exceptoque tienen unao 
más declaraciones de yield en su cuerpo. Dichas funciones no pueden return ningún valor (sin 
embargo, se permiten return vacías si desea detener el generador antes).
Esta función del generador es equivalente a la expresión del generador anterior, produce el 
mismo.
Nota : todas las expresiones generadoras tienen sus propias funciones equivalentes , pero no al 
revés.
    502/1068
    438
sum(i for i in range(10) if i % 2 == 0) #Output: 20
any(x = 0 for x in foo) #Output: True or False depending on foo 
type(a > b for a in foo if a % 2 == 1) #Output: <class 'generator'>
sum((i for i in range(10) if i % 2 == 0)) 
any((x = 0 for x in foo))
type((a > b for a in foo if a % 2 == 1))
fooFunction(i for i in range(10) if i % 2 == 0,foo,bar) 
return x = 0 for x in foo
barFunction(baz, a > b for a in foo if a % 2 == 1)
g1 = function()
print(g1) # Out: <generator object function at 0x1012e1888>
for x in g1:
print("Received", x)
# Output:
Se puede usar una expresión generadora sin paréntesis si ambos paréntesis se repetirían de lo 
contrario:
En lugar de:
Pero no:
Al llamar a una función de generador se genera un objeto generador , que luego se puede iterar. 
A diferencia de otros tipos de iteradores, los objetos generadores solo se pueden atravesar una 
vez.
Observe que el cuerpo de un generador no se ejecuta inmediatamente: cuando llama a function() 
en el ejemplo anterior, devuelve inmediatamente un objeto generador, sin ejecutar siquiera la 
primeradeclaracióndeimpresión.Estopermitequelosgeneradoresconsumanmenosmemoria 
quelas funcionesquedevuelvenunalista,ypermitecreargeneradoresqueproducensecuencias 
infinitamente largas.
Por esta razón, los generadores a menudo se utilizan en la ciencia de datos y en otros contextos 
que involucran grandes cantidades de datos. Otra ventaja es que otro código puede usar 
inmediatamente los valores generados por un generador, sin esperar a que se produzca la 
secuencia completa.
Sin embargo, si necesita usar los valores producidos por un generador más de una vez, y si 
generarlos cuesta más que almacenarlos, puede ser mejor almacenar los valores generados 
como una list que volver a generar la secuencia. Consulte 'Restablecer un generador' a 
continuación para obtener más detalles.
Normalmente, un objeto generador se usa en un bucle, o en cualquier función que requiera un 
iterable:
    503/1068
    439
arr1 = list(g1)
# arr1 = [], because the loop above already consumed all the values. 
g2 = function()
arr2 = list(g2) # arr2 = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# Received 0
# Received 1
# Received 4
# Received 9
# Received 16
# Received 25
# Received 36
# Received 49
# Received 64
# Received 81
Comolosobjetosgeneradoressoniteradores,unopuederecorrerlosmanualmenteusandola 
función next() . Al hacerlo, se devolverán los valores cedidos uno por uno en cada invocación 
posterior.
Bajo el capó, cada vez que llama a next() en un generador, Python ejecuta declaraciones en el 
cuerpo de la función del generador hasta que llega a la siguiente declaración de yield . En este 
punto, devuelve el argumento del comando de yield y recuerda el punto en el que ocurrió. Llamar 
a next() una vez más reanudará la ejecución desde ese punto y continuará hasta la próxima 
declaración de yield .
Si Python llega al final de la función del generador sin encontrar más yield , se StopIteration una 
excepción StopIteration (estoesnormal,todos lositeradoressecomportan delamisma manera).
g3 =function() 
a = next(g3) 
b = next(g3)
c = next(g3)
...
j = next(g3)
# a becomes 0 
# b becomes 1 
# c becomes 2
# Raises StopIteration, j remains undefined
TengaencuentaqueenelgeneradorPython2,losobjetosteníanmétodos.next() quesepodían 
usarparaiteraratravésdelosvaloresproducidosmanualmente.EnPython3,estemétodofue 
reemplazado por el estándar . next () para todos los iteradores.
Restablecer un generador
Recuerde que solo puede recorrer los objetos generados por un generador una vez . Si ya ha 
iterado a través de los objetos en una secuencia de comandos, cualquier otro intento de hacerlo 
dará como resultado None .
Si necesita usar los objetos generados por un generador más de una vez, puede definir la función 
del generador de nuevo y usarla por segunda vez, o bien, puede almacenar la salida de la función 
del generador en una lista en el primer uso. Volver a definir la función del generador será una 
buena opción si está manejando grandes volúmenes de datos, y almacenar una lista de todos los 
elementos de datos ocuparía mucho espacio en el disco. A la inversa, si es costoso generar los 
artículos inicialmente, es posible que prefiera almacenar los artículos generados en una lista para
    504/1068
    440
def fib(a=0, b=1):
"""Generator that yields Fibonacci numbers. `a` and `b` are the seed values""" 
while True:
yield a
a, b = b, a + b
f = fib()
print(', '.join(str(next(f)) for _ in range(10)))
def integers_starting_from(n): 
while True:
yield n 
n += 1
natural_numbers = integers_starting_from(1)
natural_numbers = itertools.count(1)
multiples_of_two = (x * 2 for x in natural_numbers) 
multiples_of_three = (x for x in natural_numbers if x % 3 == 0)
list(multiples_of_two) # will never terminate, or raise an OS-specific error
first_five_multiples_of_three = [next(multiples_of_three) for _ in range(5)] 
# [3, 6, 9, 12, 15]
poder reutilizarlos.
Usando un generador para encontrar los números de Fibonacci
Un caso de uso práctico de un generador es recorrer los valores de una serie infinita. Aquí hay un 
ejemplo de cómo encontrar los primeros diez términos de la secuencia de Fibonacci .
0, 1, 1, 2, 3, 5, 8, 13, 21, 34
Secuencias infinitas
Se pueden usar generadores para representar secuencias infinitas:
La secuencia infinita de números como la anterior también se puede generar con la ayuda de
itertools.count . El código anterior se puede escribir como abajo
Puede usar la comprensión del generador en generadores infinitos para producir nuevos 
generadores:
Tenga en cuenta que un generador infinito no tiene un fin, por lo que pasarlo a cualquier función 
que intente consumir el generador por completo tendrá graves consecuencias :
En su lugar, use la lista de listas / conjuntos con range (o xrange para python <3.0):
    505/1068
    441
from itertools import islice
multiples_of_four = (x * 4 for x in integers_starting_from(1)) 
first_five_multiples_of_four = list(islice(multiples_of_four, 5)) 
# [4, 8, 12, 16, 20]
next(natural_numbers) # yields 16 
next(multiples_of_two) # yields 34 
next(multiples_of_four) # yields 24
for idx, number in enumerate(multiplies_of_two): 
print(number)
if idx == 9:
break # stop after taking the first 10 multiplies of two
import itertools
def fibonacci(): 
a, b = 1, 1
while True:
yield a
a, b = b, a + b
first_ten_fibs = list(itertools.islice(fibonacci(), 10)) 
# [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
def nth_fib(n):
return next(itertools.islice(fibonacci(), n - 1, n))
ninety_nineth_fib = nth_fib(99) # 354224848179261915075
def foob(x):
yield from range(x * 2) 
yield from range(2)
list(foob(5)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]
o use itertools.islice() para cortar el iterador en un subconjunto:
Tenga en cuenta que el generador original también se actualiza, al igual que todos los demás 
generadores que vienen de la misma "raíz":
Una secuencia infinita también se puede iterar con un bucle for .Asegúrese de incluir una 
instrucción de break condicional para que el bucle finalice eventualmente:
Ejemplo clásico - números de Fibonacci
Rindiendo todos los valores de otro iterable.
Python 3.x 3.3
Utilice el yield from si desea obtener todos los valores de otro iterable:
    506/1068
    442
def fibto(n):
a, b = 1, 1
while True:
if a >= n: break 
yield a
a, b = b, a + b
def usefib():
yield from fibto(10) 
yield from fibto(20)
list(usefib()) # [1, 1, 2, 3, 5, 8, 1, 1, 2, 3, 5, 8, 13]
# create and advance generator to the first yield 
def coroutine(func):
def start(*args,**kwargs):
cr = func(*args,**kwargs) 
next(cr)
return cr 
return start
# example coroutine 
@coroutine
def adder(sum = 0): 
while True:
x = yield sum 
sum += x
# example use 
s = adder() 
s.send(1) # 1
s.send(2) # 3
from os import listdir
from os.path import isfile, join, exists
Esto funciona también con generadores.
Coroutines
Los generadores pueden ser utilizados para implementar coroutines:
Coroutines se usa comúnmente para implementar máquinas de estado, ya que son 
principalmente útiles para crear procedimientos de un solo método que requieren un estado para 
funcionar correctamente. Operan en un estado existente y devuelven el valor obtenido al finalizar 
la operación.
Rendimiento con recursión: listado recursivo de todos los archivos en un 
directorio
Primero, importa las bibliotecas que trabajan con archivos:
Una función auxiliar para leer solo archivos de un directorio:
    507/1068
    443
def get_directories(path):
for directory in listdir(path): 
full_path = join(path, directory) 
if not isfile(full_path):
if exists(full_path): 
yield full_path
def get_files_recursive(directory): 
for file in get_files(directory):
yield file
for subdirectory in get_directories(directory):
for file in get_files_recursive(subdirectory): # here the recursive call 
yield file
def get_files_recursive(directory): 
yield from get_files(directory)
for subdirectory in get_directories(directory): 
yield from get_files_recursive(subdirectory)
for x, y in zip(a,b): 
print(x,y)
1 x
2 y
3 z
Otra función auxiliar para obtener solo los subdirectorios:
Ahora use estas funciones para obtener recursivamente todos los archivos dentro de un directorio 
y todos sus subdirectorios (usando generadores):
Esta función se puede simplificar utilizando el yield from :
Iterando sobre generadores en paralelo.
Para iterar sobre varios generadores en paralelo, use el zip incorporado:
Resultados en:
EnPython2deberíasusaritertools.izip enitertools.izip lugar. Aquítambiénpodemosverque 
todas las funciones zip producen tuplas.
Tenga en cuenta que zip dejará de iterar tan pronto como uno de los iterables se quede sin 
elementos. Si desea iterar durante el tiempo más largo posible, use itertools.zip_longest() .
def get_files(path):
for file in listdir(path): 
full_path = join(path, file) 
if isfile(full_path):
if exists(full_path): 
yield full_path
    508/1068
    444
def create():
result = []
# logic here...
result.append(value) # possibly in several places 
# more logic...
return result # possibly in several places
values = create()
def create_gen(): 
# logic... 
yield value 
# more logic
return # not needed if at the end of the function, of course
values = list(create_gen())
def preorder_traversal(node): 
yield node.value
for child in node.children:
yield from preorder_traversal(child)
def find_and_transform(sequence, predicate, func): 
for element in sequence:
if predicate(element): 
return func(element)
raise ValueError
item = find_and_transform(my_sequence, my_predicate, my_func)
item = next(my_func(x) for x in my_sequence if my_predicate(x))
# StopIteration will be raised if there are no matches; this exception can 
# be caught and transformed, if desired.
Código de construcción de lista de refactorización
Supongamos que tiene un código complejo que crea y devuelve una lista al comenzar con una 
lista en blanco y agregarla repetidamente:
Cuando no es práctico reemplazar la lógica interna con una lista de comprensión, puede convertir 
toda la función en un generador en el lugar y luego recopilar los resultados:
Si la lógica es recursiva, use el yield from para incluir todos los valores de la llamada recursiva en 
un resultado "aplanado":
buscando
La next función es útil incluso sin iterar. Pasar una expresión del generador a la next es una forma 
rápida de buscar la primera aparición de un elemento que coincida con algún predicado. Código 
de procedimiento como
puede ser reemplazado con:
    509/1068
    445
def first(generator): 
try:
return next(generator) 
except StopIteration:
raise ValueError
Para este propósito,puede ser conveniente crear un alias, como first = next ,o una funciónde 
envoltura para convertir laexcepción:
    510/1068
    446
with EXPR as VAR:
BLOCK
mgr = (EXPR)
exit = type(mgr). exit # Not calling it yet 
value = type(mgr). enter (mgr)
exc = True 
try:
try:
VAR = value #Only if "as VAR" is present 
BLOCK
except:
# The exceptional case is handled here 
exc = False
if not exit(mgr, *sys.exc_info()): 
raise
# The exception is swallowed if exit() returns true
finally:
# The normal and non-local-goto cases are handled here
Capítulo 91: Gestores de contexto 
(declaración “con”)
Introducción
Si bien los administradores de contexto de Python son ampliamente utilizados, pocos entienden el 
propósito detrás de su uso. Estas declaraciones, comúnmente utilizadas con los archivos de 
lectura y escritura, ayudan a la aplicación a conservar la memoria del sistema y mejorar la 
administración de recursos al garantizar que los recursos específicos solo se usan para ciertos 
procesos. Este tema explica y demuestra el uso de los gestores de contexto de Python.
Sintaxis
• con "context_manager" (como "alias") (, "context_manager" (como "alias")?) *:
Observaciones
LosgestoresdecontextosedefinenenPEP343.Estándiseñadosparaserutilizadoscomoun 
mecanismo más sucinto parala administraciónderecursos que el quetry ... finally construye. 
La definición formal es lasiguiente.
En estePEP, los gestores de contexto proporcionan los enter () y exit () que 
se invocan al ingresar y salir del cuerpo de la declaración with.
Luego pasa a definir la instrucción with lo siguiente.
La traducción de la declaración anterior es:
    511/1068
    447
open_file = open(filename) 
with open_file:
file_contents = open_file.read()
# the open_file object has automatically been closed.
with open(filename) as open_file: 
file_contents = open_file.read()
# the open_file object has automatically been closed.
with database_connection as cursor: 
cursor.execute(sql_query)
Examples
Introducción a los gestores de contexto y con la declaración.
Un administrador de contexto es un objeto que se notifica cuando un contexto (un bloque de 
código) comienza y termina . Normalmente se utiliza uno con la instrucción with .Se encarga de 
la notificación.
Por ejemplo, los objetos de archivo son gestores de contexto. Cuando un contexto finaliza, el 
objeto de archivo se cierra automáticamente:
El ejemplo anterior generalmente se simplifica utilizando la palabra clave as :
Cualquier cosa que finalice la ejecución del bloque hace que se llame al método de salida del 
administrador de contexto. Esto incluye excepciones y puede ser útil cuando un error hace que 
salga prematuramente de un archivo abierto o conexión. Salir de un script sin cerrar 
correctamente los archivos / conexiones es una mala idea, ya que puede causar la pérdida de 
datos u otros problemas. Al utilizar un administrador de contexto, puede asegurarse de que 
siempre se tomen precauciones para evitar daños o pérdidas de esta manera. Esta característica 
fue añadida en Python 2.5.
Asignar a un objetivo
Muchosadministradoresdecontextodevuelvenunobjetocuandoseingresa.Puedeasignarese 
objeto a un nuevo nombre en la declaración with .
Por ejemplo, usar una conexión de base de datos en una declaración with podría darle un objeto 
de cursor:
Los objetos de archivo se devuelven solos, esto hace posible abrir el objeto de archivo y usarlo 
como administrador de contexto en una expresión:
if exc:
exit(mgr, None, None, None)
    512/1068
    448
class AContextManager():
def enter (self): 
print("Entered")
# optionally return an object 
return "A-instance"
def exit (self, exc_type, exc_value, traceback):
print("Exited" + (" (with an exception)" if exc_type else "")) 
# return True if you want to suppress the exception
with AContextManager() as a: 
print("a is %r" % a)
# Entered
# a is 'A-instance' 
# Exited
with AContextManager() as a: 
print("a is %d" % a)
# Entered
# Exited (with an exception)
# Traceback (most recent call last):
# File "<stdin>", line 2, in<module>
# TypeError: %d format: a number is required, not str
class MyContextManager: 
def enter (self):
return self
def exit (self): 
print('something')
Escribiendo tu propio gestor de contexto.
Un administrador de contexto es cualquier objeto que implementa dos métodos mágicos
 enter () y exit () (aunque también puede implementar otros métodos):
Si el contexto sale con una excepción, la información sobre esa excepción se pasa como un triple
exc_type , exc_value , traceback (estas son las mismas variables que devuelve el sys.exc_info()
función). Si el contexto sale normalmente, los tres de estos argumentos serán None .
Si ocurre una excepción y se pasa al método exit , el método puede devolver True para 
suprimir la excepción, o la excepción volverá a presentarse al final de la función exit .
Tenga en cuenta que en el segundo ejemplo, a pesar de que se produce una excepción en medio 
del cuerpo de la instrucción with, el controlador exit aún se ejecuta, antes de que la 
excepción se propague al ámbito externo.
Si solo necesita un método exit , puede devolver la instancia del administrador de contexto:
with open(filename) as open_file: 
file_contents = open_file.read()
    513/1068
    449
import contextlib
@contextlib.contextmanager 
def context_manager(num):
print('Enter') 
yield num + 1 
print('Exit')
with context_manager(2) as cm:
# the following instructions are run when the 'yield' point of the context 
# manager is reached.
# 'cm' will have the value that was yielded 
print('Right in the middle with cm = {}'.format(cm))
Enter
Right in the middle with cm = 3 
Exit
@contextlib.contextmanager
def error_handling_context_manager(num): 
print("Enter")
try:
yield num + 1
except ZeroDivisionError: 
print("Caught error")
finally:
print("Cleaning up") 
print("Exit")
with error_handling_context_manager(-1) as cm: 
print("Dividing by cm = {}".format(cm)) 
print(2 / cm)
Escribiendo tu propio administrador de contexto usando la sintaxis del 
generador.
Tambiénesposibleescribirunadministradordecontextousandolasintaxisdelgeneradorgracias 
al decorador contextlib.contextmanager :
produce:
El decorador simplifica la tarea de escribir un administrador de contexto al convertir un generador 
en uno. Todo antes de que la expresión de rendimiento se convierta en el método enter , el 
valor generado se convierta en el valor devuelto por el generador (que se puede vincular a una 
variable en la declaración with), y todo después de la expresión de rendimiento se convierte en el 
método exit
Si el administrador de contexto debe manejar una excepción, se puede escribir un 
try..except..finally try..except..finally en el generador, y este bloque de excepción manejará 
cualquier excepción que se genere en el bloque with .
Esto produce:
    514/1068
    450
with open(input_path) as input_file, open(output_path, 'w') as output_file: 
# do something with both files.
# e.g. copy the contents of input_file into output_file 
for line in input_file:
output_file.write(line + '\n')
with open(input_path) as input_file:
with open(output_path, 'w') as output_file: 
for line in input_file:
output_file.write(line + '\n')
class File():
def init (self, filename, mode): 
self.filename = filename 
self.mode = mode
def enter (self):
self.open_file = open(self.filename, self.mode) 
return self.open_file
def exit (self, *args): 
self.open_file.close()
for _ in range(10000):
with File('foo.txt', 'w') as f: 
f.write('foo')
Gestores de contexto multiples
Puede abrir varios gestores de contenido al mismo tiempo:
Tiene el mismo efecto que los administradores de contexto de anidamiento:
Gestionar recursos
 init () configuraelobjeto,enestecaso,configuraelnombredelarchivoyelmodoparaabrir 
el archivo. enter () abre y devuelve el archivo y exit () simplemente locierra.
El uso de estos métodos mágicos ( enter , exit )lepermiteimplementarobjetos que se 
pueden usar fácilmente with la instrucción with.
Usar clase de archivo:
Enter
Dividing by cm = 0 
Caught error 
Cleaning up
Exit
    515/1068
    451
    516/1068
    452
import turtle
ninja = turtle.Turtle() 
ninja.speed(10)
for i in range(180): 
ninja.forward(100) 
ninja.right(30) 
ninja.forward(20) 
ninja.left(60) 
ninja.forward(50) 
ninja.right(30)
ninja.penup() 
ninja.setposition(0, 0) 
ninja.pendown()
ninja.right(2) 
turtle.done()
Capítulo 92: Gráficos de tortuga
Examples
Ninja Twist (Tortuga Gráficos)
Aquí una Tortuga Gráficos Ninja Twist:
    517/1068
    453
hash.sha1()
hash.update(arg)
hash.digest()
hash.hexdigest()
Capítulo 93: hashlib
Introducción
hashlib implementa una interfaz común para muchos algoritmos de resumen de hash y resumen 
de mensajes. Se incluyen los algoritmos de hash seguro FIPS SHA1, SHA224, SHA256, SHA384 
y SHA512.
Examples
Hash MD5 de una cadena
Este módulo implementa una interfaz común para muchos algoritmos de resumen de hash y 
resumen de mensajes. Se incluyen los algoritmos hash seguros SHA1, SHA224, SHA256, 
SHA384 y SHA512 de FIPS (definidos en FIPS 180-2), así como el algoritmo MD5 de RSA 
(definido en Internet RFC 1321).
Hay un método constructor nombrado para cada tipo de hash. Todos devuelven un objeto hash 
con la misma interfaz simple. Por ejemplo: use sha1() para crear un objeto hash SHA1.
Los constructores de algoritmos hash que siempre están presentes en este módulo son md5() ,
sha1() , sha224() , sha256() , sha384() y sha512() .
Ahorapuedealimentar esteobjetoconcadenasarbitrariasusandoel métodoupdate().En 
cualquier momento,puedesolicitarelresumende laconcatenacióndelas cadenas que se lehan 
suministrado utilizando los métodos digest() o hexdigest().
Actualice el objeto hash con la cadena arg. Las llamadas repetidas son equivalentes a 
una sola llamada con la concatenación de todos los argumentos: m.update (a); 
m.update (b) es equivalente a m.update (a + b).
Devuelva el resumen de las cadenas pasadas al método update () hasta el momento. 
Esta es una cadena de bytes digest_size que pueden contener caracteres no ASCII, 
incluidos los bytes nulos.
Al igual que digest () excepto que el resumen se devuelve como una cadena de doble 
longitud, que contiene solo dígitos hexadecimales. Esto se puede usar para
    518/1068
    454
>>> import hashlib
>>> m = hashlib.md5()
>>> m.update("Nobody inspects")
>>> m.update(" the spammish repetition")
>>> m.digest() 
'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
>>> m.hexdigest() 
'bb649c83dd1ea5c9d9dec9a18df0ffe9'
>>> m.digest_size 
16
>>> m.block_size 
64
hashlib.md5("Nobody inspects the spammish repetition").hexdigest() 
'bb649c83dd1ea5c9d9dec9a18df0ffe9'
>>> h = hashlib.new('ripemd160')
>>> h.update("Nobody inspects the spammish repetition")
>>> h.hexdigest() 
'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'
intercambiar el valor de forma segura en el correo electrónico u otros entornos no 
binarios.
Aquí hay un ejemplo:
o:
algoritmo proporcionado por OpenSSL
También existe un constructor new() genérico que toma el nombre de la cadena del algoritmo 
deseado como su primer parámetro para permitir el acceso a los hashes enumerados 
anteriormente, así como a cualquier otro algoritmo que pueda ofrecer su biblioteca OpenSSL. Los 
constructores nombrados son mucho más rápidos que new() y deberían preferirse.
Usando new() con un algoritmo proporcionado por OpenSSL:
    519/1068
    455
import heapq
numbers = [1, 4, 2, 100, 20, 50, 32, 200, 150, 8]
print(heapq.nlargest(4, numbers)) # [200, 150, 100, 50]
print(heapq.nsmallest(4, numbers)) # [1, 2, 4, 8]
people = [
{'firstname': 'John', 'lastname': 'Doe', 'age': 30},
{'firstname': 'Jane', 'lastname': 'Doe', 'age': 25},
{'firstname': 'Janie', 'lastname': 'Doe', 'age': 10},
{'firstname': 'Jane', 'lastname': 'Roe', 'age': 22},
{'firstname': 'Johnny', 'lastname': 'Doe', 'age': 12},
{'firstname': 'John', 'lastname': 'Roe', 'age': 45}
]
oldest = heapq.nlargest(2, people, key=lambda s: s['age']) 
print(oldest)
# Output: [{'firstname': 'John', 'age': 45, 'lastname': 'Roe'}, {'firstname': 'John', 'age': 
30, 'lastname': 'Doe'}]
youngest = heapq.nsmallest(2, people, key=lambda s: s['age']) 
print(youngest)
# Output: [{'firstname': 'Janie', 'age': 10, 'lastname': 'Doe'}, {'firstname': 'Johnny', 
'age': 12, 'lastname': 'Doe'}]
Capítulo 94: Heapq
Examples
Artículos más grandes y más pequeños en una colección.
Para encontrarlos elementos más grandes enuna colección, el módulo heapq tiene una función 
llamada nlargest , le pasamos dos argumentos, el primero es el número de elementos que 
queremos recuperar, el segundo es el nombre de la colección:
De manera similar, para encontrar los elementos más pequeños en una colección, usamos la 
función nsmallest :
Las funciones nlargest y nsmallest toman un argumento opcional (parámetro clave) para 
estructurasde datos complicadas.El siguienteejemplo muestra el uso dela propiedad age para 
recuperar las personas más antiguas y más jóvenes del diccionario de people :
Artículo más pequeño en una colección.
Lapropiedad más interesante de un heap es que su elemento más pequeño es siempre el primer 
elemento: heap[0]
    520/1068
    456
import heapq
numbers = [10, 4, 2, 100, 20, 50, 32, 200, 150, 8]
heapq.heapify(numbers) 
print(numbers)
# Output: [2, 4, 10, 100, 8, 50, 32, 200, 150, 20]
heapq.heappop(numbers) # 2 
print(numbers)
# Output: [4, 8, 10, 100, 20, 50, 32, 200, 150]
heapq.heappop(numbers) # 4 
print(numbers)
# Output: [8, 20, 10, 100, 150, 50, 32, 200]
    521/1068
    457
Capítulo 95: Herramienta 2to3
Sintaxis
• $ 2to3 [-options] ruta / a / archivo.py
Parámetros
Parámetro Descripción
nombre de archivo / 
nombre_directorio
2to3 acepta una lista de archivos o directorios que se va a 
transformar como su argumento. Los directorios se 
recursivamente recorren para las fuentes de Python.
Opción Opción Descripción
-f FIX, --fix = FIX Especificartransformacionesaaplicar;pordefecto:todos.Listar 
las transformaciones disponibles con--list-fixes
-j PROCESOS, --
procesos = PROCESOS Ejecutar 2to3 al mismo tiempo
-x NOFIX, --nofix = 
NOFIX Excluir una transformación
-l, --list-fixes Listar las transformaciones disponibles
-p, --print-function Cambialagramáticaparaqueprint()seaconsideradauna 
función.
-v, --verbose Salida más detallada
--no-diffs No se muestran datos de la refactorización.
-w Escribir archivos modificados
-n, --nobackups No cree copias de seguridad de archivos modificados
-o OUTPUT_DIR, --
output-dir =
OUTPUT_DIR
Coloque los archivos de salida en este directorio en lugar de 
sobrescribir los archivos de entrada. Requiere la -n , ya que los 
archivos de copia de seguridad no son necesarios cuando los 
archivos de entrada no se modifican.
-W, --write-unchangedfiles
Escribir archivos de salida, incluso si no se requieren cambios. 
Útil con -o para que se traduzca y copie un árbol fuente completo. 
Implica -w .
    522/1068
    458
def greet(name):
print "Hello, {0}!".format(name) 
print "What's your name?"
name = raw_input() 
greet(name)
$ 2to3 example.py
> path/to/2to3.py example.py
RefactoringTool: Skipping implicit fixer: buffer
Parámetro Descripción
--add-suffix = 
ADD_SUFFIX
Especifique una cadenaquese agregaráa todoslosnombres de 
archivo de salida. Requiere -n si no está vacío. Ej .: --addsuffix='3' generará archivos .py3 .
Observaciones
La herramienta 2to3 es un programa de Python que se utiliza para convertir el código escrito en
Python 2.x en el código de Python 3.x. La herramienta lee el código fuente de Python 2.x y aplica 
una serie de reparadores para transformarlo en un código válido de Python 3.x.
La herramienta 2to3 está disponible en la biblioteca estándar como lib2to3, que contiene un 
amplio conjunto de fijadores que manejarán casi todo el código. Dado que lib2to3 es una 
biblioteca genérica, es posible escribir sus propios fijadores para 2to3.
Examples
Uso básico
Considere el siguiente código Python2.x. Guarde el archivo como example.py
Python 2.x 2.0
Enelarchivoanterior,hayvariaslíneasincompatibles.Elmétodoraw_input()sehareemplazado 
coninput()enPython3.xylaprint ya noesunadeclaración, sino unafunción.Este códigose 
puede convertir a código Python 3.x usando la herramienta 2to3.
Unix
Windows
La ejecución del código anterior generará las diferencias con respecto al archivo fuente original, 
como se muestra a continuación.
    523/1068
    459
def greet(name):
print("Hello, {0}!".format(name)) 
print("What's your name?")
name = input() 
greet(name)
$ 2to3 -w example.py
> path/to/2to3.py -w example.py
Las modificaciones se pueden volver a escribir en el archivo de origen utilizando el indicador -w. 
Se crea una copia de seguridad del archivo original llamado example.py.bak , a menos que se 
indique el distintivo -n.
Unix
Windows
Ahora el archivo example.py se ha convertido de Python 2.x al código de Python 3.x. 
Una vez finalizado, example.py contendrá el siguiente código válido de Python3.x: 
Python 3.x 3.0
RefactoringTool: Skipping implicit fixer: idioms 
RefactoringTool: Skipping implicit fixer: set_literal 
RefactoringTool: Skipping implicit fixer: ws_comma 
RefactoringTool: Refactored example.py
---example.py (original)
+++ example.py (refactored) 
@@ -1,5 +1,5 @@
def greet(name):
- print "Hello, {0}!".format(name)
-print "What's your name?"
-name = raw_input()
+ print("Hello, {0}!".format(name))
+print("What's your name?")
+name = input() 
greet(name)
RefactoringTool: Files that need to be modified: 
RefactoringTool: example.py
    524/1068
    460
pip install pydotplus
pip install https://github.com/carlos-jenkins/pydotplus/archive/master.zip
import pydotplus
graph_a = pydotplus.graph_from_dot_file('demo.dot') 
graph_a.write_svg('test.svg') # generate graph in svg.
Capítulo 96: herramienta grafica
Introducción
Las herramientas de python se pueden usar para generar graficos.
Examples
PyDotPlus
PyDotPlus es una versión mejorada del antiguo proyecto pydot que proporciona una interfaz 
Python al lenguaje Dot de Graphviz.
Instalación
Para la última versión estable:
Para la versión de desarrollo:
Cargar gráfico como se define por un archivo DOT
• Se asume que el archivo está en formato DOT. Se cargará, se analizará y se devolverá una 
clase Dot, que representa el gráfico. Por ejemplo, un simple demo.dot:
digraph demo1 {a -> b -> c; c -> a; }
Obtendrá un svg (gráficos vectoriales escalables) como este:
    525/1068
    461
import pygraphviz as pgv
G = pgv.AGraph("demo.dot") 
G.draw('test', format='svg', prog='dot')
PyGraphviz
Obtenga PyGraphviz del Índice de Paquetes de Python en http://pypi.python.org/pypi/pygraphviz
O instálalo con:
pip install pygraphviz
y se intentará encontrar e instalar una versión adecuada que coincida con su sistema operativo y 
la versión de Python.
Puede instalar la versión de desarrollo (en github.com) con:
pip install git://github.com/pygraphviz/pygraphviz.git#egg=pygraphviz
Obtenga PyGraphviz del Índice de Paquetes de Python en http://pypi.python.org/pypi/pygraphviz
O instálalo con:
easy_install pygraphviz
y se intentará encontrar e instalar una versión adecuada que coincida con su sistema operativo y 
la versión de Python.
Cargar gráfico como se define por un archivo DOT
• Se asume que el archivo está en formato DOT. Se cargará, se analizará y se devolverá una 
clase Dot, que representa el gráfico. Por ejemplo, un simple demo.dot:
digraph demo1 {a -> b -> c; c -> a; }
• Cárgalo y dibújalo.
Obtendrá un svg (gráficos vectoriales escalables) como este:
    526/1068
    462
    527/1068
    463
import ijson
def load_json(filename):
with open(filename, 'r') as fd: 
parser = ijson.parse(fd) 
ret = {'builders': {}}
for prefix, event, value in parser:
if (prefix, event) == ('builders', 'map_key'): 
buildername = value 
ret['builders'][buildername] = {}
elif prefix.endswith('.shortname'): 
ret['builders'][buildername]['shortname'] = value
return ret
if name == " main ": 
load_json('allthethings.json')
Capítulo 97: ijson
Introducción
ijson es una excelente biblioteca para trabajar con archivos JSON en Python. 
Desafortunadamente, de forma predeterminada, utiliza un analizador Python JSON puro como su 
backend. Se puede lograr un rendimiento mucho mayor utilizando un backend C.
Examples
Ejemplo simple
Ejemplo de ejemplo Tomado de un punto de referencia
ENLACE DE ARCHIVO JSON
    528/1068
    464
print "Hello World!"
import clr
from System import Console 
Console.WriteLine("Hello World!")
Capítulo 98: Implementaciones no oficiales 
de Python
Examples
IronPython
Implementación de código abierto para .NET y Mono escrito en C #, con licencia de Apache 
License 2.0. Se basa en DLR (Dynamic Language Runtime). Sólo es compatible con la versión 
2.7, la versión 3 se está desarrollando actualmente.
Diferencias con CPython:
• Integración estrecha con .NET Framework.
• Las cadenas son Unicode por defecto.
• No admite extensiones para CPython escritas en C.
• No sufre de Global Intérprete Lock.
• El rendimiento suele ser menor, aunque depende de las pruebas.
Hola Mundo
También puedes usar las funciones .NET:
enlaces externos
• Sitio web oficial
• Repositorio GitHub
Jython
Implementación de código abierto para JVM escrita en Java, con licencia de Python Software 
Foundation License. Sólo es compatible con la versión 2.7, la versión 3 se está desarrollando 
actualmente.
Diferencias con CPython:
    529/1068
    465
print "Hello World!"
from java.lang import System 
System.out.println("Hello World!")
• Integración estrecha con JVM.
• Las cuerdas son Unicode.
• No admite extensiones para CPython escritas en C.
• No sufre de Global Intérprete Lock.
• El rendimiento suele ser menor, aunque depende de las pruebas.
Hola Mundo
También puedes usar las funciones de Java:
enlaces externos
• Sitio web oficial
• Repositorio mercurial
Transcrypt
Transcrypt es una herramienta para precompilar un subconjunto bastante extenso de Python en 
un Javascript compacto y legible. Tiene las siguientes características:
• Permite la programación OO clásica con herencia múltiple utilizando la sintaxis de Python 
pura, analizada por el analizador nativo de CPython
• Integración perfecta con el universo de bibliotecas de JavaScript de alta calidad orientadas a 
la web, en lugar de las de Python orientadas al escritorio
• Sistema de módulo jerárquico basado en URL que permite la distribución de módulos a 
través de PyPi
• Relación simple entre la fuente Python y el código JavaScript generado para una fácil 
depuración
• Mapas de referencia de niveles múltiples y anotación opcional del código de destino con 
referencias de origen
• Descargas compactas, kB's en lugar de MB's
• Código JavaScript optimizado, que utiliza memoization (almacenamiento en caché de 
llamadas) para omitir opcionalmente la cadena de búsqueda de prototipos
• La sobrecarga del operador se puede activar y desactivar localmente para facilitar las 
matemáticas numéricas legibles
Tamaño y velocidad del código
    530/1068
    466
<script src=" javascript /hello.js"></script>
<h2>Hello demo</h2>
<p>
<div id = "greet">...</div>
<button onclick="hello.solarSystem.greet ()">Click me repeatedly!</button>
<p>
<div id = "explain">...</div>
<button onclick="hello.solarSystem.explain ()">And click me repeatedly too!</button>
from itertools import chain
class SolarSystem:
planets = [list (chain (planet, (index + 1,))) for index, planet in enumerate (( 
('Mercury', 'hot', 2240),
('Venus', 'sulphurous', 6052),
('Earth', 'fertile', 6378),
('Mars', 'reddish', 3397),
('Jupiter', 'stormy', 71492),
('Saturn', 'ringed', 60268),
('Uranus', 'cold', 25559), 
('Neptune', 'very cold', 24766)
))]
lines = (
'{} is a {} planet',
'The radius of {} is {} km',
'{} is planet nr. {} counting from the sun'
)
def init (self): 
self.lineIndex = 0
def greet (self):
self.planet = self.planets [int (Math.random () * len (self.planets))] 
document.getElementById ('greet') .innerHTML = 'Hello {}'.format (self.planet [0]) 
self.explain ()
def explain (self):
document.getElementById ('explain').innerHTML = (
self.lines [self.lineIndex] .format (self.planet [0], self.planet [self.lineIndex
+ 1])
)
self.lineIndex = (self.lineIndex + 1) % 3
La experiencia ha demostrado que 650 kB de código fuente de Python se traducen 
aproximadamente en la misma cantidad de código fuente de JavaScript. La velocidad coincide 
con la velocidad del JavaScript manuscrito y puede sobrepasarlo si la memorización de llamadas 
está activada.
Integración con HTML
Integración con JavaScript y DOM
    531/1068
    467
class A:
def init (self, x): 
self.x = x
def show (self, label):
print ('A.show', label, self.x)
class B:
def init (self, y):
alert ('In B constructor') 
self.y = y
def show (self, label):
print ('B.show', label, self.y)
class C (A, B):
def init (self, x, y): alert 
('In Cconstructor') A. 
init (self, x)
B. init (self, y) 
self.show ('constructor')
def show (self, label): 
B.show (self, label)
print ('C.show', label, self.x, self.y)
a = A (1001)
a.show ('america')
b = B (2002)
b.show ('russia')
c = C (3003, 4004)
c.show ('netherlands')
show2 = c.show 
show2 ('copy')
Integración con otras bibliotecas de 
JavaScript
Transcrypt se puede utilizar en combinación con cualquier biblioteca de JavaScript sin medidas ni 
sintaxis especiales. En la documentación se dan ejemplos para ao react.js, riot.js, fabric.js y 
node.js.
Relación entre Python y código JavaScript
Pitón
JavaScript
solarSystem = SolarSystem ()
    532/1068
    468
enlaces externos
• Sitio web oficial: http://www.transcrypt.org/
• Repositorio: https://github.com/JdeH/Transcrypt
var A = class ('A', [object], {
get init () {return get (this, function (self, x) { 
self.x = x;
});},
get show (){return get (this, function (self, label) { 
print ('A.show', label, self.x);
});}
});
var B = class ('B', [object], {
get init () {return get (this, function (self, y) { 
alert ('In B constructor');
self.y = y;
});},
get show (){return get (this, function (self, label) { 
print ('B.show', label, self.y);
});}
});
var C = class ('C', [A, B], {
get init () {return get (this, function (self, x, y) { 
alert ('In C constructor');
A. init (self, x);
B. init (self, y); 
self.show ('constructor');
});},
get show () {return get (this, function (self, label) { 
B.show (self, label);
print ('C.show', label, self.x, self.y);
});}
});
var a = A (1001); 
a.show ('america'); 
var b = B (2002); 
b.show ('russia');
var c = C (3003, 4004);
c.show ('netherlands'); 
var show2 = c.show; 
show2 ('copy');
    533/1068
    469
>>> import random
>>> print(random.randint(1, 10))
4
>>> import random as rn
>>> print(rn.randint(1, 10))
4
import custom
Capítulo 99: Importando modulos
Sintaxis
• importar nombre_módulo
• import module_name.submodule_name
• desde nombre_módulo import *
• from module_name import submodule_name [, class_name , function_name , ... etc]
• desde nombre_módulo importar nombre_algunos como nuevo_nombre
• from module_name.submodule_name import class_name [, function_name , ... etc]
Observaciones
Importar un módulo hará que Python evalúe todo el código de nivel superior en este módulo para 
que aprenda todas las funciones, clases y variables que contiene el módulo. Cuando desee que 
un módulo suyo se importe en otro lugar, tenga cuidado con su código de nivel superior y if
 name == ' main ': en if name =='main':sinodeseaqueseejecutecuandose 
importe el módulo.
Examples
Importando un modulo
Utilice la declaración de import :
import module importará un módulo y luego le permitirá hacer referencia a sus objetos (valores, 
funciones y clases, por ejemplo) utilizando la sintaxis module.name . En el ejemplo anterior, se 
importa el módulo random , que contiene la función randint . Entonces, al importar random , puede 
llamar a randint con random.randint .
Puedes importar un módulo y asignarlo a un nombre diferente:
Si su archivo python main.py está en la misma carpeta que custom.py . Puedes importarlo así:
También es posible importar una función desde un módulo:
    534/1068
    470
from urllib.request import urlopen
from hello import function 
from world import function
function() #world's function will be invoked. Not hello's
import hello 
import world
hello.function() # exclusively hello's function will be invoked 
world.function() # exclusively world's function will be invoked
>>> # Multiple modules
>>> import time, sockets, random
>>> # Multiple functions
>>> from math import sin, cos, tan
>>> # Multiple constants
>>> from math import pi, e
>>> print(pi) 
3.141592653589793
>>> print(cos(45)) 
0.5253219888177297
>>> print(time.time()) 
1482807222.7240417
>>> from urllib.request import urlopen as geturl, pathname2url as path2url, getproxies
>>> from math import factorial as fact, gamma, atan as arctan
>>> import random.randint, time, sys
Para importar funciones específicas más profundamente en un módulo, el operador de punto se 
puede usar solo en el lado izquierdo de la palabra clave de import :
En Python, tenemos dos formas de llamar a la función desde el nivel superior. Uno es import y 
otro es from . Debemos utilizar la import cuando tenemos la posibilidad de colisión de nombres. 
Supongamos que tenemos el archivo hello.py y los archivos world.py que tienen la misma función 
llamada function . Entonces la declaración de import funcionará bien.
En general la import le proporcionará un espacio de nombres.
Pero si está lo suficientemente seguro, en todo su proyecto no hay forma de tener el mismo 
nombre de función que debe usar from declaración
Múltiples importaciones se pueden hacer en la misma línea:
Las palabras clave y la sintaxis que se muestran arriba también se pueden usar en 
combinaciones:
>>> from math import sin
>>> sin(1) 
0.8414709848078965
    535/1068
    471
fromrandomimportrandint#Syntax"fromMODULENAMEimportNAME1[,NAME2[,...]]" 
print(randint(1, 10)) # Out: 5
# Out: 3.14159265359
frommath import pi 
print(pi)
random.randrange(1, 10) # works only if "import random" has been run before
NameError: name 'random' is not defined
import random 
random.randrange(1, 10)
from module_name import *
from math import *
sqrt(2) # instead of math.sqrt(2) 
ceil(2.7) # instead of math.ceil(2.7)
Importando nombres específicos desde un módulo
En lugar de importar el módulo completo, solo puede importar nombres específicos:
senecesitadeformafrom random ,porqueelintérpretedepythondebesaberdequérecursodebe 
importar una función o clase y import randint especifica la función o la clase en sí.
Otro ejemplo a continuación (similar al anterior):
El siguiente ejemplo generará un error, porque no hemos importado un módulo:
Salidas:
El intérprete de python no entiende lo que quieres decir con random . Debe declararse agregando
import random al ejemplo:
Importando todos los nombres de un módulo
por ejemplo:
>>> print(time.time()) 
1482807222.7240417
>>> print(arctan(60)) 
1.554131203080956
>>> filepath = "/dogs/jumping poodle (december).png"
>>> print(path2url(filepath))
/dogs/jumping%20poodle%20%28december%29.png
    536/1068
    472
def sqrt(num):
print("I don't know what's the square root of {}.".format(num))
sqrt(4)
# Output: I don't know what's the square root of 4.
from math import * 
sqrt(4)
# Output: 2.0
def f():
from math import *
class A:
from math import *
SyntaxError: import * only allowed at module level
# mymodule.py
 all = ['imported_by_star'] 
imported_by_star = 42
not_imported_by_star = 21
>>> from mymodule import *
Esto importará todos los nombres definidos en el módulo math en el espacio de nombres global, 
excepto los nombres que comienzan con un guión bajo (lo que indica que el escritor siente que es 
solo para uso interno).
Advertencia :si una función con el mismo nombre yasedefinió oimportó, se sobrescribirá . 
Casi siempre importando solo nombres específicos from math import sqrt, ceil es la forma 
recomendada :
Las importaciones destacadas solo se permiten a nivel de módulo. Los intentos de realizarlas en 
definiciones de clase o función dan como resultado un SyntaxError .
y
ambos fallan con:
La variable especial all
Los módulos pueden tener una variable especial llamada all para restringir qué variables se 
importan cuando se usan from mymodule import * .
Dado el siguiente módulo:
Sólo imported_by_star ha sido importada cuando se utiliza from mymodule import * :
    537/1068
    473
>>> from mymodule import not_imported_by_star
>>> not_imported_by_star 
21
import importlib
random = importlib.import_module("random")
collections_abc = importlib.import_module("collections.abc")
Sin embargo, not_imported_by_star se puede importar explícitamente:
Importación programática
Python 2.x 2.7
Para importar un módulo a través de una llamada de función, use el módulo importlib (incluido en 
Python a partir de la versión 2.7):
La función importlib.import_module() también importará el submódulo de un paquete 
directamente:
Para versiones anteriores de Python, use el módulo imp . 
Python 2.x 2.7
Utilice las funciones imp.find_module y imp.load_module para realizar una importación programática. 
Tomado de la documentación de la biblioteca estándar
NOuse import()paraimportar módulosmedianteprogramación.Haydetallessutiles 
relacionadosconsys.modules,elargumentofromlist,etc.quesonfácilesdepasarporalto,que 
importlib.import_module() maneja por ti.
Importar módulos desde una ubicación de sistema de archivos arbitraria.
import imp, sys
def import_module(name):
fp, pathname, description = imp.find_module(name) 
try:
return imp.load_module(name, fp, pathname, description) 
finally:
if fp:
fp.close()
>>> imported_by_star 
42
>>> not_imported_by_star 
Traceback (most recent calllast):
File "<stdin>", line 1, in <module>
NameError: name 'not_imported_by_star' is not defined
    538/1068
    474
import sys 
sys.path.append("/path/to/directory/containing/your/module") 
import mymodule
from module.submodule import function
if user_input == "os": 
os = import ("os")
Si deseaimportarun móduloqueyanoexistecomo un módulointegrado enlaBiblioteca
estándardePythonni comounpaqueteadicional,puedehacerloagregandolarutaal directorio 
donde se encuentra su módulo a sys.path Esto puede ser útil cuando existen varios entornos de 
Python en un host.
Es importante que agregue la ruta al directorio en el que se encuentra mymodule , no la ruta al 
módulo en sí.
Reglas PEP8 para Importaciones
Algunas pautas de estilo PEP8 recomendadas para importaciones:
1. Las importaciones deben ser en líneas separadas:
from math import sqrt, ceil 
from math importsqrt
from math import ceil
# Not recommended 
# Recommended
2. Ordene las importaciones de la siguiente manera en la parte superior del módulo:
• Importaciones de la biblioteca estándar
• Importaciones de terceros relacionados
• Importaciones específicas de aplicaciones / bibliotecas locales
3. Se deben evitar las importaciones de comodines ya que genera confusión en los nombres 
en el espacio de nombres actual. Si lo hace from module import * , puede no estar claro siun 
nombre específico en su código proviene de module o no.Esto es doblemente cierto si tiene 
múltiples declaraciones from module import * -type.
4. Evite el uso de importaciones relativas; usa importaciones explícitas en su lugar.
Importando submódulos
Esto importa la function desde module.submodule .
importar () función
La función import () se puede usar para importar módulos donde el nombre solo se conoce en 
tiempo de ejecución
    539/1068
    475
# 3.141592653589793
# 3
import math 
math.pi = 3 
print(math.pi) 
reload(math) 
print(math.pi)
mod = import (r"C:/path/to/file/anywhere/on/computer/module.py")
# 3
# 3
import math 
math.pi = 3 
print(math.pi) 
import math
print(math.pi)
if 'math' in sys.modules: # Is the ``math`` module in the register? 
del sys.modules['math'] # If so, remove it.
import math
print(math.pi) # 3.141592653589793
print(math.pi) # 3
import sys
Esta función también se puede utilizar para especificar la ruta del archivo a un módulo
Reimportando un módulo
Cuando utilice el intérprete interactivo, es posible que desee volver a cargar un módulo. Esto 
puede ser útil si está editando un módulo y desea importar la versión más reciente, o si ha 
modificado un elemento de un módulo existente y desea revertir sus cambios.
Tenga en cuenta que no puede volver a import el módulo para revertir:
Esto se debe a que el intérprete registra todos los módulos que importa. Y cuando intenta 
reimportar un módulo, el intérprete lo ve en el registro y no hace nada. Por lo tanto, la manera 
más difícil de reimportar es usar la import después de eliminar el elemento correspondiente del 
registro:
Pero hay más de una manera directa y sencilla.
Python 2
Utilice la función de reload : 
Python 2.x 2.3
Python 3
# equivalent to import os
    540/1068
    476
from importlib import reload 
reload(math)
print(math.pi) # 3.141592653589793
# 3
import math 
math.pi = 3 
print(math.pi)
La función de reload ha movido a importlib :
Python 3.x 3.0
    541/1068
    477
from future import print_function
# other imports and instructions go after future
print('Hello world')
Capítulo 100: Incompatibilidades que se 
mueven de Python 2 a Python 3
Introducción
A diferencia de la mayoría de los idiomas, Python admite dos versiones principales. Desde 2008, 
cuando se lanzó Python 3, muchos han hecho la transición, mientras que muchos no lo han 
hecho. Para entender ambos, esta sección cubre las diferencias importantes entre Python 2 y 
Python 3.
Observaciones
Actualmente hay dos versiones compatibles de Python: 2.7 (Python 2) y 3.6 (Python 3). Además, 
las versiones 3.3 y 3.4 reciben actualizaciones de seguridad en formato de origen.
Python 2.7 es compatible con versiones anteriores de la mayoría de las versiones anteriores de 
Python, y puede ejecutar el código de Python desde la mayoría de las versiones 1.xy 2.x de 
Python sin cambios. Está ampliamente disponible, con una extensa colección de paquetes.
También es considerado obsoleto por los desarrolladores de CPython, y recibe solo seguridad y 
desarrollo de corrección de errores. Los desarrolladores de CPython tienen la intención de 
abandonar esta versión del lenguaje en 2020 .
De acuerdo con la Propuesta 373 de mejora de Python, no hay lanzamientos futuros planeados 
de Python 2 después del 25 de junio de 2016, pero las correcciones de errores y las 
actualizaciones de seguridad serán compatibles hasta 2020. (No especifica cuál será la fecha 
exacta en 2020 para la fecha de caducidad de Python 2.)
Python 3 rompió intencionalmente la compatibilidad con versiones anteriores, para abordar las 
preocupaciones que los desarrolladores de idiomas tenían con el núcleo del lenguaje. Python 3 
recibe nuevos desarrollos y nuevas características. Es la versión del lenguaje con la que los 
desarrolladores del lenguaje pretenden avanzar.
Durante el tiempo entre la versión inicial de Python 3.0 y la versión actual, algunas características 
de Python 3 se portaron en Python 2.6, y otras partes de Python 3 se ampliaron para tener una 
sintaxis compatible con Python 2. Por lo tanto, es posible escribir Python que funcionará tanto en 
Python 2 como en Python 3, mediante el uso de futuras importaciones y módulos especiales 
(como seis ).
Las importaciones futuras deben estar al comienzo de su módulo:
Para obtener más información sobre el módulo future , consulte la página correspondiente en
    542/1068
    478
# null string for sep: prints as ABC
# flush the output buffer, added in Python 3.3 
# print space-separated arguments: "1 2 3"
# print tuple "(1, 2, 3)"
print("Flush this", flush=True) 
print(1, 2, 3)
print((1, 2, 3))
print("Comma", "separated", "output", sep=",") # sep specifies the separator 
print("A", "B", "C", sep="")
# print a newline (must use parentheses)
# end specifies what to append (defaults to newline) 
# file specifies the output buffer
print "Hello World" # SyntaxError
print("Hello World") 
print()
print("No newline", end="") 
print("Error", file=sys.stderr)
print "Hello World"
print # print a newline
print "No newline", # add trailing comma to remove newline 
print >>sys.stderr, "Error" # print to stderr
print("hello") # print "hello", since ("hello") == "hello"
print() # print an empty tuple "()"
print 1, 2, 3 # print space-separated arguments: "1 2 3"
print(1, 2, 3) # print tuple "(1, 2, 3)"
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
la documentación de Python .
La herramienta 2to3 es un programa de Python que convierte el código de Python 2.x en el 
código de Python 3.x; consulte también la documentación de Python .
El paquete seis proporciona utilidades para la compatibilidad con Python 2/3:
• Acceso unificado a bibliotecas renombradas
• variables para los tipos de cadena / Unicode
• Funciones para el método que se eliminó o se ha renombrado.
Una referencia para las diferencias entre Python 2 y Python 3 se puede encontrar aquí .
Examples
Declaración de impresión vs. función de impresión
En Python 2, print es una declaración:
Python 2.x 2.7
En Python 3, print() es una función, con argumentos de palabras clave para usos comunes: 
Python 3.x 3.0
La función de impresión tiene los siguientes parámetros:
sep es lo que separa los objetos que pasas para imprimir. Por ejemplo:
    543/1068
    479
print('foo', 'bar', end='!') # out: foo bar!
print('foo', end='~') 
print('bar')
# out: foo~bar
from future import print_function
s = 'Cafe' # type(s) == str
s = u'Café' # type(s) == unicode 
b = 'Lorem ipsum' # type(b) == str
end es lo que sigue el final de la declaración de impresión. Por ejemplo:
La impresión de nuevo después de una declaración de impresión final que no sea de nueva línea
se imprimirá en la misma línea:
Nota: Para compatibilidad futura, print función de print también está disponible en Python 2.6 en 
adelante; sin embargo, no se puede utilizar a menos que el análisis de la declaración de print se 
deshabilite con
Estafunción tieneexactamente el mismoformatoquePython3,excepto quecarecedel 
parámetro de flush .
Ver PEP 3105 para la justificación. 
Cuerdas: Bytes contra Unicode 
Python 2.x 2.7
En Python 2 hay dos variantes de cadena: las de bytes con tipo ( str ) y las de texto con tipo (
unicode ).
EnPython 2, un objeto de tipo str es siempre una secuencia de bytes, pero se usa comúnmente 
tanto para texto como para datos binarios.
Un literal de cadena se interpreta como una cadena de bytes.
Hay dos excepciones: Puedes definir un literal de Unicode (texto) explícitamente prefijando el 
literal con u :
Alternativamente, puede especificar que los literales de cadena de un módulo completo deberían 
crear literales Unicode (texto):
print('foo', 'bar', sep='~') # out: foo~bar 
print('foo', 'bar', sep='.') # out: foo.bar
    544/1068
    480
isinstance(s, basestring)
# type(s) == str
# type(s) == str (note the accented trailing e)
s = 'Cafe' 
s = 'Café'
# Or, if you really need a byte string: 
s = b'Cafe' # type(s) == bytes 
s = 'Café'.encode() # type(s) == bytes
isinstance(s, str)
u'Cafe' == 'Cafe'
>>> ur'Café'
File "<stdin>", line 1 
ur'Café'
^
SyntaxError: invalid syntax
Para verificar si su variable es una cadena (ya sea Unicode o una cadena de bytes), puede usar:
Python 3.x 3.0
En Python 3, el tipo str es un tipo de texto Unicode.
Además, Python 3 agregó un objeto de bytes , adecuado para "blobs" binarios o escrito en 
archivos independientes de lacodificación.Para crearun objeto de bytes,puedeprefijar b aun 
literal de cadena o llamar al método de encode la cadena:
Para probar si un valor es una cadena, use:
Python 3.x 3.3
También es posible prefijar literales de cadena con un prefijo u para facilitar la compatibilidad 
entre las bases de código de Python 2 y Python 3. Dado que, en Python 3, todas las cadenas son 
Unicode de forma predeterminada, el antepuesto de una cadena literal con u no tiene ningún 
efecto:
Sin embargo, el prefijo ur cadena Unicode sin procesar de Python 2 no es compatible:
Tenga en cuenta que debe encode un objeto de texto ( str ) de Python 3 para convertirlo en una 
representación de bytes de ese texto. La codificación predeterminada de este método es UTF-8 .
Puede usar decode para pedir a un objeto de bytes texto Unicode que representa:
from future import unicode_literals
s = 'Café' # type(s) == unicode
b = 'Lorem ipsum' # type(b) == unicode
    545/1068
    481
from future import unicode_literals 
print(repr("hi"))
# u'hi'
b"abc"[0] == 97
b"abc"[0:1] == b"a"
# -*- coding: utf8 -*-
print("Hi, my name is Łukasz Langa.") 
print(u"Hi, my name is Łukasz Langa."[::-1]) 
print("Hi, my name is Łukasz Langa."[::-1])
# Output in Python 2
# Hi, my name is Łukasz Langa. 
# .agnaL zsakuŁ si eman ym ,iH 
# .agnaL zsaku��si eman ym ,iH
# Output in Python 3
# Hi, my name is Łukasz Langa. 
# .agnaL zsakuŁ si eman ym ,iH 
# .agnaL zsakuŁ si eman ym,iH
Python 2.x 2.6
Mientras que el tipo de bytes existe tanto en Python 2 como en 3, el tipo unicode solo existe en 
Python 2. Para usar las cadenas de Unicode implícitas de Python 3 en Python 2, agregue lo 
siguiente en la parte superior de su archivo de código:
Python 3.x 3.0
Otra diferencia importante es que la indexaciónde bytes enPython 3 da como resultado una 
salida int como:
Mientras se corta en un tamaño de uno, se obtiene un objeto de longitud de 1 bytes:
Además, Python 3 corrige algunos comportamientos inusuales con Unicode, es decir, invierte 
cadenas de bytes en Python 2. Por ejemplo, se resuelve el siguiente problema :
División entera
Elsímbolodedivisiónestándar(/)funcionademaneradiferenteenPython3yPython2 
cuando se aplica a enteros.
CuandosedivideunenteroporotroenteroenPython3,laoperacióndedivisiónx / yrepresenta 
una verdadera división (usa el método truediv ) y produce un resultado de punto flotante.
Mientras tanto, la misma operación en Python 2 representa una división clásica que redondea el 
resultado hacia el infinito negativo (también conocido como tomar el piso ).
>>> b.decode() 
'Café'
    546/1068
    482
# equivalent to `/` in Python 3
from operator import truediv, floordiv
assert truediv(10, 8) == 1.25
Por ejemplo:
Código Salida Python 2 Salida Python 3
3 / 2 1 1.5
2 / 3 0 0.6666666666666666
-3 / 2 -2 -1.5
El comportamiento de redondeo hacia cero fue obsoleto en Python 2.2 , pero permanece en 
Python 2.7 por motivos de compatibilidad con versiones anteriores y se eliminó en Python 3.
Nota:paraobtenerunresultado flotanteenPython2 (sinredondearelpiso)podemosespecificar 
unodelosoperandosconelpuntodecimal.Elejemploanteriorde2/3queda0enPython2se 
usará como 2 / 3.0 o 2.0 / 3 o 2.0/3.0 para obtener 0.6666666666666666
Código Salida Python 2 Salida Python 3
3.0 / 2.0 1.5 1.5
2 / 3.0 0.6666666666666666 0.6666666666666666
-3.0 / 2 -1.5 -1.5
También está el operador de división de piso ( // ), que funciona de la misma manera en 
ambasversiones:seredondeaal entero más cercano.(aunquesedevuelveunflotador cuandose 
usa con flotadores) En ambas versiones, el operador // asigna a floordiv .
Código Salida Python 2 Salida Python 3
3 // 2 1 1
2 // 3 0 0
-3 // 2 -2 -2
3.0 // 2.0 1.0 1.0
2.0 // 3 0.0 0.0
-3 // 2.0 -2.0 -2.0
Uno puede imponer explícitamente la división verdadera o la división de piso usando funciones 
nativas en el módulo del operator :
    547/1068
    483
# needs to be the first statement in a module 
from future import division
Si bien es claro y explícito, el uso de funcionesde operadorpara cada división puede ser tedioso. 
Cambiar el comportamiento del operador / a menudo será preferido. Una práctica común es 
eliminar el comportamiento de división típico agregando la from future import division como la 
primera declaración en cada módulo:
Código Salida Python 2 Salida Python 3
3 / 2 1.5 1.5
2 / 3 0.6666666666666666 0.6666666666666666
-3 / 2 -1.5 -1.5
from future import division garantiza que el operador / representa la división verdadera y 
solo dentro de los módulos que contienen la importación future , porlo queno hayrazones de 
peso para no habilitarla en todos los módulos nuevos.
Nota:Algunosotroslenguajesdeprogramaciónutilizanelredondeohaciacero (truncamiento)en 
lugar de redondearhacia el infinitonegativo comoPython (es decir,enesos idiomas -3 / 2 == -1
). Este comportamiento puede crear confusión al portar o comparar código.
Nota sobre los operandos deflotación :Como alternativa alafrom future import division , 
se podría usar el símbolo de división habitual / y asegurarse de que al menos uno de los 
operandosesunaflotación: 3 / 2.0 == 1.5 .Sinembargo, estopuedeconsiderarseunamala 
práctica. Es demasiado fácil escribir el average = sum(items) / len(items) y olvidarse delanzar uno 
delosargumentosparaflotar.Además,estoscasospuedenevadirconfrecuenciaelaviso 
durantelaspruebas,porejemplo,sirealizapruebasenunamatrizquecontienefloatperorecibe 
una matriz de int s en producción. Además, si se usa el mismo código en Python 3, los 
programasqueesperanque3/23 / 2 == 1 seaVerdaderonofuncionaráncorrectamente.
Vea PEP 238 para una explicación más detallada de por qué se cambió el operador de la división 
en Python 3 y por qué se debe evitar la división de estilo antiguo.
Vea el tema de Matemáticas simples para más información sobre la división.
Reducir ya no es una función incorporada.
En Python 2, reduce está disponible comounafunción incorporada odesdeelpaquetefunctools 
(versión 2.6 enadelante), mientras queen Python 3, reduceestádisponible solo desdefunctools. 
Sin embargo, la sintaxis para reduce tanto en Python2 como en Python3 es la misma y es 
reduce(function_to_reduce, list_to_reduce) .
assert floordiv(10, 8) == 1 # equivalent to `//`
    548/1068
    484
>>> my_list = [1, 2, 3, 4, 5]
>>> import operator
>>> reduce(operator.truediv, my_list)
0.008333333333333333
>>> my_list = [1, 2, 3, 4, 5]
>>> import operator, functools
>>> functools.reduce(operator.truediv, my_list) 
0.008333333333333333
print(range(1, 10))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(isinstance(range(1, 10), list)) 
# Out: True
print(xrange(1, 10)) 
# Out: xrange(1, 10)
print(isinstance(xrange(1, 10), xrange)) 
# Out: True
print(range(1, 10)) 
# Out: range(1, 10)
print(isinstance(range(1, 10), range))
Como ejemplo, consideremos reducir una listaa un solo valor al dividir cada uno de los números 
adyacentes. Aquí usamos la función truediv de la biblioteca del operator .
En Python 2.x es tan simple como:
Python 2.x 2.3
En Python 3.x el ejemplo se vuelve un poco más complicado:
Python 3.x 3.0
También podemos utilizar from functools import reduce para evitar reduce llamadas con el nombre 
del espacio de nombres.
Diferencias entre las funciones de rango y rango
En Python 2, la función de range devuelve una lista, mientras que xrange crea un objeto de xrange 
especial, que es una secuencia inmutable, que a diferencia de otros tipos de secuencia 
incorporados, no admite el corte y no tiene métodos de index ni de count :
Python 2.x 2.3
En Python 3, xrange se expandió a la secuencia de range , que ahora crea un objeto de range . No 
hay tipo xrange :
Python 3.x 3.0
    549/1068
    485
print(range(1, 10)[3:7]) 
# Out: range(3, 7)
print(range(1, 10).count(5)) 
# Out: 1
print(range(1, 10).index(7)) 
# Out: 6
# range(10000000000000000)
# The output would be:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module> 
# MemoryError
print(xrange(100000000000000000)) 
# Out: xrange(100000000000000000)
print(list(range(1, 10)))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]
#forward-compatible
from builtins import range
Además, dado que Python 3.2, el range también admite el corte, index y count :
La ventaja de usar un tipo de secuencia especial en lugar de una lista es que el intérprete no tiene 
que asignar memoria para una lista y llenarla:
Python 2.x 2.3
Como generalmente se desea el último comportamiento, el primero se eliminó en Python 3.Si 
aún desea tener una lista en Python 3, simplemente puede usar el constructor list() en un objeto 
de range :
Python 3.x 3.0
Compatibilidad
Para mantenerla compatibilidadentrelas versionesdePython2.xyPython3.x, puedeusar el 
módulo builtins del future paquete externo para lograr tanto compatibilidad con versiones 
anteriores como compatibilidad con versiones anteriores:
Python 2.x 2.0
# Out: True
# print(xrange(1, 10)) 
# The output will be:
#Traceback (most recent call last): 
# File "<stdin>", line 1, in <module>
#NameError: name 'xrange' is not defined
    550/1068
    486
#backward-compatible
from past.builtins import xrange
for i in xrange(10**8): 
pass
first, second, *tail, last = [1, 2, 3, 4, 5] 
print(first)
# Out: 1 
print(second) 
# Out: 2 
print(tail)
# Out: [3, 4]
print(last) 
# Out: 5
first, second, *tail, last = [1, 2, 3, 4] 
print(tail)
# Out: [3]
first, second, *tail, last = [1, 2, 3] 
print(tail)
# Out: []
print(last) 
# Out: 3
begin, *tail = "Hello" 
print(begin)
# Out: 'H'
print(tail)
Python 3.x 3.0
El range en la biblioteca future admite la segmentación, el index y el count en todas las versiones 
de Python, al igual que el método incorporado en Python 3.2+.
Desembalaje Iterables
Python 3.x 3.0
En Python 3, puedes descomprimir un iterable sin saber la cantidad exacta de elementos que 
contiene, e incluso tener una variable que mantenga el final del iterable. Para eso, proporciona 
una variable que puede recopilar una lista de valores. Esto se hace colocando un asterisco antes 
del nombre. Por ejemplo, desempaquetar una list :
Nota : Al usar la sintaxis de la *variable , la variable siempre será una lista, incluso si el tipo 
original noera unalista.Puede contener cero o máselementos dependiendo del número de 
elementos en la listaoriginal.
Del mismo modo, desempaquetando un str :
for i in range(10**8): 
pass
    551/1068
    487
person = ('John', 'Doe', (10, 16, 2016))
*_, (*_, year_of_birth) = person 
print(year_of_birth)
# Out: 2016
*head, *tail = [1, 2]
# Out: SyntaxError: two starred expressions in assignment
{*range(4), 4, *(5, 6, 7)}
# Out: {0, 1, 2, 3, 4, 5, 6, 7}
iterable = [1, 2, 3, 4, 5] 
print(iterable)
# Out: [1, 2, 3, 4, 5]
print(*iterable)
# Out: 1 2 3 4 5
tail = {'y': 2, 'z': 3}
{'x': 1, **tail}
# Out: {'x': 1, 'y': 2, 'z': 3}
dict1 = {'x': 1, 'y': 1}
dict2 = {'y': 2, 'z': 3}
{**dict1, **dict2}
# Out: {'x': 1, 'y': 2, 'z': 3}
Ejemplo de desempaquetar una date ; _ se utiliza en este ejemplo como una variable desechable 
(solo nos interesa el valor del year ):
Vale la pena mencionar que, dado que * consume una cantidad variable de elementos, no puede 
tener dos * s para el mismo iterable en una asignación; no sabría cuántos elementos entran en el 
primer desempaquetado y cuántos en el segundo :
Python 3.x 3.5
Hasta ahora hemos discutido el desempaquetado en las tareas. * y ** se extendieron en Python
. Ahora es posible tener varias operaciones de desempaquetado en una expresión:
Python 2.x 2.0
También es posible descomprimir un iterable en argumentos de función:
Python 3.x 3.5
Desembalar un diccionario usa dos estrellas adyacentes ** ( PEP 448 ):
Esto permite anular valores antiguos y fusionar diccionarios.
Python 3.x 3.0
# Out: ['e', 'l', 'l', 'o']
    552/1068
    488
try:
raise IOError, "input/output error" 
except IOError, exc:
print exc
# Works in Python 2, but syntax error in Python 3: 
map(lambda (x, y): x + y, zip(range(5), range(5))) 
# Same is true for non-lambdas:
def example((x, y)): 
pass
# Works in both Python 2 and Python 3:
map(lambda x: x[0] + x[1], zip(range(5), range(5))) 
# And non-lambdas, too:
def working_example(x_y): 
x, y = x_y
pass
try:
raise IOError("input/output error") 
except IOError as exc:
print(exc)
try:
file = open('database.db') 
except FileNotFoundError as e:
raise DatabaseError('Cannot open {}') from e
Python 3 eliminó el desempaquetado de tuplas en las funciones. Por lo tanto lo siguiente no 
funciona en Python 3
Ver PEP 3113 para una explicación detallada.
Levantando y manejando excepciones
EstaeslasintaxisdePython2,tengaencuentalascomas,enlaslíneasderaise yexcept : 
Python 2.x 2.3
En Python 3, el , la sintaxis se deja caer y se sustituye por el paréntesis y as palabra clave:
Para la compatibilidad con versiones anteriores, la sintaxis de Python 3 también está disponible 
en Python 2.6 en adelante, por lo que debe usarse para todo el código nuevo que no necesita ser 
compatible con versiones anteriores.
Python 3.x 3.0
Python 3 también agrega el encadenamiento de excepciones , en el que puede indicar que alguna 
otra excepción fue la causa de esta excepción. Por ejemplo
La excepción generada en la declaración de except es de tipo DatabaseError , pero la excepción 
original está marcada como el atributo cause de esa excepción. Cuando se muestra el rastreo,
    553/1068
    489
Traceback (most recent call last): 
File "<stdin>", line 2, in<module>
FileNotFoundError
The above exception was the direct cause of the following exception: 
Traceback (most recent call last):
File "<stdin>", line 4, in <module> 
DatabaseError('Cannot open database.db')
try:
file = open('database.db') 
except FileNotFoundError as e:
raise DatabaseError('Cannot open {}')
Traceback (most recent call last): 
File "<stdin>", line 2, in<module>
FileNotFoundError
During handling of the above exception, another exception occurred: 
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')
import sys 
import traceback
try:
funcWithError() 
except:
sys_vers = getattr(sys, 'version_info', (0,)) 
if sys_vers < (3, 0):
traceback.print_exc()
raise Exception("new exception")
try:
file = open('database.db') 
except FileNotFoundError as e:
la excepción original también se mostrará en el rastreo:
Si lanza un bloque de except sin encadenamiento explícito:
La traza es
Python 2.x 2.0
Ninguno de los dos está soportado en Python 2.x; la excepción original y su rastreo se perderán si 
se genera otra excepción en el bloque de excepción. El siguiente código puede ser usado para 
compatibilidad:
Python 3.x 3.3
Para "olvidar" la excepción lanzada anteriormente, use raise from None
    554/1068
    490
g = (i for i in range(0, 3)) 
g.next() # Yields 0 
g.next() # Yields 1 
g.next() # Yields 2
Traceback (most recent call last): 
File "<stdin>", line 4, in<module>
DatabaseError('Cannot open database.db')
import six 
try:
file = open('database.db') 
except FileNotFoundError as e:
six.raise_from(DatabaseError('Cannot open {}'), None)
g = (i for i in range(0, 3)) 
next(g) # Yields 0 
next(g) # Yields 1 
next(g) # Yields 2
Ahora el rastreo sería simplemente
O para que sea compatible con Python 2 y 3 puede usar el paquete seis así:
.next () método en los iteradores renombrados
En Python 2, se puede recorrer un iterador usando un método llamado next en el mismo iterador: 
Python 2.x 2.3
EnPython 3, el método .next ha sido renombrado a . next ,reconociendosufunción"mágica", 
por lo que llamar a .next generará un AttributeError . La forma correcta de acceder a esta 
funcionalidadtantoenPython2comoenPython3esllamaralanextfunciónconeliteradorcomo 
argumento.
Python 3.x 3.0
Este código es portátil en las versiones desde 2.6 hasta las versiones actuales.
Comparación de diferentes tipos
Python 2.x 2.3
Se pueden comparar objetos de diferentes tipos. Los resultados son arbitrarios, pero 
consistentes.EstánordenadosdemodoqueNoneesmenorquecualquierotracosa,lostipos 
numéricos son más pequeños que los tipos no numéricos y todo lo demás está ordenado 
lexicográficamenteportipo.Porlotanto,un intesmenorque un stry unatuplees mayor que 
una list :
raise DatabaseError('Cannot open {}') from None
    555/1068
    491
user_input = raw_input()
l = [7, 'x', (1, 2), [5, 6], 5, 8.0, 'y', 1.2, [7, 8], 'z']
sorted(l)
# Out: [1.2, 5, 7, 8.0, [5, 6], [7, 8], 'x', 'y', 'z', (1, 2)]
1 < 1.5
# Out: True
[1, 2] > 'foo'
# TypeError: unorderable types: list() > str() 
(1, 2) > 'foo'
#TypeError: unorderable types: tuple() >str() 
[1, 2] > (1, 2)
# TypeError: unorderable types: list() > tuple()
>>> list = [1, 'hello', [3, 4], {'python': 2}, 'stackoverflow', 8, {'python': 3}, [5, 6]]
>>> sorted(list, key=str)
# Out: [1, 8, [3, 4], [5, 6], 'hello', 'stackoverflow', {'python': 2}, {'python': 3}]
Esto se hizo originalmente para poder ordenar una lista de tipos mixtos y los objetos se 
agruparían por tipo:
Python 3.x 3.0
Se produce una excepción al comparar diferentes tipos (no numéricos):
Para ordenar las listas mixtas en Python 3 por tipos y para lograr la compatibilidad entre 
versiones, debe proporcionar una clave para la función ordenada:
Elusodestrcomolafuncióndekeyconviertetemporalmentecadaelementoenunacadenasolo 
parafines decomparación. Luegovelarepresentación delacadenacomenzandocon[,', {o
y es capaz de ordenarlas (y todos los siguientes caracteres).
Entrada del usuario
En Python 2, la entrada del usuario se acepta utilizando la función raw_input , 
Python 2.x 2.3
Mientras que en Python 3, la entrada del usuario se acepta usando la función de input . 
Python 3.x 3.0
[1, 2] > 'foo'
# Out: False 
(1, 2) > 'foo'
# Out: True
[1, 2] > (1, 2)
# Out: False
100 < [1, 'x'] < 'xyz' < (1, 'x')
# Out: True
    556/1068
    492
try:
input = raw_input 
except NameError:
pass
d = {'a': 0, 'b': 1, 'c': 2, '!': 3}
for key in d.keys(): 
if key.isalpha():
del d[key]
EnPython2,lainput lafunciónaceptarálaentradaeinterpretarla.Sibienestopuedeserútil, 
tiene varias consideraciones de seguridad y seeliminó enPython 3.Para acceder a la misma 
funcionalidad, se puede usar eval(input()).
Para mantener un script portátil en las dos versiones, puede colocar el código a continuación 
cerca de la parte superior de su script de Python:
Cambios en el método del diccionario
EnPython3,muchosdelosmétodosdeldiccionariotienenuncomportamientobastantediferente 
al de Python 2, y muchos también fueron eliminados: has_key , iter* y view* se han ido. En lugar 
ded.has_key(key) , quehabíaestado en desusodurante muchotiempo, ahora se debeusarlakey 
in d .
En Python 2, las keys métodos de diccionario, values y items devuelven listas. En Python 3 
devuelven los objetos de vista en su lugar;los objetos de vista no son iteradores, y se diferencian 
de ellos de dos maneras, a saber:
• tienen tamaño (uno puede usar la función len en ellos)
• Se pueden iterar varias veces.
Además, como con los iteradores, los cambios en el diccionario se reflejan en los objetos de vista. 
Python 2.7 ha respaldado estos métodos desde Python 3; están disponibles como viewkeys ,
viewvalues y elementos de viewitems . Para transformar el código de Python 2 en el código de
Python 3, los formularios correspondientes son:
• d.keys() , d.values() y d.items() de Python 2 deben cambiarse a list(d.keys()) ,
list(d.values()) y list(d.items())
• d.iterkeys() , d.itervalues() y d.iteritems() deben cambiarse a iter(d.keys()) , o incluso 
mejor, iter(d) ; iter(d.values()) e iter(d.items()) respectivamente
• y, finalmente, las llamadas al método Python 2.7 d.viewkeys() , d.viewvalues() y
d.viewitems() se pueden reemplazar por d.keys() , d.values() y d.items() .
Portar el código de Python 2 que itera sobre las claves del diccionario, los valores o los elementos 
mientras se muta a veces es complicado. Considerar:
user_input = input()
    557/1068
    493
exec('code')
exec('code', global_vars) 
exec('code', global_vars, local_vars)
exec 'code'
exec 'code' in global_vars
exec 'code' in global_vars, local_vars
class A(object): 
@property 
def get(self):
raise IOError
ElcódigoparecequefuncionaríademanerasimilarenPython3,peroallíelmétododelaskeys 
devuelve un objeto de vista,no una lista, y si el diccionario cambia de tamaño mientras se repite, 
el código de Python 3 se bloqueará con RuntimeError: dictionary changed size during iteration .
La solución es, por supuesto, escribir correctamente for key in list(d) .
Demanera similar,los objetos de vista se comportande manera diferente alos iteradores: uno no 
puedeusar next()enellos,y unono puede reanudarlaiteración;ensulugar sereiniciaría;Siel 
código de Python 2 pasa el valor de retorno de d.iterkeys() , d.itervalues() o d.iteritems() a un 
método que espera un iterador en lugar de un iterable , entonces debería ser iter(d) , 
iter(d.values()) o iter(d.items()) en Python 3.
La sentencia exec es una función en Python 3
EnPython2,execesunadeclaración,conunasintaxisespecial:execcode [inglobals[,locals]]. 
En Python 3, execahora es una función: exec(code, [, globals[, locals]]) , y la sintaxis de 
Python 2 generará un SyntaxError.
Amedidaquesecambiólaprintdeunadeclaración aunafunción,tambiénseagregóuna 
importación future . Sin embargo, no hay from future import exec_function , ya que no es 
necesario:ladeclaraciónexecenPython2tambiénsepuedeusarconunasintaxisqueseve 
exactamentecomolainvocacióndelafunciónexecenPython3.Porlotanto,puedecambiarlas 
declaraciones
Python 2.x 2.3
a las formas
Python 3.x 3.0
y se garantiza que las últimas formas funcionarán de manera idéntica tanto en Python 2 como en 
Python 3.
Error de la función hasattr en Python 2
En Python 2, cuando una propiedad hasattr un error, hasattr ignorará esta propiedad y devolverá
False .
    558/1068
    494
try:
a.get
except AttributeError: 
print("no get property!")
p = getattr(a, "get", None) 
if p is not None:
print(p) 
else:
print("no get property!")
Este error se corrige en Python3. Así que si usas Python 2, usa
o use getattr en getattr lugar
Módulos renombrados
Algunos módulos en la biblioteca estándar han sido renombrados:
Viejo nombre Nuevo nombre
_winreg Winreg
ConfigParser configparser
copy_reg copyreg
Cola cola
SocketServer socketserver
_markupbase markupbase
reprimir reprender
test.test_support test.support
Tkinter tkinter
class B(object): 
@property 
def get(self):
return 'get in b'
a = A()
b = B()
print 'a hasattr get: ', hasattr(a, 'get')
# output False in Python 2 (fixed, True in Python 3) 
print 'b hasattr get', hasattr(b, 'get')
# output True in Python 2 and Python 3
    559/1068
    495
>>> X. mro
( main .X, object)
>>> Y. mro
( main .Y, object)
>>> 0755 # only Python 2
0o755 # both Python 2 and Python 3
class X: pass
class Y(object): pass
Viejo nombre Nuevo nombre
tkFileDialog tkinter.filedialog
urllib / urllib2 urllib, urllib.parse, urllib.error, urllib.response, urllib.request, 
urllib.robotparser
Algunos módulos incluso se han convertido de archivos a bibliotecas. Tome tkinter y urllib desde 
arriba como ejemplo.
Compatibilidad
Al mantenerlacompatibilidadentrelas versionesdePython2.xy 3.x,puedeusarel paquete
externo future para habilitar la importación de paquetes de biblioteca de nivel superior con 
nombres de Python 3.x en las versiones de Python 2.x.
Constantes octales
En Python 2, un literal octal podría definirse como
Para asegurar la compatibilidad cruzada, use
Todas las clases son "clases de nuevo estilo" en Python 3.
En Python 3.x todas las clases son clases de nuevo estilo ; Al definir una nueva clase, Python 
implícitamente la hace heredar de un object . Como tal, especificar un object en una definición de 
class es completamente opcional:
Python 3.x 3.0
Ambas de estas clases ahora contienen object en su mro (orden de resolución de métodos): 
Python 3.x 3.0
En Python 2.x clases son, por defecto, las clases de estilo antiguo; no heredan implícitamente del
    560/1068
    496
>>> 1 <> 2
True
>>> 1 <> 1
False
>>> foo = 'hello world'
>>> repr(foo) 
"'hello world'"
>>> `foo` 
"'hello world'"
class X: pass
class Y(object): pass
>>> Y. mro
(<class ' main .Y'>, <type 'object'>)
class mycls(object):
"""I am fully compatible with Python 2/3"""
 metaclass = type
class mycls:
"""I am also fully compatible with Python 2/3"""
object .Esto hace que la semántica de las clases difiera dependiendo de si agregamos 
explícitamente el object como una class base:
Python 2.x 2.3
En este caso, si intentamos imprimir el mro de Y , mro una salida similar a la del caso 
Python 3.x :
Python 2.x 2.3
Esto sucede porque hicimos que Y heredara explícitamente de un objeto al definirlo: class 
Y(object): pass . Para la clase X que no hereda del objeto, el atributo mro noexiste,alintentar 
acceder a él se obtiene un AttributeError .
Para garantizar la compatibilidad entre ambas versiones de Python, las clases se pueden 
definir con el object como una clase base:
Alternativamente, si la variable metaclass está configurada para type en el ámbito global, todas 
las clases definidas posteriormente en un módulo dado son implícitamente un estilo nuevo sin la 
necesidad de heredar explícitamente del object :
Se eliminaron los operadores <> y ``, sinónimo de! = Y repr ()
En Python 2, <> es un sinónimo para != ; Del mismo modo, `foo` es un sinónimo de repr(foo) . 
Python 2.x 2.7
Python 3.x 3.0
    561/1068
    497
"1deadbeef3".decode('hex') 
# Out: '\x1d\xea\xdb\xee\xf3'
'\x1d\xea\xdb\xee\xf3'.encode('hex') 
# Out: 1deadbeef3
"1deadbeef3".decode('hex')
# Traceback (most recent call last):
# File "<stdin>", line 1, in<module>
# AttributeError: 'str' object has no attribute 'decode'
b"1deadbeef3".decode('hex')
# Traceback (most recent call last):
# File "<stdin>", line 1, in<module>
# LookupError: 'hex' is not a text encoding; use codecs.decode() to handle arbitrary codecs
'\x1d\xea\xdb\xee\xf3'.encode('hex') 
# Traceback (most recent call last):
# File "<stdin>", line 1, in<module>
# LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
b'\x1d\xea\xdb\xee\xf3'.encode('hex') 
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: 'bytes' object has no attribute 'encode'
import codecs 
codecs.decode('1deadbeef4', 'hex') 
# Out: b'\x1d\xea\xdb\xee\xf4'
codecs.encode(b'\x1d\xea\xdb\xee\xf4', 'hex') 
# Out: b'1deadbeef4'
codecs.encode(b'\x1d\xea\xdb\xee\xff', 'hex').decode('ascii')
codificar / decodificar a hex ya no está disponible
Python 2.x 2.7
Python 3.x 3.0
Sinembargo,comolosugiereelmensajedeerror,puedeusarelmódulodecodecs paralograrel 
mismo resultado:
Tenga en cuenta que codecs.encode devuelve un objeto de bytes . Para obtener un objeto str
simplemente decode a ASCII:
>>> 1 <> 2
File "<stdin>", line 1 
1 <> 2
^
SyntaxError: invalid syntax
>>> `foo`
File "<stdin>", line 1
`foo`
^
SyntaxError: invalid syntax
    562/1068
    498
x = 'hello world!'
vowels = [x for x in 'AEIOU']
print (vowels)
# Out: ['A', 'E', 'I', 'O', 'U']
print(x) 
# Out: 'U'
x = 'hello world!'
vowels = [x for x in 'AEIOU']
print (vowels)
# Out: ['A', 'E', 'I', 'O', 'U']
print(x)
# Out: 'hello world!'
Función cmp eliminada en Python 3
En Python 3 se eliminó la función incorporada de cmp , junto con el método especial cmp . 
De la documentación:
Lafuncióncmp()debetratar comopasada, yelmétodoespecial cmp ()yanose 
admite. Use lt () para clasificar, eq () con hash () , y otras comparaciones 
ricas según sea necesario. (Si realmente necesita la funcionalidad cmp() , puede usar 
la expresión (a > b) - (a < b) como equivalente para cmp(a, b) .
Además, todas las funciones incorporadas que aceptaron el parámetro cmp ahora solo aceptan el 
parámetro de key clave única.
Enelmódulofunctools tambiénhayunafunciónútilcmp_to_key(func) quelepermiteconvertirde 
una función de estilo cmp a una key estilo de key :
Transformaruna funcióndecomparaciónde estiloantiguoenunafunciónclave.Se 
usacon herramientas que aceptanfunciones clave(como sorted(), min(), max(), 
heapq.nlargest() , heapq.nsmallest() , itertools.groupby() ). Esta función se utiliza 
principalmente como una herramienta detransiciónpara los programas quese 
conviertendesdePython2queadmiteelusodefuncionesdecomparación.
Variables filtradas en la lista de comprensión.
Python 2.x 2.3
Python 3.x 3.0
Como se puede ver en el ejemplo, en Python 2 se filtró el valor de x : ¡enmascaró a hello world! e 
imprimió U , ya que este fue el último valor de x cuando finalizó el bucle.
Sin embargo, en Python 3 x imprime el hello world! originalmente definido hello world! , ya que la
# Out: '1deadbeeff'
    563/1068
    499
x = 'hello world!' 
vowels = []
for x in 'AEIOU': 
vowels.append(x)
print(x) 
# Out: 'U'
# Python 2.X
>>> map(str, [1, 2, 3, 4, 5])
['1', '2', '3', '4', '5']
>>> type(_)
>>> <class 'list'>
# Python 3.X
>>> map(str, [1, 2, 3, 4, 5])
<map object at 0x*>
>>> type(_)
<class 'map'>
# We need to apply map again because we "consumed" the previous map....
>>> map(str, [1, 2, 3, 4, 5])
>>> list(_)
['1', '2', '3', '4', '5']
>>> map(None, [0, 1, 2, 3, 0, 4])
[0, 1, 2, 3, 0, 4]
>>> list(map(None, [0, 1, 2, 3, 0, 5])) 
Traceback (most recent call last):
File "<stdin>", line 1, in <module> 
TypeError: 'NoneType' object is not callable
variable local de la lista de comprensión no enmascara las variables del ámbito circundante.
Además, ni las expresiones generadoras (disponibles en Python desde la versión 2.5) ni las 
comprensiones de diccionario o conjunto (que fueron respaldadas a Python 2.7 desde Python 3) 
filtran las variables en Python 2.
Tenga en cuenta que tanto en Python 2 como enPython 3, las variables se filtrarán en el ámbito 
circundante cuando se use un bucle for:
mapa()
map() es un componente que es útil para aplicar una función a elementos de un iterable. En 
Python 2, el map devuelve una lista.En Python 3, map devuelve un objeto map , que es un 
generador.
En Python 2, puede pasar None para que funcione como una función de identidad. Esto ya no 
funciona en Python 3.
Python 2.x 2.3
Python 3.x 3.0
    564/1068
    500
>>> map(None, [1, 2, 3], [1, 2], [1, 2, 3, 4, 5])
[(1, 1, 1), (2, 2, 2), (3, None, 3), (None, None, 4), (None, None, 5)]
>>> list(map(lambda x, y, z: (x, y, z), [1, 2, 3], [1, 2], [1, 2, 3, 4, 5]))
[(1, 1, 1), (2, 2, 2)]
# to obtain the same padding as in Python 2 use zip_longest from itertools
>>> import itertools
>>> list(itertools.zip_longest([1, 2, 3], [1, 2], [1, 2, 3, 4, 5]))
[(1, 1, 1), (2, 2, 2), (3, None, 3), (None, None, 4), (None, None, 5)]
>>> [str(i) for i in [1, 2, 3, 4, 5]]
['1', '2', '3', '4', '5']
>>> s = filter(lambda x: x.isalpha(), 'a1b2c3')
>>> s
'abc'
>>> s = map(lambda x: x * x, [0, 1, 2])
>>> s 
[0, 1, 4]
>>> s = zip([0, 1, 2], [3, 4, 5])
>>> s
[(0, 3), (1, 4), (2, 5)]
>>> it = filter(lambda x: x.isalpha(), 'a1b2c3')
Además, al pasar más de un iterable como argumento en Python 2, el map rellena los iterables 
más cortos con None (similar a itertools.izip_longest ). En Python 3, la iteración se detiene 
después de la iteración más corta.
En Python 2:
Python 2.x 2.3
En Python 3:
Python 3.x 3.0
Nota :enlugar de un map considere utilizarlistasde comprensión,quesoncompatibles con 
Python 2/3. Reemplazo del map(str, [1, 2, 3, 4, 5]) :
filter (), map () y zip () devuelven iteradores en lugar de secuencias
Python 2.x 2.7
En el filterPython 2, las funciones incorporadas de map y zip devuelven una secuencia. map y zip 
siempre devuelven una lista, mientras que con el filter el tipo de retorno depende del tipo de 
parámetro dado:
Python 3.x 3.0
En el filter Python 3, el map y el zip iterador de retorno en sulugar:
    565/1068
    501
import foo
from .moduleY import spam
from.moduleYimportspamasham 
from . import moduleY
from ..subpackage1 import moduleY 
from ..subpackage2.moduleZ import eggs 
from ..moduleA import foo
from ...package import bar 
from ...sys import path
Desde Python 2, itertools.izip es equivalente a Python 3 zip izip se ha eliminado en Python 3.
Importaciones absolutas /relativas
En Python 3,PEP 404 cambia la forma en que funcionan las importaciones desde Python 2.Ya 
no se permiten las importaciones relativas implícitas en los paquetes y from ... import * solo se 
permiten en el código de nivel de módulo.
Para lograr el comportamiento de Python 3 en Python 2:
• lacaracterísticadeimportacionesabsolutassepuedehabilitarfrom future import 
absolute_import
• Se alientan las importaciones relativas explícitas en lugar de las importacionesrelativas 
implícitas
Para aclarar, en Python 2, un módulo puede importar el contenido de otro módulo ubicadoen el 
mismo directorio de la siguiente manera:
Observe que la ubicación de foo es ambigua desde la declaración de importación solo.Este tipo 
deimportaciónrelativaimplícitasedesaconseja,portanto,a favordelas importaciones relativas
explícitas , que se parecen a lassiguientes:
El punto . Permite una declaración explícita dela ubicación del módulo dentro del árbol de 
directorios.
>>> it
<filter object at 0x00000098A55C2518>
>>> ''.join(it) 
'abc'
>>> it = map(lambda x: x * x, [0, 1, 2])
>>> it
<map object at 0x000000E0763C2D30>
>>> list(it) 
[0, 1, 4]
>>> it = zip([0, 1, 2], [3, 4, 5])
>>> it
<zip object at 0x000000E0763C52C8>
>>> list(it)
[(0, 3), (1, 4), (2, 5)]
    566/1068
    502
shapes
├── init .py
|
├── circle.py
|
├── square.py
|
└── triangle.py
from . import util # use util.PI, util.sq(x), etc
from .util import * #use PI, sq(x), etc to call functions
from .. import util # use util.PI, util.sq(x), etc
from ..util import * # use PI, sq(x), etc to call functions
Más sobre Importaciones Relativas
Considere algún paquete definido por el usuario llamado shapes . La estructura del directorio es la 
siguiente:
circle.py , square.py y triangle.py importan util.py como un módulo. ¿Cómo se referirán a un 
módulo en el mismonivel?
O
El.Seutilizaparaimportacionesrelativasdelmismo nivel. 
Ahora,considereundiseñoalternativodelmódulodeshapes:
Ahora, ¿cómo se referirán estas 3 clases a util.py?
O
└── util.py
├── triangle.py
│ ├── init .py
│
|
shapes
├── init .py
|
├── circle
│ ├── init .py
│ └── circle.py
|
├── square
│ ├── init .py
│ └── square.py
|
├── triangle
    567/1068
    503
import io
assert io.open is open # the builtin is an alias 
buffer = io.StringIO()
buffer.write('hello,')#returnsnumberofcharacterswritten 
buffer.write('world!\n')
buffer.getvalue() # 'hello, world!\n'
with open('data.txt') as f: 
first_line = next(f)
assert type(first_line) is str 
with open('data.bin', 'rb') as f:
first_kb = f.read(1024)
assert type(first_kb) is bytes
with open('old_japanese_poetry.txt', 'shift_jis') as text: 
haiku = text.read()
round(1.5) # Out: 2.0 
round(0.5) # Out: 1.0 
round(-0.5) # Out: -1.0
round(-1.5) # Out: -2.0
El..seutilizaparalasimportaciones relativasdenivelpadre.Añadir más. sconnúmerode 
niveles entre el padre y el niño.
Archivo I / O
file ya no es un nombre incorporado en 3.x ( open aún funciona).
Los detalles internos del archivo de E / S se han trasladado al módulo de la biblioteca estándar io
, que también es el nuevo hogar de StringIO :
El modo de archivo (texto frente a binario) ahora determina el tipo de datos producidos al leer un 
archivo (y el tipo requerido para escribir):
La codificación de los archivos de texto se establece de forma predeterminada en 
locale.getpreferredencoding(False) . Para especificar una codificación explícitamente, use el 
parámetro de palabra clave de encoding :
La función round () rompe el empate y devuelve el tipo 
rotura de corbata redonda ()
En Python 2, usar round() en un número igualmente cercano a dos enteros devolverá el más 
alejado de 0. Por ejemplo:
Python 2.x 2.7
Sin embargo, en Python 3, round() devolverá el entero par (también conocido como redondeo de 
banqueros ). Por ejemplo:
    568/1068
    504
round(4.8) 
# 5
round(4.8) 
# 5.0
round(1.5) # Out: 2 
round(0.5) # Out: 0 
round(-0.5) # Out: 0 
round(-1.5) # Out: -2
True, False = False, True 
True # False
False # True
Python 3.x 3.0
La función round () sigue la mitad de la estrategia de redondeo uniforme que redondeará los
números a mitad de camino al entero par más cercano (por ejemplo, round(2.5) ahora devuelve 2 
en lugar de 3.0).
Según la referencia en Wikipedia , esto también se conoce como redondeo imparcial , redondeo 
convergente , redondeo estadístico, redondeo holandés , redondeo gaussiano o redondeo impar .
La mitad del redondeo uniforme es parte del estándar IEEE 754 y también es el modo de 
redondeo predeterminado en .NET de Microsoft.
Esta estrategia de redondeo tiende a reducir el error de redondeo total. Como en promedio, la 
cantidad de números que se redondean es la misma que la cantidad de números que se 
redondean hacia abajo, los errores de redondeo se cancelan. En cambio, otros métodos de 
redondeo tienden a tener un sesgo hacia arriba o hacia abajo en el error promedio.
round () tipo de retorno
La función round() devuelve un tipo float en Python 2.7 
Python 2.x 2.7
A partir de Python 3.0, si se omite el segundo argumento (número de dígitos), devuelve un int . 
Python 3.x 3.0
Verdadero, Falso y Ninguno
En Python 2, True , False y None son constantes integradas. Lo que significa que es posible 
reasignarlos.
Python 2.x 2.0
No puedes hacer esto con None desde Python 2.4.
    569/1068
    505
hi = sys.stdout.write('hello world\n') 
# Out: hello world
type(hi)
# Out: <type 'NoneType'>
True, False = False, True # SyntaxError: can't assign to keyword
None = None # SyntaxError: can't assign to keyword
None = None # SyntaxError: cannot assign to None
import sys
char_count = sys.stdout.write('hello world □\n') 
# Out: hello world □
char_count 
# Out: 14
byte_count = sys.stdout.buffer.write(b'hello world \xf0\x9f\x90\x8d\n') 
# Out: hello world □
byte_count 
# Out: 17
>>> 2**31 
2147483648L
>>> type(2**31)
<type 'long'>
>>> 2**30 
1073741824
>>> type(2**30)
Python 2.x 2.4
En Python 3, True , False y None ahora son palabras clave. 
Python 3.x 3.0
Devolver valor al escribir en un objeto de archivo
En Python 2, escribir directamente en un identificador de archivo devuelve None : 
Python 2.x 2.3
En Python 3, escribir en un identificador devolverá el número de caracteres escritos al escribir 
texto, y el número de bytes escritos al escribir bytes:
Python 3.x 3.0
largo vs. int
En Python 2, cualquier entero mayor que un C ssize_t se convertiría en el tipo de datos long , 
indicado por un sufijo L en el literal. Por ejemplo, en una compilación de Python de 32 bits:
Python 2.x 2.7
    570/1068
    506
class MyClass:
def nonzero (self): 
return False
my_instance = MyClass()
print bool(MyClass) # True 
print bool(my_instance) # False
# True
# False
class MyClass:
def bool (self): 
return False
my_instance = MyClass() 
print(bool(MyClass))
print(bool(my_instance))
Sin embargo, en Python 3, el tipo de datos long fue eliminado; no importa qué tan grande sea el 
número entero, será un int .
Python 3.x 3.0
2**1024
# Output: 
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021
print(-(2**1024)) 
# Output: -
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021
type(2**1024)
# Output: <class 'int'>
Valor booleano de clase
Python 2.x 2.7
EnPython 2, si desea definir un valor booleano de clase por sí mismo,debe implementar el 
método nonzero en su clase. El valor es True pordefecto.
Python 3.x 3.0
En Python 3, bool se usa en lugar de nonzero
<type 'int'>
>>> 2**31 - 1 # 2**31 is long and long - int is long 
2147483647L
    571/1068
    507
Capítulo 101: Indexación y corte
Sintaxis
• obj [inicio: detener: paso]
• cortar
• rebanada (inicio, parada [, paso])
Parámetros
Paramer Descripción
obj El objeto del que desea extraer un "subobjeto" de
start
El índice de obj que desea que comience el subobjeto (tenga en cuenta que 
Python tiene un índice de cero, lo que significa que el primer elemento de obj 
tiene un índice de 0 ). Si se omite, el valor predeterminado es 0 .
stop
El índice (no incluido) de obj que desea que termine el subobjeto.Si se omite, el 
valor predeterminado es len(obj) .
step
Le permite seleccionar solo cada elemento de step . Si se omite, el valor 
predeterminado es 1 .
Observaciones
Puede unificar el concepto de corte de cadenas con el de cortar otras secuencias al ver las 
cadenas como una colección de caracteres inmutables, con la advertencia de que un carácter 
Unicode está representado por una cadena de longitud 1.
Enlanotaciónmatemática,puedeconsiderardividirparausarunintervalosemiabiertode[start, 
end),esdecir,queelinicioestáincluidoperoelfinalno.Lanaturalezasemiabiertadelintervalo 
tiene la ventaja de que len(x[:n])= n donde len(x)> = n , mientras que el intervalo que se cierra 
al inicio tiene la ventaja de que x[n:n+1] = [x[n]] donde x es una lista con len(x) >= n , 
manteniendo así la coherencia entre la notación de indexación y de corte.
Examples
Rebanado basico
Para cualquier iterable (por ejemplo, una cadena, lista, etc.), Python le permite dividir y devolver 
una subcadena o una lista secundaria de sus datos.
Formato para rebanar:
    572/1068
    508
# "ace" (every 2nd element)
# "bd" (from index 1, to index 4 (excluded), every 2nd element)
a[::2]
a[1:4:2]
# "abcde" (from index 0 (default), to the second last element (last element - 1)) 
# "abcd" (from index 0 (default), to the third last element (last element -2))
# "f" (from the last element to the end (default len())
a[:-1]
a[:-2]
a[-1:]
a[3:1:-1] # "dc" (from index 2 to None (default), in reverse order)
a[::-1] # "fedcba" (from last element (default len()-1), to first, in reverse order(-1))
a[5:None:-1] # "fedcba" (this is equivalent to a[::-1])
a[5:0:-1] # "fedcb" (from the last element (index 5) to second element (index 1)
dónde,
• start es el primer índice de la rebanada. Por defecto es 0 (el índice del primer elemento)
• stop uno más allá del último índice de la rebanada. Por defecto a len (iterable)
• step es el tamaño del paso (mejor explicado porlos ejemplos a continuación) 
Ejemplos:
Además, cualquiera de los anteriores se puede utilizar con el tamaño de paso definido:
Los índices pueden ser negativos, en cuyo caso se calculan desde el final de la secuencia.
Los tamaños de los pasos también pueden ser negativos, en cuyo caso la división se repetirá en 
orden inverso:
Este constructo es útil para revertir un iterable.
Tenga en cuenta que para los pasos negativos, el end_index predeterminado es None (consulte 
http://stackoverflow.com/a/12521981 )
Hacer una copia superficial de una matriz
Una forma rápida de hacer una copia de una matriz (en lugar de asignar una variable con otra
a = "abcdef"
a # "abcdef"
# Same as a[:] or a[::] since it uses the defaults for all three indices a[-
1] # "f"
a[:] #"abcdef"
a[::] #"abcdef"
a[3:] # "def" (from index 3, to end(defaults to size of iterable)) 
a[:4] # "abcd" (from beginning(default 0) to position 4 (excluded)) 
a[2:4] # "cd" (from position 2, to position 4 (excluded))
iterable_name[start:stop:step]
    573/1068
    509
arr[:]
arr = ['a', 'b', 'c'] 
copy = arr[:] 
arr.append('d')
print(arr) # ['a', 'b', 'c', 'd']
print(copy) # ['a', 'b', 'c']
s = 'reverse me!'
s[::-1] # '!em esrever'
class MultiIndexingList: 
def init (self, value):
self.value = value
def repr (self):
return repr(self.value)
def getitem (self, item):
if isinstance(item, (int, slice)): 
return self.class(self.value[item])
return [self.value[i] for i in item]
def setitem (self, item, value): 
if isinstance(item, int):
self.value[item] = value 
elif isinstance(item, slice):
referencia a la matriz original) es:
Vamosa examinarlasintaxis. [:]Mediosquestart , end , y sliceestán omitidos. Los valores 
predeterminados son 0 , len(arr)y 1 ,respectivamente, lo quesignifica que el subarregloque 
solicitamostendrátodosloselementosdearrdesdeelprincipiohastaelfinal.
En la práctica, esto se parece a algo como:
Como puede ver, arr.append('d') agregó d a arr , ¡pero la copy mantuvo sin cambios! 
Tenga en cuenta que esto hace una copia superficial y es idéntico a arr.copy() . 
Invertir un objeto
Puedeusar cortespararevertir muyfácilmenteunastr,listotuple (obásicamentecualquier 
objeto de colección que implemente el corte con el parámetro de paso).Este es un ejemplo de 
inversión de una cadena, aunque esto se aplica igualmente a los otros tipos mencionados 
anteriormente:
Veamos rápidamente la sintaxis. [::-1] significa que la división debe ser desde el principio hasta 
el final de la cadena (porque se omiten el start y el end ) y un paso de -1 significa que debe 
moverse a través de la cadena en sentidoinverso.
Clases personalizadas de indexación: getitem , setitem y delitem
    574/1068
    510
del a[4,2,5] 
a
# Out: [1, 100, 4, 8]
<-- indicated which element came from which index
a = MultiIndexingList([1,2,3,4,5,6,7,8]) 
a
# Out: [1, 2, 3, 4, 5, 6, 7, 8] 
a[1,5,2,6,1]
# Out: [2, 6, 3, 7, 2]
a[4, 1, 5:, 2, ::2]
# Out: [5, 2, [6, 7, 8], 3, [1, 3, 5, 7]]
# 4|1-|----50:---|2-|-----::2-----
lst = [1, 2, 3]
Esto permite el corte y la indexación para el acceso al elemento:
Al configurar y eliminar elementos solo se permite la indexación de enteros separados por comas
(sin rebanar):
a[4] = 1000
a
# Out: [1, 2, 3, 4, 1000, 6, 7, 8]
a[2,6,1] = 100
a
# Out: [1, 100, 100, 4, 1000, 6, 100, 8]
del a[5]
a
# Out: [1, 100, 100, 4, 1000, 100, 8]
Asignación de rebanada
Otra característica interesante que utiliza los segmentos es la asignación de sectores. Python le 
permite asignar nuevos segmentos para reemplazar los segmentos antiguos de una lista en una 
sola operación.
Esto significa que si tiene una lista, puede reemplazar varios miembros en una sola tarea:
raise ValueError('Cannot interpret slice with multiindexing') 
else:
for i in item:
if isinstance(i, slice):
raise ValueError('Cannot interpret slice with multiindexing') 
self.value[i] = value
def delitem (self, item): 
if isinstance(item, int):
del self.value[item]
elif isinstance(item, slice): 
del self.value[item]
else:
if any(isinstance(elem, slice) for elem in item):
raise ValueError('Cannot interpret slice with multiindexing') 
item = sorted(item, reverse=True)
for elem in item:
del self.value[elem]
    575/1068
    511
lst = [1, 2, 3, 4, 5]
lst[1:4] = [6]
print(lst) # Out: [1, 6, 5]
lst = [1, 2, 3]
lst[:] = [4, 5, 6]
print(lst) # Out: [4, 5, 6]
lst = [1, 2, 3]
lst[-2:] = [4, 5, 6]
print(lst) # Out: [1, 4, 5, 6]
>>> programmer_1 = [ 1956, 'Guido', 'van Rossum', 'Python', 'Netherlands']
>>> programmer_2 = [ 1815, 'Ada', 'Lovelace', 'Analytical Engine', 'England']
>>> name_columns = slice(1, 3)
>>> programmer_1[name_columns] 
['Guido', 'van Rossum']
>>> programmer_2[name_columns] 
['Ada', 'Lovelace']
arr = ['a', 'b', 'c', 'd'] 
print(arr[0])
>> 'a'
print(arr[1])
La asignación tampoco debe coincidir en tamaño, por lo que si desea reemplazar una porción 
antigua por una nueva que es de tamaño diferente, podría:
También es posible usar la sintaxis de corte conocida para hacer cosas como reemplazar toda la 
lista:
O solo los dos últimos miembros:
Rebanar objetos
Los cortes son objetos en sí mismos y se pueden almacenar en variables con la función de 
slice() incorporada. Las variables de división se pueden usar para hacer que su código sea más 
legible y para promover la reutilización.
Indexación básica
Las listas de Python están basadas en 0, es decir, se puede acceder al primer elemento de la lista 
mediante el índice 0
Puede acceder al segundo elemento de la lista por índice 1 , tercer elemento por índice 2 y así 
sucesivamente:
lst[1:3] = [4, 5]
print(lst) # Out: [1, 4, 5]
    576/1068
    512
print(arr[-1])
>> 'd'
print(arr[-2])
>> 'c'
print arr[6]
Traceback (most recent call last): 
File "<stdin>", line 1, in<module>
IndexError: list index out of range
También puede usar índices negativos para acceder a los elementos del final de la lista. p.ej. El 
índice -1 le dará el último elemento de la lista y el índice -2 le dará el segundo elemento de la 
lista:
Si intenta acceder a un índice que no está presente en la lista, se IndexError un IndexError :
>> 'b'
print(arr[2])
>> 'c'
    577/1068
    513
headers_set = [] 
headers_sent = []
def write (data): 
"""
Writes header data from 'start_response()' as well as body data from 'response' 
to system standard output.
"""
if not headers_set:
raise AssertionError("write() before start_response()")
elif not headers_sent:
status, response_headers = headers_sent[:] = headers_set 
sys.stdout.write('Status: %s\r\n' % status)
for header in response_headers: 
sys.stdout.write('%s: %s\r\n' % header)
sys.stdout.write('\r\n')
sys.stdout.write(data) 
sys.stdout.flush()
def start_response(status, response_headers):
""" Sets headers for the response returned by this server.""" 
if headers_set:
raise AssertionError("Headers already set!")
headers_set[:] = [status, response_headers] 
return write
= sys.stdin
= sys.stderr
import os, sys
def run(application): 
environ['wsgi.input'] 
environ['wsgi.errors']
Capítulo 102: Interfaz de puerta de enlace de 
servidor web (WSGI)
Parámetros
Parámetro Detalles
start_response Una función utilizada para procesar el inicio.
Examples
Objeto de servidor (Método)
A nuestro objeto de servidor se le asigna un parámetro de 'aplicación' que puede ser cualquier 
objeto de aplicación que se pueda llamar (ver otros ejemplos). Primero escribe los encabezados, 
luego el cuerpo de datos devueltos por nuestra aplicación a la salida estándar del sistema.
    578/1068
    514
# This is the most important piece of the 'server object'
# Our result will be generated by the 'application' given to this method as a parameter 
result = application(environ, start_response)
try:
for data in result: 
if data:
write(data) 
if not headers_sent:
write('')
# Body isn't empty send its data to 'write()' 
#Bodyisempty,sendemptystringto'write()'
    579/1068
    515
pip install amqpstorm
from amqpstorm import Connection
def on_message(message):
"""This function is called on message received.
:param message: Delivered message.
:return:
"""
print("Message:", message.body)
# Acknowledge that we handled the message without any issues. 
message.ack()
# Reject the message. 
# message.reject()
# Reject the message, and put it back in the queue. 
# message.reject(requeue=True)
connection = Connection('127.0.0.1', 'guest', 'guest')
Capítulo 103: Introducción a RabbitMQ 
utilizando AMQPStorm
Observaciones
La última versión de AMQPStorm está disponible en pypi o puede instalarla usando pip
Examples
Cómo consumir mensajes de RabbitMQ
Comience con la importación de la biblioteca.
Alconsumirmensajes,primerodebemosdefinirunafunciónparamanejarlosmensajesentrantes. 
Esta puede ser cualquier función que se pueda llamar y tiene que tomar un objeto de mensaje o 
una tupla de mensaje (según el parámetro to_tuple definido en start_consuming ).
Además de procesar los datos del mensaje entrante, también tendremos que Reconocer o 
Rechazar el mensaje. Esto es importante, ya que necesitamos informar a RabbitMQ que 
recibimos y procesamos el mensaje correctamente.
A continuación, debemos configurar la conexión al servidor RabbitMQ.
Después de eso tenemos que configurar un canal. Cada conexión puede tener múltiples canales
    580/1068
    516
channel = connection.channel()
channel.basic.consume(callback=on_message, queue='simple_queue', no_ack=False)
channel.start_consuming(to_tuple=False)
from amqpstorm import Connection 
from amqpstorm import Message
connection = Connection('127.0.0.1', 'guest', 'guest')
channel = connection.channel()
# Message Properties. 
properties = {
'content_type': 'text/plain', 
'headers': {'key': 'value'}
}
# Create the message.
message = Message.create(channel=channel, body='Hello World!', properties=properties)
y, en general, al realizar tareas de subprocesos múltiples, se recomienda (pero no es obligatorio) 
tener uno por subproceso.
Una vez que tengamos configurado nuestro canal, debemos informarle a RabbitMQ que 
queremos comenzar a consumir mensajes.Eneste caso, usaremos nuestra función on_message 
previamente definida para manejar todos nuestros mensajes consumidos.
La cola que escucharemos en el servidor RabbitMQ será simple_queue , y también le estamos 
diciendo a RabbitMQ que reconoceremos todos los mensajes entrantes una vez que hayamos 
terminado con ellos.
Finalmente, necesitamos iniciar el bucle IO para comenzar a procesar los mensajes entregados 
por el servidor RabbitMQ.
Cómo publicar mensajes a RabbitMQ
Comience con la importación de la biblioteca.
Luego necesitamos abrir una conexión al servidor RabbitMQ.
Después de eso tenemos que configurar un canal. Cada conexión puede tener múltiples canales 
y, en general, al realizar tareas de subprocesos múltiples, se recomienda (pero no es obligatorio) 
tener uno por subproceso.
Una vez que tengamos configurado nuestro canal, podemos comenzar a preparar nuestro 
mensaje.
    581/1068
    517
message.publish(routing_key='simple_queue')
channel.queue.bind(exchange='amq.direct', routing_key='hello', queue='hello')
delay_channel.queue.declare(queue='hello_delay', durable=True, arguments={ 
'x-message-ttl': 5000,
'x-dead-letter-exchange': 'amq.direct', 
'x-dead-letter-routing-key': 'hello'
})
delay_channel.basic.publish(exchange='',
Ahora podemos publicar el mensaje simplemente llamando a publish y proporcionando una
routing_key . En este caso, vamos a enviar el mensaje a una cola llamada simple_queue .
Cómo crear una cola retrasada en RabbitMQ
Primero debemos configurar dos canales básicos, uno para la cola principal y otro para la cola de 
demora.En mi ejemplo al final, incluyo un par de marcas adicionales que no son necesarias, pero 
hacen que el código sea más confiable; tales como confirm delivery , delivery_mode y durable .
Puede encontrar más información sobre estos en el manual de RabbitMQ.
Después de configurar los canales, agregamos un enlace al canal principal que podemos utilizar 
para enviar mensajes desde el canal de retardo a nuestra cola principal.
A continuación, debemos configurar nuestro canal de retardo para reenviar los mensajes a la cola 
principal una vez que hayan caducado.
• x-message-ttl (Mensaje - Time To Live)
Normalmente se usa para eliminar automáticamente los mensajes antiguos en la cola 
después de una duración específica, pero al agregar dos argumentos opcionales podemos 
cambiar este comportamiento y, en cambio, hacer que este parámetro determine en 
milisegundos el tiempo que los mensajes permanecerán en la cola de demora.
• x-dead-letter-routing-key
Esta variable nos permite transferir el mensaje a una cola diferente una vez que han 
caducado, en lugar del comportamiento predeterminado de eliminarlo por completo.
• x-dead-letter-exchange
Esta variable determina qué Exchange usó para transferir el mensaje de hello_delay a hello 
queue.
Publicación en la cola de retardo
Cuando hayamos terminado de configurar todos los parámetros básicos de Pika, simplemente 
envíe un mensaje a la cola de demora utilizando la publicación básica.
    582/1068
    518
from amqpstorm import Connection
connection = Connection('127.0.0.1', 'guest', 'guest') 
# Create normal 'Hello World' type channel.
channel = connection.channel()
channel.confirm_deliveries() 
channel.queue.declare(queue='hello', durable=True)
# We need to bind this channel to an exchange, that will be used to transfer 
# messages from our delay queue.
channel.queue.bind(exchange='amq.direct', routing_key='hello', queue='hello')
# Create our delay channel. 
delay_channel = connection.channel() 
delay_channel.confirm_deliveries()
# This is where we declare the delay, and routing for our delay channel. 
delay_channel.queue.declare(queue='hello_delay', durable=True, arguments={
'x-message-ttl': 5000, # Delay until the message is transferred in milliseconds.
'x-dead-letter-exchange': 'amq.direct', # Exchange used to transfer the message from A to
B.
'x-dead-letter-routing-key': 'hello' # Name of the queue we want the message transferred
to.
})
delay_channel.basic.publish(exchange='',
routing_key='hello_delay', 
body='test', 
properties={'delivery_mode': 2})
print("[x] Sent")
Una vez que haya ejecutado el script, debería ver las siguientes colas creadas en su módulo de 
administración RabbitMQ.
Ejemplo.
routing_key='hello_delay', 
body='test', 
properties={'delivery_mod': 2})
    583/1068
    519
import collections
>>> collections.Iterator()
class MyIterable: 
def iter (self):
return self
def next (self): 
#code
#Classic iterable object in older versions of python, getitem is still supported... 
class MySequence:
def getitem (self, index): 
if (condition):
raise IndexError
return (item)
#Can produce a plain `iterator` instance by using iter(MySequence())
Capítulo 104: Iterables e iteradores
Examples
Iterador vs Iterable vs generador
Uniterable esun objeto que puede devolver un iterador.Cualquier objeto con estado que tenga 
un método iter y devuelva un iterador es iterable. También puede ser un objeto sin estado 
que implemente un método getitem . - El método puede tomar índices (comenzando desde 
cero) y generar un IndexError cuando los índices ya no son válidos.
La clase str de Python es un ejemplo de getitem iterable.
Un iterador es un objeto que produce el siguiente valor en una secuencia cuando llama al 
next(*object*) en algún objeto. Además, cualquier objeto con un método next esuniterador. 
Un iterador genera StopIteration después de agotar el iterador y no se puede reutilizar en este 
punto.
Clases iterables
Las clases iter definen un iter y next . Ejemplo de una clase iterable:
Intentando crear una instancia de la clase abstracta del módulo de collections para ver mejor 
esto.
Ejemplo: 
Python 2.x 2.3
    584/1068
    520
class MyIterable(object): #or collections.Iterator, which I'd recommend....
....
def iter (self):
return self 
defnext(self): #code
 next = next
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
ex1 = MyIterableClass() 
ex2 = MySequence()
for (item) in (ex1): #code 
for (item) in (ex2): #code
[1, 2, 3] # list, iterate over items
(1, 2, 3) # tuple
{1, 2, 3} # set
{1: 2, 3: 4} # dict, iterate over keys
def foo(): # foo isn't iterable yet... 
yield 1
res = foo() # ...but res already is
Python 3.x 3.0
Maneje la compatibilidad de Python 3 para las clases iterables en Python 2 haciendo lo siguiente: 
Python 2.x 2.3
Ambos son ahora iteradores y se pueden pasar a través de:
Los generadores son formas simples de crear iteradores. Un generador es un iterador y un 
iterador es un iterable.
Lo que puede ser iterable
Iterable puede ser cualquier cosa por la cual los artículos se reciben uno por uno, solo hacia 
adelante . Las colecciones Python incorporadas son iterables:
Los generadores devuelven iterables:
Iterando sobre todo iterable
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
    585/1068
    521
a, = iterable
def foo():
yield 1
a, = foo() # a = 1 
nums = [1, 2, 3]
a, = nums # ValueError: too many values to unpack
s = {1, 2} # or list or generator or even iterator 
i = iter(s) # get iterator
a = next(i) # a = 1 
b = next(i) # b = 2
c = next(i) # raises StopIteration
def gen():
yield 1
iterable = gen() 
for a in iterable:
print a
#What was the first item ofiterable? No way to get it now. 
# Only to get a new iterator
gen()
Verificar solo un elemento en iterable.
Utilice el desembalaje para extraer el primer elemento y asegurarse de que sea el único:
Extraer valores uno por uno.
Comienceconiter() incorporado paraobtener iterador sobre iterable yusenext() paraobtener 
elementos uno por uno hasta que se StopIteration para StopIteration el final:
¡El iterador no es reentrante!
s = {1, 2, 3}
# get every element in s 
for a in s:
print a # prints 1, then 2, then 3
# copy into list
l1 = list(s) # l1 = [1, 2, 3]
# use list comprehension
l2 = [a * 2 for a in s if a > 2] # l2 = [6]
    586/1068
    522
from kivy.app import App
from kivy.uix.label import Label
class Test(App): 
def build(self):
return Label(text='Hello world')
if name == 'main ': 
Test().run()
from kivy.app import App
from kivy.uix.label import Label
Capítulo 105: kivy - Framework Python 
multiplataforma para el desarrollo de NUI
Introducción
NUI: una interfaz de usuario natural (NUI) es un sistema para la interacción persona-computadora 
que el usuario opera a través de acciones intuitivas relacionadas con el comportamiento humano 
natural y cotidiano.
Kivy es una biblioteca de Python para el desarrollo de aplicaciones ricas en medios con 
capacidad multitáctil que se pueden instalar en diferentes dispositivos. La función multitáctil se 
refiere a la capacidad de una superficie sensible al tacto (generalmente una pantalla táctil o un 
trackpad) para detectar o detectar entradas provenientes de dos o más puntos de contacto 
simultáneamente.
Examples
Primera aplicación
Para crear una aplicación kivy.
1. subclase la clase de aplicación
2. Implementar el método de construcción , que devolverá el widget.
3. Crea una instancia de la clase e invoca la carrera .
Explicación
La declaración anterior importará la aplicación de clase principal. Esto estará presente en su 
directorio de instalación directorio_instalación / kivy / app.py
La declaración anterior importará la etiqueta del elemento ux. Todos los elementos ux están 
presentes en su directorio de instalación directorio_instalación / kivy / uix /.
    587/1068
    523
def build(self):
return Label(text='Hello world')
if name == ' main ':
Test().run()
La declaración anterior es para crear su aplicación y el nombre de la clase será el nombre de su 
aplicación. Esta clase se hereda de la clase de la aplicación padre.
La declaración anterior anula el método de compilación de la clase de aplicación. Lo que 
devolverá el widget que debe mostrarse cuando inicie la aplicación.
La declaración anterior es el cuerpo del método de construcción. Está devolviendo la etiqueta con 
su texto Hola mundo .
La declaración anterior es el punto de entrada desde donde el intérprete de Python comienza a 
ejecutar su aplicación.
La declaración anterior Inicializa tu clase de prueba creando su instancia. E invoca la función de 
clase de aplicación run ().
Su aplicación se verá como la imagen de abajo.
class Test(App):
    588/1068
    524
    589/1068
    525
try:
self.version = "Expat %d.%d.%d" % expat.version_info 
except AttributeError:
pass # unknown
try:
os.unlink(filename_larry) 
except:
pass
Capítulo 106: La declaración de pase
Sintaxis
• pasar
Observaciones
¿Porquéquerríadecirleal intérpretequenohaganadaexplícitamente?Pythontieneelrequisito 
sintáctico de que los bloques de código (después de, if , except , def , class , etc.) no pueden 
estar vacíos.
Pero a veces un bloque de código vacío es útil en sí mismo. Un bloque de class vacío puede 
definir una nueva clase diferente, como una excepción que se puede capturar. Un bloque de 
except vacío puede ser la forma más simple de expresar "pedir perdón más tarde" si no hubiera 
nada por lo que pedir perdón. Si un iterador hace todo el trabajo pesado, un iterador vacío for 
ejecutar el iterador puede ser útil.
Porlo tanto, si no se supone que ocurra nada en un bloque de código, se necesita un pass para 
que dicho bloque no produzca un IndentationError . Alternativamente, se puede usar cualquier 
declaración (incluido solo un término para ser evaluado, como el literal de Ellipsis ... o una 
cadena, más a menudo una cadena de documentación), pero el passdeja claro que en realidad 
no se supone que suceda nada, y no es necesario para ser realmente evaluado y (al menos 
temporalmente)almacenado enla memoria.Aquíhayuna pequeña colección anotadadelos 
usos más frecuentes del passque se cruzó en mi camino, junto con algunos comentarios sobre 
buenas y malas prácticas.
• Ignorar (todo o) un cierto tipo de Exception (ejemplo de xml ):
Nota: ignorar todos los tipos de aumentos, como en el siguiente ejemplo de pandas , 
generalmente se considera una mala práctica, ya que también detecta excepciones que 
probablemente deberían transmitirse a la persona que llama, por ejemplo, KeyboardInterrupt 
o SystemExit (o incluso HardwareIsOnFireError - ¿Cómo lo sabe?) no se está ejecutando en un 
cuadro personalizado con errores específicos definidos, que alguna aplicación dellamada 
querría conocer?).
    590/1068
    526
class CompileError(Exception): 
pass
class _BaseSubmittingController(_BaseController): 
def submit(self, tasks): pass
def retrieve(self, deferred_results): pass
for x, error in MDNewton(mp, f, (1,-2), verbose=0,
norm=lambda x: norm(x, inf)):
pass
class ParsingError(Exception):
"""Error encountered while parsing an ill-formed datafile.""" 
pass
def update_agent(agent):
...
def update_agent(agent):
En sulugar, usar al menos except Error: o enestecaso, preferiblemente, except OSError: se 
consideraunapráctica mucho mejor.Un análisisrápidode todos losmódulos depythonque 
heinstaladomedioelhechodequemásdel10%detodos, except ...: passdeclaraciones 
de except ...: pass detectan todas las excepciones, por lo que sigue siendo un patrón 
frecuente en la programación de python.
• Derivar una clase de excepción que no agrega un comportamiento nuevo (por ejemplo, en
scipy ):
De manera similar, las clases destinadas a la clase base abstracta a menudo tienen un
 init vacío explícito u otros métodos que sesuponeque derivan lassubclases.(por 
ejemplo, pebl )
• La prueba de que el código se ejecuta correctamente para unos pocos valores de prueba, 
sin preocuparse por los resultados (de mpmath ):
• En las definiciones de clase o función, a menudo una cadena de documentación ya está 
implementada como la declaración obligatoria que debe ejecutarse como la única cosa en el 
bloque. En tales casos, el bloque puede contener un pass además de la cadena de 
documentación para decir "Esto no pretende hacer nada", por ejemplo, en pebl :
• Enalgunos casos, el pass se utiliza como marcador de posición para decir "Este método / 
class / if-block / ... no se ha implementado todavía, pero este será el lugar para hacerlo", 
aunque personalmente prefiero el literal de Ellipsis ... (NOTA: solo python-3) para 
diferenciar estrictamente entre esto y el "no-op"intencional en el ejemplo anterior.Por 
ejemplo, si escribo un modelo a grandes rasgos, podría escribir
donde otros podrían tener
    591/1068
    527
def time_step(agents): 
for agent in agents:
update_agent(agent)
try:
metadata = metadata['properties'] 
except KeyError:
pass
class CompileError(Exception): 
pass
antes de
comounrecordatorio paracompletarlafunciónupdate_agent enunpuntoposterior, pero 
ejecutealgunaspruebasparaversielrestodel códigosecomportacomoseesperaba. 
(Una tercera opción para este caso es raise NotImplementedError . Esto es útil en particular 
para dos casos:“Este método abstractodebe serimplementado por cada subclase,nohay 
unaformagenéricadedefinirloenestaclasebase”,o“Estafunción,conestenombre,aún 
noestáimplementado en estaversión, peroeste es el aspectoquetendrásufirma” )
Examples
Ignorar una excepción
Crear una nueva excepción que puede ser capturada
pass
    592/1068
    528
print('hello world!') 
# out: hello world!
foo = 1
bar = 'bar' 
baz = 3.14
print(foo) 
# out: 1 
print(bar) 
# out: bar 
print(baz) 
# out: 3.14
print(foo, bar, baz) 
# out: 1 bar 3.14
print(str(foo) + " " + bar + " " + str(baz)) 
# out: 1 bar 3.14
# Wrong:
# type:int str float 
print(foo + bar + baz) 
# will result in an error
print(4 + 5)
# out: 9
print("4" + "5")
# out: 45
print([4] + [5])
# out: [4, 5]
Capítulo 107: La función de impresión
Examples
Fundamentos de impresión
En Python 3 y superior, print es una función en lugar de una palabra clave.
También puede pasar una serie de parámetros para print :
Otra forma de print múltiples parámetros es usando un +
Sin embargo, lo que debe tener cuidado al utilizar + para imprimir varios parámetros es que el tipo 
de parámetros debe ser el mismo. Tratar de imprimir el ejemplo anterior sin la conversión de la 
string primero daría como resultado un error, ya que intentaría agregar el número 1 a la cadena 
"bar" y agregarlo al número 3.14 .
Esto se debe a que el contenido de la print se evaluará primero:
    593/1068
    529
import random
#telling python to include a function to create random numbers 
randnum = random.randint(0, 12)
#make a random number between 0 and 12 and assign it to a variable 
print("The randomly generated number was - " + str(randnum))
print("this has no newline at the end of it... ", end="") 
print("see?")
# out: this has no newline at the end of it... see?
with open('my_file.txt', 'w+') as my_file: 
print("this goes to the file!", file=my_file)
>>>print('apples','bannas','cherries',sep=',') 
apple, bannas, cherries
>>> print('apple','banna', 'cherries', sep=', ') 
apple, banna, cherries
>>>
>>> print("<a", end=''); print(" class='jidn'" if 1 else "", end=''); print("/>")
<a class='jidn'/>
>>> print("paragraph1", end="\n\n");print("paragraph2") 
paragraph1
paragraph2
De lo contrario, usar a + puede ser muy útil para que un usuario lea la salida de variables. En el 
siguiente ejemplo, ¡la salida es muy fácil de leer!
El siguiente script demuestra esto
Puede evitar la print la función de imprimir automáticamente una nueva línea utilizando el end de 
parámetros:
Si desea escribir en un archivo, puede pasarlo como file parámetros:
¡Esto va al archivo!
Parámetros de impresión
Puedes hacer más que solo imprimir texto. print también tiene varios parámetros para ayudarte. 
Argumento sep : coloca una cadena entreargumentos.
¿Necesita imprimir una lista de palabras separadas por una coma o alguna otra cadena?
end argumento: use algo que no sea una nueva línea al final
Sin el argumento end , todas print() funciones print() escriben una línea y luego van al principio 
de la siguiente línea.Puede cambiarlo para que no haga nada (use una cadena vacía de ''), o 
doble espacio entre párrafos utilizando dos líneasnuevas.
    594/1068
    530
>>> def sendit(out, *values, sep=' ', end='\n'):
... print(*values, sep=sep, end=end,file=out)
...
>>> sendit(sys.stdout, 'apples', 'bannas', 'cherries', sep='\t') 
apples bannas cherries
>>> with open("delete-me.txt", "w+") as f:
... sendit(f, 'apples', 'bannas', 'cherries', sep=' ', end='\n')
...
>>> with open("delete-me.txt", "rt") as f:
... print(f.read())
...
apples bannas cherries
>>>
file argumento: enviar salida a otro lugar que no sea sys.stdout.
Ahora puede enviar su texto a stdout, a un archivo, oa StringIO y no le importa lo que le den. Si 
funciona como un archivo, funciona como un archivo.
Hay un cuarto parámetro de flush que forzará la descarga de la corriente.
>>>
    595/1068
    531
import module2.py
print('hello')
Capítulo 108: La variable especial name
Introducción
La variable especial name se usa para verificar si un archivo ha sido importado como un 
módulo o no, y para identificar una función, clase, objeto de módulo por su atributo name .
Observaciones
La variable especial de Python name se establece en el nombre del módulo que lo contiene. En 
el nivel superior (como en el intérprete interactivo, o en el archivo principal) se establece en
' main ' .Estosepuedeusarparaejecutarunbloquedeinstruccionessiunmóduloseejecuta 
directamente en lugar de importarse.
El atributo especial relacionado obj. name se encuentra en las clases, los módulos y las 
funciones importadas (incluidos los métodos) y proporciona el nombre del objeto cuando se 
define.
Examples
name == ' main '
La variable especial name no es establecida por el usuario. Se utiliza principalmente para 
verificar si el módulo se está ejecutando solo o no porque se realizó una import . Para evitar que 
su módulo ejecute ciertas partes de su código cuando se importa, verifique if name ==
' main ' .
Deje que module_1.py tenga una sola línea de largo:
Y veamos que pasa, dependiendo de module2.py.
Situación 1
módulo2.py
Ejecutando module1.py imprimiráhello
Ejecutando module2.py imprimiráhello
Situación 2
    596/1068
    532
if name == 'main ': 
print('hello')
import os
class C:
pass
def f(x):
x += 2
return x
print(f)
#<functionfat0x029976B0> 
print(f. name )
# f
print(C)
#<class' main .C'> 
print(C. name )
# C
print(os)
# <module 'os' from '/spam/eggs/'> 
print(os. name )
# os
def f():
pass
print(f. name ) 
# f - as expected
g = f
print(g. name )
# f - even though the variable is named g, the function is still named f
def enter_exit_info(func):
módulo2.py
Ejecutando module1.py no imprimirá nada 
Ejecutando module2.py imprimiráhello
function_class_or_module . name
El atributo especial name de una función, clase o módulo es una cadena que contiene su 
nombre.
Sin embargo, el atributo name no es el nombre de la variable que hace referencia a la clase, el 
método o la función, sino que es el nombre que se le asigna cuando se define.
Esto se puede utilizar, entre otros, para la depuración:
    597/1068
    533
logger = logging.getLogger( name )
Utilizar en el registro
Al configurar la funcionalidad de logging incorporada, un patrón común es crear un registrador con 
el name del módulo actual:
Esto significa que el nombre completo del módulo aparecerá en los registros, lo que facilitará ver 
de dónde provienen los mensajes.
def wrapper(*arg, **kw):
print '-- entering', func. name
res = func(*arg, **kw)
print '-- exiting', func. name
return res
return wrapper
@enter_exit_info 
def f(x):
print 'In:', x 
res = x +2
print 'Out:', res 
return res
a = f(2)
# Outputs:
# -- entering f
# In: 2
# Out: 4
# -- exiting f
    598/1068
    534
class BaseClass(object): 
pass
class DerivedClass(BaseClass): 
pass
class Rectangle():
def init (self, w, h): 
self.w = w
self.h = h
def area(self):
return self.w * self.h
def perimeter(self):
return 2 * (self.w + self.h)
Capítulo 109: Las clases
Introducción
Python se ofrece a sí mismo no solo como un popular lenguaje de scripting, sino que también es 
compatible con el paradigma de programación orientado a objetos. Las clases describen datos y 
proporcionan métodos para manipular esos datos, todos incluidos en un solo objeto. Además, las 
clases permiten la abstracción al separar los detalles de implementación concretos de las 
representaciones abstractas de datos.
El código que utiliza clases es generalmente más fácil de leer, entender y mantener.
Examples
Herencia basica
La herencia en Python se basa en ideas similares utilizadas en otros lenguajes orientados a 
objetos como Java, C ++, etc. Una nueva clase puede derivarse de una clase existente de la 
siguiente manera.
BaseClass es la clase ya existente ( principal ), y DerivedClass es la nueva clase ( secundaria ) que 
hereda (o subclases ) atributos de BaseClass . Nota : a partir de Python 2.2, todas las clases
heredan implícitamente de la clase de object , que es la clase base para todos los tipos 
incorporados.
Definimos una clase de Rectangle principal en el siguiente ejemplo, que se hereda implícitamente 
del object :
La clase Rectangle se puede usar como una clase base para definir una clase Square , ya que un 
cuadrado es un caso especial de rectángulo.
    599/1068
    535
r.area()
# Output: 12 
r.perimeter() 
# Output: 14
s.area()
# Output: 4 
s.perimeter() 
# Output: 8
# subclass check 
issubclass(Square, Rectangle) 
# Output: True
# instantiate
r = Rectangle(3, 4) 
s = Square(2)
isinstance(r, Rectangle) 
# Output: True 
isinstance(r, Square)
# Output: False
# A rectangle is not a square
isinstance(s, Rectangle) 
# Output: True
# A square is a rectangle 
isinstance(s, Square)
# Output: True
Laclase Square heredaráautomáticamente todos losatributos delaclaseRectangle , así comola 
clase de objeto. super() se utiliza para llamar al init () de la clase Rectangle , esencialmente 
llamandoacualquier métodoanuladodelaclasebase.Nota:enPython3,super()norequiere 
argumentos.
Los objetos de clase derivados pueden acceder y modificar los atributos de sus clases base:
Funciones incorporadas que funcionan con 
herencia.
issubclass(DerivedClass, BaseClass) : devuelve True si DerivedClass es una subclase de BaseClass
isinstance(s, Class) :devuelve True sisesunainstanciadeClass ocualquieradelasclases 
derivadas de Class
class Square(Rectangle): 
def init (self, s):
# call parent constructor, w and h are both s 
super(Square, self). init (s, s)
self.s = s
    600/1068
    536
class C:
x = 2 # class variable
def init (self, y):
self.y = y # instance variable
C.x 
# 2
C.y
# AttributeError: type object 'C' has no attribute 'y'
c1 = C(3)
c1.x 
# 2
c1.y 
# 3
c2 = C(4)
c2.x 
# 2
c2.y 
# 4
c2.x = 4 
c2.x
# 4
C.x 
# 2
class D:
x = []
def init (self, item):
self.x.append(item) # note that this is not an assigment!
d1 = D(1) 
d2 = D(2)
d1.x
# [1, 2]
d2.x
# [1, 2]
D.x
# [1, 2]
Variables de clase e instancia
Las variables de instancia son únicas para cada instancia, mientras que las variables de clase son 
compartidas por todas las instancias.
Se puede acceder a las variables de clase en las instancias de esta clase, pero la asignación al 
atributo de clase creará una variable de instancia que sombrea la variable de clase
Tenga en cuenta que la mutación de variables de clase de instancias puede llevar a algunas 
consecuencias inesperadas.
    601/1068
    537
class A(object): 
def f(self, x):
return 2 * x
A.f
# <function A.f at ...> (in Python 3.x)
A.f
# <unbound method A.f> (in Python 2.x)
A.f. class
# <type 'instancemethod'>
A.f. func
# <function f at ...>
import inspect
inspect.isfunction(A.f) 
# True 
inspect.ismethod(A.f) 
# False
import inspect
inspect.isfunction(A.f) 
# False 
inspect.ismethod(A.f) 
# True
Métodos enlazados, no enlazados y estáticos.
La idea de métodos enlazados y no enlazados se eliminó en Python 3 . En Python 3 cuando 
declara un método dentro de una clase, está usando una palabra clave def , creando así un 
objeto de función. Esta es una función regular, y la clase circundante funciona como su espacio 
de nombres. En el siguiente ejemplo, declaramos el método f dentro de la clase A , y se convierte 
en una función Af :
Python 3.x 3.0
EnPython2,elcomportamientofuediferente:losobjetosdefuncióndentrodelaclasefueron 
reemplazadosimplícitamenteporobjetosdetipoinstancemethod ,quesedenominaronmétodosno 
vinculados porque no estaban vinculados a ningunainstancia de clase en particular.Fue posible 
acceder a la función subyacente utilizando la propiedad . func .
Python 2.x 2.3
Los últimos comportamientos se confirman mediante inspección: los métodos se reconocen como 
funciones en Python 3, mientras que la distinción se mantiene en Python 2.
Python 3.x 3.0
Python 2.x 2.3
En ambas versiones de Python function / method Af se puede llamar directamente, siempre que
    602/1068
    538
A.f(1, 7)
# Python 2: TypeError: unbound method f() must be called with
# A instance as first argument (got int instance instead) 
# Python 3: 14
a = A() 
A.f(a, 20)
# Python 2 & 3: 40
a = A()
a.f
# <bound method A.f of < main .A object at ...>> 
a.f(2)
# 4
# Note: the bound method object a.f is recreated *every time* you call it:
a.f is a.f # False
# As a performance optimization you can store the bound method in the object's 
# dict , in which case the method object will remain fixed:
a.f = a.f
a.f is a.f # True
class D(object): 
multiplier = 2
@classmethod 
def f(cls, x):
return cls.multiplier * x
@staticmethod 
def g(name):
print("Hello, %s" % name)
pase una instancia de clase A como primer argumento.
Supongamos ahora que a es una instancia de la clase A , lo que es af entonces? Bueno, 
intuitivamente este debe ser el mismo métodof de clase A , sólo que debe de alguna manera 
"saber" que se aplica al objeto a - método en Python esto se llama unida a a .
Losdetalles esenciales sonlos siguientes: writing af invoca el método magic getattribute de a
, que primero verifica si a tiene un atributo llamado f (no lo hace), luego verifica la clase A si 
contiene un método con ese nombre (lo hace), y crea un nuevo objeto m del method de tipo que 
tiene la referencia al Af original en m. func , y una referencia al objeto a en m. self .Cuando 
este objeto se llama como una función, simplemente hace lo siguiente: m(...) =>
m. func (m. self , ...) . Por lo tanto, este objeto se denomina método enlazado porque, 
cuando se invoca, sabe que debe proporcionar el objeto al que estaba vinculado como primer 
argumento. (Estas cosas funcionan de la misma manera en Python 2 y 3).
Finalmente, Python tiene métodos de clase y métodos estáticos , tipos especiales de métodos. 
Los métodos de clase funcionan de la misma manera que los métodos regulares, excepto que 
cuando se invocan en un objeto, se unen a la clase del objeto en lugar de al objeto. Así m. self
= type(a) . Cuando llama a dicho método enlazado, pasa la clase de a como primer argumento. 
Los métodos estáticos son incluso más simples: no vinculan nada en absoluto, y simplemente 
devuelven la función subyacente sin ninguna transformación.
    603/1068
    539
d = D()
d.multiplier = 1337 
(D.multiplier, d.multiplier) 
# (2, 1337)
d.f
# <bound method D.f of <class ' main .D'>> 
d.f(10)
# 20
# new-style class 
class New(object):
pass
# new-style instance 
new = New()
new. class
#<class'main.New'> 
type(new)
# <class 'main .New'> 
issubclass(New, object) 
# True
Tenga en cuenta que los métodos de clase están vinculados a la clase incluso cuando se accede 
a ellos en la instancia:
Valelapenaseñalar que enel nivel másbajo, lasfunciones,los métodos,los métodosestáticos, 
etc., son en realidad descriptores que invocan los métodos especiales get , set y 
opcionalmente del . Para más detalles sobre métodos de clase y métodos estáticos:
• ¿Cuál es la diferencia entre @staticmethod y @classmethod en Python?
• ¿Significado de @classmethod y @staticmethod para principiante?
Clases de estilo nuevo vs. estilo antiguo
Python 2.x 2.2.0
Las clases de nuevo estilo se introdujeron en Python 2.2 para unificar clases y tipos . Heredan del 
tipo de object nivel superior. Una clase de nuevo estilo es un tipo definido por el usuario y es muy 
similar a los tipos incorporados.
Las clases de estilo antiguo no heredan de object . Las instancias de estilo antiguo siempre se 
implementan con un tipo de instance incorporado.
D.f
#<boundmethodtype.fof<class'main.D'>> 
D.f(12)
# 24
D.g
# <function D.g at ...> 
D.g("world")
# Hello, world
    604/1068
    540
class MyClass: 
pass
my_inst = MyClass() 
type(my_inst)
# <class ' main .MyClass'>
my_inst. class
#<class' main .MyClass'> 
issubclass(MyClass, object) 
# True
class Rectangle(object):
def init (self, width, height, color='blue'): 
self.width = width
self.height = height 
self.color = color
def area(self):
return self.width * self.height
# Create some instances of the class 
default_rectangle = Rectangle(2, 3) 
print(default_rectangle.color) # blue
red_rectangle = Rectangle(2, 3, 'red') 
print(red_rectangle.color) # red
Python 3.x 3.0.0
En Python 3, se eliminaron las clases de estilo antiguo.
Las clases de nuevo estilo en Python 3 heredan implícitamente del object , por lo que ya no es 
necesario especificar MyClass(object) .
Valores por defecto para variables de instancia
Si la variable contiene un valor de un tipo inmutable (por ejemplo, una cadena), está bien asignar 
un valor predeterminado como este
Hay que tener cuidado al inicializar objetos mutables como listas en el constructor. Considere el 
siguiente ejemplo:
# old-style class 
class Old:
pass
# old-style instance 
old = Old()
old. class
# <class main .Old at ...> 
type(old)
# <type 'instance'> 
issubclass(Old, object) 
# False
    605/1068
    541
class Rectangle2D(object):
def init (self, width, height, pos=None, color='blue'): 
self.width = width
self.height = height
self.pos = pos or [0, 0] # default value is [0, 0] 
self.color = color
r1 = Rectangle2D(5,3) 
r2 = Rectangle2D(7,8) 
r1.pos[0] = 4
r1.pos # [4, 0]
r2.pos # [0, 0] r2's pos hasn't changed
class Foo(object):
foo = 'attr foo of Foo'
class Bar(object):
foo = 'attr foo of Bar' # we won't see this. 
bar = 'attr bar of Bar'
class FooBar(Foo, Bar):
foobar = 'attr foobar of FooBar'
Este comportamiento se debe al hecho de que en Python los parámetros predeterminados están 
vinculados en la ejecución de la función y no en la declaración de la función. Para obtener una 
variable de instancia predeterminada que no se comparte entre las instancias, se debe usar una 
construcción como esta:
Consulte también Argumentos predeterminados mutables y “Menos asombro” y el Argumento
predeterminado mutable .
Herencia múltiple
Python utiliza el algoritmo de linealización C3 para determinar el orden en el que resolver los 
atributos de clase, incluidos los métodos. Esto se conoce como Orden de resolución de métodos 
(MRO).
Aquí hay un ejemplo simple:
Ahora si creamos una instancia de FooBar, si buscamos el atributo foo, veremos que el atributo
class Rectangle2D(object):
def init (self, width, height, pos=[0,0], color='blue'): 
self.width = width
self.height = height 
self.pos = pos 
self.color = color
r1 = Rectangle2D(5,3) 
r2 = Rectangle2D(7,8) 
r1.pos[0] = 4
r1.pos # [4, 0]
r2.pos # [4, 0] r2's pos has changed as well
    606/1068
    542
fb = FooBar()
>>> fb.foo
'attr foo of Foo'
>>> FooBar.mro()
[<class ' main .FooBar'>, <class ' main .Foo'>, <class ' main .Bar'>, <type 'object'>]
class Foo(object):
def foo_method(self): 
print "foo Method"
class Bar(object):
def bar_method(self): 
print "bar Method"
class FooBar(Foo, Bar): 
def foo_method(self):
super(FooBar, self).foo_method()
class Foo(object): 
def init (self):
print "foo init"
class Bar(object): 
def init (self):
de Foo se encuentra primero
y
Aquí está el MRO de FooBar:
Se puede decir simplemente que el algoritmo MRO de Python es
1. Profundidad primero (por ejemplo, FooBar luego Foo ) a menos que
2. un padre compartido ( object ) está bloqueado por un hijo ( Bar )y
3. No se permiten relaciones circulares.
Es decir, por ejemplo, Bar no puede heredar de FooBar, mientras que FooBar hereda de Bar. 
Para un ejemplo completo en Python, vea la entrada de wikipedia .
Otra característica poderosa en la herencia es super . super puede obtener características de 
clases para padres.
Herencia múltiple con el método init de clase, cuando cada clase tiene su propio método init, 
entonces intentamos obtener una inercia múltiple, luego solo se llama al método init de la clase 
que se hereda primero.
para el siguiente ejemplo, solo se llama al método de inicio de clase Foo que no se llama a la 
clase de barra de inicio
    607/1068
    543
foobar init 
foo init
print isinstance(a,FooBar) 
print isinstance(a,Foo) 
print isinstance(a,Bar)
True 
True 
True
Salida:
Pero eso no significa que la clase Bar no sea hereditaria. La instancia de la clase FooBar final 
también es una instancia de la clase Bar y la clase Foo .
Salida:
Descriptores y búsquedas punteadas
Losdescriptores sonobjetosqueson(generalmente)atributosdeclasesyquetienencualquiera 
de los métodos especiales get , set o delete .
Losdescriptoresdedatostienencualquierade set , o delete
Estos pueden controlarla búsqueda de puntos en una instancia y se utilizanpara implementar 
funciones, staticmethod , classmethod y property . Una búsqueda de puntos (por ejemplo, la 
instancia foo de la clase Foo busca la bar atributos, es decir, foo.bar ) utiliza el siguiente algoritmo:
1. bar se mira en la clase, Foo . Si está allí y es un descriptor de datos , entonces se usa el 
descriptor de datos. Así es como la property puede controlar el acceso a los datos en una 
instancia, y las instancias no pueden anular esto. Si un descriptor de datos no está allí, 
entonces
2. bar se mira en la instancia dict . Es por esto que podemos anular o bloquear los 
métodos que seinvocan desdeunainstancia conuna búsqueda de puntos.Si existe una 
bar en la instancia, se utiliza. Si no, entonces nosotros
3. Busca en la clase Foo para bar . Si es un Descriptor , entonces se usa el protocolo del 
descriptor.Así es como se implementan las funciones (en este contexto, los métodos 
classmethod ), el classmethod y el staticmethod . De lo contrario, simplemente devuelve el
print "bar init"
class FooBar(Foo, Bar): 
def init (self):
print "foobar init" 
super(FooBar, self). init ()
a = FooBar()
    608/1068
    544
class Person(object):
def init (self, first_name, last_name, age): 
self.first_name = first_name 
self.last_name = last_name
self.age = age
self.full_name = first_name + " " + last_name
def greet(self):
print("Hello, my name is " + self.full_name + ".")
class Person(object):
def init (self, first_name, age, last_name=None): 
if last_name is None:
self.first_name, self.last_name = first_name.split(" ", 2) 
else:
self.first_name = first_name 
self.last_name = last_name
self.full_name = self.first_name + " " + self.last_name 
self.age = age
def greet(self):
print("Hello, my name is " + self.full_name + ".")
objeto allí, o hay un AttributeError
Métodos de clase: inicializadores alternos
Los métodos de clase presentan formas alternativas para construir instancias de clases. Para 
ilustrar, veamos un ejemplo.
Supongamos que tenemos una clase de Person relativamente simple:
Podría ser útil tener una forma de crear instancias de esta clase especificando un nombre 
completo en lugar del nombre y apellido por separado. Una forma de hacer esto sería tener el 
last_name como un parámetro opcional, y suponiendo que si no se da, pasamos el nombre 
completo en:
Sin embargo, hay dos problemas principales con este bit de código:
1. Los parámetros first_name y last_name ahora son last_name , ya que puede ingresar un 
nombre completo para first_name . Además, si hay más casos y / o más parámetros que 
tieneneste tipo de flexibilidad,la ramificación if/elif /else puede ser molesta rápidamente.
2. No es tan importante, pero aún así vale la pena señalar: ¿y si last_name es None , pero 
first_name no se divide en dos o más cosas a través de los espacios? Tenemos otra capa 
de validación de entrada y / o manejo de excepciones ...
Introduzca los métodos de clase.En lugar de tener un solo inicializador, crearemos un 
inicializador separado, llamado from_full_name , y lo classmethod decorador de classmethod 
(incorporado).
    609/1068
    545
In [2]: bob = Person("Bob", "Bobberson", 42)
In [3]: alice = Person.from_full_name("Alice Henderson", 31) 
In [4]: bob.greet()
Hello, my name is Bob Bobberson.
In [5]: alice.greet()
Hello, my name is Alice Henderson.
class Country(object):
Note clslugar de self como el primer argumento de from_full_name . Los métodos de clase se 
aplican a la clase general, no a una instancia de una clase dada (que es lo que el self 
generalmentedenota).Porlotanto,si clsesnuestra Persondeclase,entonceselvalordevuelto 
por la from_full_name método de clase es Person(first_name, last_name, age) , que utiliza la Person 
's init paracrearunainstanciadelaPersondeclase.Enparticular,situviéramosquehacer 
una subclase Employee of Person , from_full_name también funcionaría en la clase Employee .
Para mostrar que esto funciona como se esperaba, init instancias de Person de más deuna 
manera sin la bifurcación en init :
Otras referencias:
• Python @classmethod y @staticmethod para principiantes?
• https://docs.python.org/2/library/functions.html#classmethod
• https://docs.python.org/3.5/library/functions.html#classmethod
Composición de la clase
La composición de clase permite relaciones explícitas entre objetos. En este ejemplo, las 
personas viven en ciudades que pertenecen a países. La composición permite a las personas 
acceder al número de todas las personas que viven en su país:
class Person(object):
def init (self, first_name, last_name, age): 
self.first_name = first_name 
self.last_name = last_name
self.age = age
self.full_name = first_name + " " + last_name
@classmethod
def from_full_name(cls, name, age): 
if " " not in name:
raise ValueError
first_name, last_name = name.split(" ", 2) 
return cls(first_name, last_name, age)
def greet(self):
print("Hello, my name is " + self.full_name + ".")
    610/1068
    546
class A(object):
def init (self, num): 
self.num = num
def add (self, other):
return A(self.num + other.num)
def init (self): 
self.cities=[]
def addCity(self,city): 
self.cities.append(city)
class City(object):
def init (self, numPeople): 
self.people = [] 
self.numPeople = numPeople
def addPerson(self, person): 
self.people.append(person)
def join_country(self,country): 
self.country = country 
country.addCity(self)
for i in range(self.numPeople): 
person(i).join_city(self)
class Person(object): 
def init (self, ID):
self.ID=ID
def join_city(self, city): 
self.city = city 
city.addPerson(self)
def people_in_my_country(self):
x= sum([len(c.people) for c in self.city.country.cities]) 
return x
US=Country() 
NYC=City(10).join_country(US) 
SF=City(5).join_country(US)
print(US.cities[0].people[0].people_in_my_country()) 
# 15
Parche de mono
En este caso, "parche de mono" significa agregar una nueva variable o método a una clase 
después de que se haya definido. Por ejemplo, digamos que definimos la clase A como
Pero ahora queremos agregar otra función más adelante en el código. Supongamos que esta 
función es la siguiente.
    611/1068
    547
A.get_num = get_num
foo = A(42) 
A.get_num = get_num 
bar = A(6); 
foo.get_num() # 42
bar.get_num() # 6
dir(Class)
>>> dir(list)
[' add ', ' class ', ' contains ', ' delattr ', ' delitem ', ' dir ', ' doc ', 
' eq ', ' format ', ' ge ', ' getattribute ', ' getitem ', ' gt ', ' hash ',
' iadd ', ' imul ', ' init ', ' iter ', ' le ', ' len ', ' lt ', ' mul ',
' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' reversed ', ' rmul ',
' setattr ', ' setitem ', ' sizeof ', ' str ', ' subclasshook ', 'append', 'clear',
'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> [m for m in dir(list) if not m.startswith(' ')]
['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse',
Pero, ¿cómo añadimos esto como un método en A ? Eso es simple, simplemente colocamos esa 
función en A con una declaración de asignación.
¿Por qué funciona esto? Porque las funciones son objetos como cualquier otro objeto, y los 
métodos son funciones que pertenecen a la clase.
La función get_num estará disponible para todos los existentes (ya creados) así como para las 
nuevas instancias de A
Estas adiciones están disponibles en todas las instancias de esa clase (o sus subclases) 
automáticamente. Por ejemplo:
Tenga en cuenta que, a diferencia de otros idiomas, esta técnica no funciona para ciertos tipos 
integrados y no se considera un buen estilo.
Listado de todos los miembros de la clase
La función dir() se puede usar para obtener una lista de los miembros de una clase:
Por ejemplo:
Es común buscar solo miembros "no mágicos". Esto se puede hacer usando una comprensión 
simple que enumera los miembros con nombres que no comienzan con :
def get_num(self): 
return self.num
    612/1068
    548
def rename(self, renamed): # regular method 
"""Reassign and print the name attribute."""
self.name = renamed
print("Now my name is {}".format(self.name))
# special method
# instance attribute
def str (self):
"""ThismethodisrunwhenPythontries 
to cast the object to a string. Return 
this string when using print(), etc. 
"""
return self.name
def init (self, name): # special method
"""This is the initializer. It's a special 
method (see below).
"""
self.name = name
# docstring
# class attribute
class Person(object): 
"""Asimple class."""
species = "Homo Sapiens"
Advertencias:
Las clases pueden definir un dir () . Si ese método existe, se llama a dir() a dir () , de lo 
contrario,Python intentará crear una lista de miembros de laclase.Esto significa quela función 
dirpuede tenerresultadosinesperados.Dos citasdeimportanciadeladocumentación oficialde
python :
Si el objeto no proporciona dir (), la función intenta recopilar información del atributo 
dict del objeto, si está definido, y de su tipo de objeto. La lista resultante no está 
necesariamente completa, y puede ser inexacta cuando el objeto tiene un getattr () 
personalizado.
Nota: dado que dir () se proporciona principalmente como una conveniencia para su 
uso en una solicitud interactiva, intenta proporcionar un conjunto interesante de 
nombres más de lo que trata de proporcionar un conjunto de nombres definido de 
manera rigurosa o consistente, y su comportamiento detallado puede cambiar 
lanzamientos Por ejemplo, los atributos de metaclase no están en la lista de resultados 
cuando el argumento es una clase.
Introducción a las clases
Una clase, funciona como una plantilla que define las características básicas de un objeto en 
particular. Aquí hay un ejemplo:
Hay algunas cosas que se deben tener en cuenta al observar el ejemplo anterior.
1. La clase se compone de atributos (datos) y métodos (funciones).
2. Los atributos y métodos se definen simplemente como variables y funciones normales.
'sort']
    613/1068
    549
>>> # Instances
>>> kelly = Person("Kelly")
>>> joseph = Person("Joseph")
>>> john_doe = Person("John Doe")
>>> # Attributes
>>> kelly.species 
'Homo Sapiens'
>>> john_doe.species 
'Homo Sapiens'
>>> joseph.species 
'Homo Sapiens'
>>> kelly.name 
'Kelly'
>>> joseph.name 
'Joseph'
3. Como se indica en la cadena de documentación correspondiente, el init () se llama 
inicializador.Esequivalente al constructor enotros lenguajes orientados a objetos, y es el 
método que se ejecuta por primera vez cuandocrea un nuevoobjetoo una nuevainstancia 
de la clase.
4. Los atributos que se aplican a toda la clase se definen primero y se denominan atributos de 
clase .
5. Los atributos que se aplican a una instancia específica de una clase (un objeto) se 
denominan atributos de instancia .Generalmente se definen dentro de init (); esto no 
esnecesario, pero serecomienda(yaquelosatributos definidos fuerade init () corren 
el riesgo de ser accedidos antes de que se definan).
6. Cada método, incluido en la definición de clase, pasa el objeto en cuestión como su primer 
parámetro. La palabra self se usa para este parámetro (el uso de self es en realidad por 
convención, ya que la palabra self no tiene un significado inherente en Python, pero esta es 
una de las convenciones más respetadas de Python, y siempre se debe seguir).
7. Aquellos que están acostumbrados a la programación orientada a objetos en otros 
lenguajespuedensorprenderseporalgunas cosas.UnaesquePythonnotieneun concepto 
real de elementos private , por lo que todo, de manera predeterminada, imita el 
comportamiento de la palabra clave public C ++ / Java. Para obtener más información, 
consulte el ejemplo "Miembros de la clase privada" en esta página.
8. Algunos de los métodos de la clase tienen la siguiente forma: functionname (self, 
other_stuff) . Todos estos métodos se denominan "métodos mágicos" y son una parte 
importantedelas clases enPython.Porejemplo,la sobrecarga deoperadoresenPython se 
implementa con métodos mágicos. Para más información, consulte la documentación
relevante .
AhoravamosahaceralgunosejemplosdenuestraclasedePerson!
Actualmente tenemos tres objetos Person , kelly , joseph y john_doe .
Podemos acceder a los atributos de la clase desde cada instancia utilizando el operador de punto
. Note nuevamente la diferencia entre los atributos de clase e instancia:
Podemos ejecutar los métodos de la clase usando el mismo operador de punto . :
    614/1068
    550
class MyClass(object):
def init (self): 
self._my_string = ""
@property
def string(self):
"""A profoundly important string.""" 
return self._my_string
@string.setter
def string(self, new_value):
assert isinstance(new_value, str), \
"Give me a string, not a %r!" % type(new_value) 
self._my_string = new_value
@string.deleter 
def x(self):
self._my_string = None
mc = MyClass() 
mc.string = "String!" 
print(mc.string)
del mc.string
class Character(object): 
definit (name, max_hp):
self._name = name 
self._hp = max_hp 
self._max_hp = max_hp
Propiedades
Las clases de Python admiten propiedades , que parecen variables de objetos normales, pero 
con la posibilidad de adjuntar comportamiento y documentación personalizados.
De la clase de objeto MyClass parecerá tener tiene una propiedad .string , sin embargo su 
comportamiento está ahora estrictamente controlado:
Además de la sintaxis útil que se mencionó anteriormente, la sintaxis de la propiedad permite la 
validación u otros aumentos a esos atributos. Esto podría ser especialmente útil con las API 
públicas, donde se debe brindar un nivel de ayuda al usuario.
Otro uso común de las propiedades es permitir que la clase presente "atributos virtuales", 
atributos que no se almacenan en realidad, sino que se calculan solo cuando se solicitan.
>>> # Methods
>>> john_doe. str () 
'John Doe'
>>> print(john_doe) 
'John Doe'
>>> john_doe.rename("John") 
'Now my name is John'
    615/1068
    551
# Make hp read only by not providing a set method 
@property
def hp(self):
return self._hp
# Make name read only by not providing a set method 
@property
def name(self): 
return self.name
def take_damage(self, damage): 
self.hp -= damage
self.hp = 0 if self.hp <0 else self.hp
@property
def is_alive(self): 
return self.hp != 0
@property
def is_wounded(self):
return self.hp < self.max_hp if self.hp > 0 else False
@property
def is_dead(self):
return not self.is_alive
bilbo = Character('Bilbo Baggins', 100) 
bilbo.hp
# out : 100 
bilbo.hp = 200
# out : AttributeError: can't set attribute 
# hp attribute is read only.
bilbo.is_alive 
# out : True
bilbo.is_wounded 
# out : False 
bilbo.is_dead
# out : False 
bilbo.take_damage( 50 )
bilbo.hp 
# out : 50
bilbo.is_alive 
# out : True
bilbo.is_wounded 
# out : True 
bilbo.is_dead
# out : False
bilbo.take_damage( 50) 
bilbo.hp
# out :0
bilbo.is_alive 
# out : False
bilbo.is_wounded 
# out : False 
bilbo.is_dead
    616/1068
    552
class Singleton: 
def new (cls):
try:
it =cls. it
exceptAttributeError:
it = cls. it = object. new (cls) 
return it
def repr (self):
return '<{}>'.format(self. class . name .upper())
def eq (self, other): 
return other is self
class Singleton: 
"""
A non-thread-safe helper class to ease implementing singletons. 
This should be used as a decorator -- not a metaclass -- to the 
class that should be a singleton.
The decorated class can define one ` init ` function that 
takes only the `self` argument. Other than that, there are 
no restrictions that apply to the decorated class.
To get the singleton instance, use the `Instance` method. Trying 
to use ` call ` will result in a `TypeError` being raised.
Limitations: The decorated class cannot be inherited from. 
"""
def init (self, decorated): 
self._decorated = decorated
def Instance(self): 
"""
Returns the singleton instance. Upon its first call, it creates a 
new instance of the decorated class and calls its ` init ` method. 
On all subsequent calls, the already created instance is returned.
"""
try:
return self._instance 
except AttributeError:
self._instance = self._decorated() 
return self._instance
Clase de singleton
Un singleton es un patrón que restringe la creación de instancias de una clase a una instancia / 
objeto. Para más información sobre los patrones de diseño singleton de python, consulte aquí .
Otro método es decorar tu clase. Siguiendo el ejemplo de esta respuesta, crea una clase 
Singleton:
# out : True
    617/1068
    553
@Singleton 
class Single:
def init (self): 
self.name=None 
self.val=0
def getName(self): 
print(self.name)
x=Single.Instance() 
y=Single.Instance() 
x.name='I\'m single' 
x.getName()#outputsI'msingle 
y.getName()#outputsI'msingle
Para usar puedes usar el método de Instance
def call (self):
raise TypeError('Singletons must be accessed through `Instance()`.')
def instancecheck (self, inst):
return isinstance(inst, self._decorated)
    618/1068
    554
import csv
with open('/tmp/output.tsv', 'wt') as out_file: 
tsv_writer = csv.writer(out_file, delimiter='\t') 
tsv_writer.writerow(['name', 'field']) 
tsv_writer.writerow(['Dijkstra', 'Computer Science']) 
tsv_writer.writerow(['Shelah', 'Math']) 
tsv_writer.writerow(['Aumann', 'Economic Sciences'])
$ cat /tmp/output.tsv
name field
Dijkstra Computer Science 
Shelah Math
Aumann Economic Sciences
import pandas as pd
d = {'a': (1, 101), 'b': (2, 202), 'c': (3, 303)}
pd.DataFrame.from_dict(d, orient="index") 
df.to_csv("data.csv")
df = pd.read_csv("data.csv") 
d = df.to_dict()
Capítulo 110: Lectura y Escritura CSV
Examples
Escribiendo un archivo TSV
Pitón
Archivo de salida
Usando pandas
Escriba un archivo CSV desde un dict o un DataFrame .
Lea un archivo CSV como un DataFrame y DataFrame a un dict :
    619/1068
    555
lst = [1, 2, 3, 4]
lst[0] # 1
lst[1] # 2
lst[4] # IndexError: list index out of range
lst[-1] # 4
Capítulo 111: Lista
Introducción
La Lista de Python es una estructura de datos general ampliamente utilizada en los programas 
de Python. Se encuentran en otros idiomas, a menudo denominados arreglos dinámicos . Ambos 
son mutables y un tipo de datos de secuencia que les permite ser indexados y segmentados . La 
lista puede contener diferentes tipos de objetos, incluidos otros objetos de lista.
Sintaxis
• [valor, valor, ...]
• lista ([iterable])
Observaciones
listes un tipoparticulardeiterable, peronoesel únicoqueexisteenPython.Avecesserámejor 
usar set , tuple o dictionary
list es el nombre dado en Python a arreglos dinámicos (similar al vector<void*> de C ++ o
ArrayList<Object> de Java ArrayList<Object> ). No es una lista enlazada.
El acceso a los elementos se realiza en tiempo constante y es muy rápido. Anexar elementos al 
final de la lista es tiempo constante amortizado, pero de vez en cuando puede implicar la 
asignación y copia de toda la list .
Las comprensiones de listas están relacionadas con listas.
Examples
Acceso a los valores de la lista
Las listas de Python están indexadas a cero, y actúan como matrices en otros idiomas.
Intentar acceder a un índice fuera de los límites de la lista generará un IndexError .
Los índices negativos se interpretan como contadores desde el final de la lista.
    620/1068
    556
lst[5:8]
lst[1:10]
# [] since starting index is greater than length of lst, returns empty list 
# [2, 3, 4] same as omitting ending index
lst[len(lst)-1] # 4
lst[::-1] # [4, 3, 2, 1]
lst[3:1:-1] # [4, 3]
reversed(lst)[0:2] # 0 = 1 -1
# 2 = 3 -1
data = 'chandan purohit 22 2000' #assuming data fields of fixed length 
name_slice = slice(0,19)
age_slice = slice(19,21) 
salary_slice = slice(22,None)
#now we can have more readable slices 
print(data[name_slice]) #chandan purohit 
print(data[age_slice]) #'22'
print(data[salary_slice]) #'2000'
Esto es funcionalmente equivalente a
Las listas permiten usar notación de lst[start:end:step] como lst[start:end:step] . La salida de 
lanotación dedivisión esunanueva listaquecontiene elementosdesde elstarthasta el end-1del 
índice.Siseomitenlasopciones,startdefectoalprincipiodelalista,deendaextremodelalista 
y step al 1:
lst[1:] # [2, 3, 4]
lst[:3] # [1, 2, 3]
lst[::2] # [1, 3]
lst[::-1] # [4, 3, 2, 1]
lst[-1:0:-1] # [4, 3, 2]
Con esto en mente, puede imprimir una versión invertida de la lista llamando
Cuando se usan longitudes de pasos de cantidades negativas, el índice inicial debe ser mayor 
que el índice final, de lo contrario, el resultado será una lista vacía.
El uso de índices de pasos negativos es equivalente al siguiente código:
Los índices utilizados son 1 menos que los utilizados en la indexación negativa y se invierten.
Rebanado avanzado
Cuando las listas se getitem () se llama al método getitem () del objeto de lista, con un 
objetodeslice .Pythontieneunmétododedivisiónintegradoparagenerarobjetosdedivisión. 
Podemos usar esto para almacenar una porción y reutilizarla más tarde como así,
lst[-2] # 3
lst[-5] # IndexError: list index out of range
    621/1068
    557
a = [1, 2, 3, 4, 5]
# Append values 6, 7, and 7 to the list 
a.append(6)
a.append(7) 
a.append(7)
# a: [1, 2, 3, 4, 5, 6, 7, 7]
# Append another list 
b = [8, 9]
a.append(b)
# a: [1, 2, 3, 4, 5, 6, 7, 7, [8, 9]]
# Append an element of a different type, as list elements do not need to have the same 
type
my_string = "hello world" 
a.append(my_string)
# a: [1, 2, 3, 4, 5, 6, 7, 7, [8, 9], "hello world"]
# Appending a list to another list 
a = [1, 2, 3, 4, 5, 6, 7, 7]
b = [8, 9]
a.append(b)
# a: [1, 2, 3, 4, 5, 6, 7, 7, [8, 9]] 
a[8]
# Returns: [8,9]
a = [1, 2, 3, 4, 5, 6, 7, 7]
b = [8, 9, 10]
# Extend list by appending all elementsfrom b 
a.extend(b)
# a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10]
# Extend list with elements from a non-list enumerable: 
a.extend(range(3))
# a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 0, 1, 2]
Esto puede ser de gran utilidad al proporcionar funcionalidad de corte a nuestros objetos al 
reemplazar getitem en nuestra clase.
Lista de métodos y operadores soportados.
Comenzando con una lista dada a :
1. append(value) : agrega un nuevo elemento al final de lalista.
Tenga en cuenta que el método append() solo agrega un elemento nuevo al final de la lista. 
Si agrega una lista a otra, la lista que agregue se convertirá en un elemento único al final de 
la primera lista.
2. extend(enumerable) : extiende la lista agregando elementos de otro enumerable.
Las listas también se pueden concatenar con el operador + . Tenga en cuenta que esto no
    622/1068
    558
a.pop(2)
# Returns: 5
# a: [0, 1, 2, 3, 4,
a.pop(8)
# Returns: 7
# a: [0, 1, 2, 3, 4,
# With no argument: 
a.pop()
# Returns: 10
# a: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a = [1, 2, 3, 4, 5, 6] + [7, 7] + b
# a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10]
a.index(7) 
# Returns:6
a.index(49) # ValueError, because 49 is not in a. 
a.index(7, 7)
# Returns: 7
a.index(7, 8) # ValueError, because there is no 7 starting at index 8
a.insert(0, 0) # insert 0 at position 0
a.insert(2, 5) # insert 5 at position 2
# a: [0, 1, 5, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10]
a.remove(0) 
a.remove(9)
# a: [1, 2, 3, 4, 5, 6, 7, 8]
a.remove(10)
# ValueError, because 10 is not in a
modifica ninguna de las listas originales:
3. index(value, [startIndex]) índice de inicio index(value, [startIndex]) : obtiene el índice de 
la primera aparición del valor de entrada. Si el valor de entrada no está en la lista, se 
ValueError una excepción ValueError . Si se proporciona un segundo argumento, la
búsqueda se inicia en ese índiceespecificado.
4. insert(index, value) : inserta un value justo antes del index especificado. Así después de la 
inserción el nuevo elemento ocupa el index posición.
5. pop([index]) : elimina y devuelve el elemento en el index . Sin ningún argumento, elimina y 
devuelve el último elemento de la lista.
5, 6, 7, 7, 8, 9, 10]
5, 6, 7, 8, 9, 10]
6. remove(value) : elimina la primera aparición del valor especificado. Si no se puede encontrar 
el valor proporcionado, se ValueError un ValueError .
7. reverse() : invierte la lista en el lugar y devuelve None .
    623/1068
    559
import datetime
class Person(object):
def init (self, name, birthday, height): 
self.name = name
self.birthday = birthday 
self.height = height
def repr (self): 
return self.name
l.sort(key=lambda item: item.name)
# l: [Chuck Norris,John Cena,Jon Skeet]
l.sort(key=lambda item: item.birthday) 
# l: [Chuck Norris,Jon Skeet,JohnCena]
l.sort(key=lambda item: item.height)
# l: [John Cena, Chuck Norris, JonSkeet]
a.count(7) 
# Returns:2
a.sort()
# a = [1, 2, 3, 4, 5, 6, 7, 8]
# Sorts the list in numerical order
a.sort(reverse=True)
# a = [8, 7, 6, 5, 4, 3, 2, 1]
import datetime
l = [{'name':'John Cena', 'birthday': datetime.date(1992, 9, 12),'height': 175},
También hay otras formas de revertir una lista .
8. count(value) : cuenta el número de apariciones de algún valor en lalista.
9. sort() : ordena la lista en orden numérico y lexicográfico y devuelve None .
Laslistas también sepuedenrevertir cuandoseordenanusando la reverse=True en el 
método sort() .
Si desea ordenar por atributos de elementos, puede usar el argumento de palabra key clave:
l = [Person("John Cena", datetime.date(1992, 9, 12), 175),
Person("Chuck Norris", datetime.date(1990, 8, 28), 180),
Person("Jon Skeet", datetime.date(1991, 7, 6), 185)]
En caso de lista de dictados el concepto es el mismo:
a.reverse()
# a: [8, 7, 6, 5, 4, 3, 2, 1]
    624/1068
    https://riptutorial.com/es/home 560
import datetime
l = [{'name':'John Cena', 'birthday': datetime.date(1992, 9, 12),'size': {'height': 175, 
'weight': 100}},
{'name': 'Chuck Norris', 'birthday': datetime.date(1990, 8, 28),'size' : {'height': 180, 
'weight': 90}},
{'name': 'Jon Skeet', 'birthday': datetime.date(1991, 7, 6), 'size': {'height': 185, 
'weight': 110}}]
l.sort(key=lambda item: item['size']['height']) 
# l: [John Cena, Chuck Norris, Jon Skeet]
from operator import itemgetter,attrgetter
people = [{'name':'chandan','age':20,'salary':2000},
{'name':'chetan','age':18,'salary':5000},
{'name':'guru','age':30,'salary':3000}] 
by_age = itemgetter('age')
by_salary = itemgetter('salary')
people.sort(key=by_age) #in-place sorting by age 
people.sort(key=by_salary) #in-place sorting by salary
list_of_tuples = [(1,2), (3,4), (5,0)] 
list_of_tuples.sort(key=itemgetter(1)) 
print(list_of_tuples) #[(5, 0), (1, 2), (3, 4)]
persons = [Person("John Cena", datetime.date(1992, 9, 12), 175),
Person("Chuck Norris", datetime.date(1990, 8, 28), 180),
Ordenar por subdivisión:
Mejor manera de ordenar usando attrgetter y itemgetter
Las listas también se pueden clasificar utilizando las funciones attrgetter y itemgetter del módulo 
del operador. Estos pueden ayudar a mejorar la legibilidad y la reutilización. Aquí hay unos 
ejemplos,
itemgetter también se puede dar un índice. Esto es útil si desea ordenar según los índices de una 
tupla.
Utilice el attrgetter si desea ordenar por atributos de un objeto,
{'name': 'Chuck Norris', 'birthday': datetime.date(1990, 8, 28),'height': 180},
{'name': 'Jon Skeet', 'birthday': datetime.date(1991, 7, 6), 'height': 185}]
l.sort(key=lambda item: item['name'])
# l: [Chuck Norris, John Cena, Jon Skeet]
l.sort(key=lambda item: item['birthday']) 
# l: [ChuckNorris,Jon Skeet, JohnCena]
l.sort(key=lambda item: item['height']) 
# l: [JohnCena, Chuck Norris, Jon Skeet]
    625/1068
    561
a.clear() 
# a = []
b = ["blah"] * 3
# b = ["blah", "blah", "blah"] 
b = [1, 3, 5] * 5
# [1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3, 5]
a = list(range(10)) 
del a[::2]
# a = [1, 3, 5, 7, 9]
del a[-1]
# a = [1, 3, 5, 7]
del a[:] 
# a = []
b = a 
a.append(6)
# b: [1, 2, 3, 4, 5, 6]
10. clear() : elimina todos los elementos de lalista
11. Replicación : multiplicar una lista existente por un número entero producirá una lista más 
grande que consiste en tantas copias del original. Esto puede ser útil, por ejemplo, para la 
inicialización de listas:
Tenga cuidado al hacer esto si su lista contiene referencias a objetos (por ejemplo, una lista 
de listas), vea Errores comunes: multiplicación de listas y referencias comunes .
12. Eliminación de elementos : es posible eliminar varios elementos de la lista utilizando la 
palabra clave del y la notación de segmento:
13. Proceso de copiar
La asignación predeterminada "=" asigna una referencia de la lista original al nuevo nombre. 
Es decir, el nombre original y el nuevo nombre apuntan al mismo objeto de lista. Los 
cambios realizados a través de cualquiera de ellos se reflejarán en otro. Esto a menudo no 
es lo que pretendías.
Si desea crear una copia de la lista, tiene las siguientes opciones. 
Puedes cortarlo:
new_list = old_list[:]
Person("Jon Skeet", datetime.date(1991, 7, 6), 185)] #reusing Person class from 
above example
person.sort(key=attrgetter('name')) #sort by name 
by_birthday = attrgetter('birthday') 
person.sort(key=by_birthday) #sort by birthday
    626/1068
    562
new_list = list(old_list)
import copy
new_list = copy.copy(old_list) #inserts references to the objects found in the original.
import copy
new_list = copy.deepcopy(old_list) #inserts copies of the objects found in the original.
aa = a.copy()
# aa = [1, 2, 3, 4, 5]
len(['one', 'two']) # returns 2
len(['one', [2, 3], 'four']) # returns 3, not 4
my_list = ['foo', 'bar', 'baz'] 
for item in my_list:
print(item)
# Output: foo
Puedes usar la función integrada en la lista ():
Puedes usar copy.copy genérico ():
Esto es un poco más lento que list () porque primero tiene que averiguar el tipo de datos de 
old_list.
Si la lista contiene objetos y también desea copiarlos, use copy.deepcopy genérico ():
Obviamente, el método más lento y que más memoria necesita, pero a veces inevitable.
Python 3.x 3.0
copy() - Devuelve una copia superficial de la lista
Longitud de una lista
Use len() para obtener la longitud unidimensional de una lista.
len()tambiénfuncionaencadenas,diccionariosyotrasestructurasdedatossimilaresalaslistas. 
Tenga en cuenta que len() es una función incorporada, no un método de un objeto de lista.
También tenga en cuenta que el costo de len() es O(1) , lo que significa que tomará la misma 
cantidad de tiempo paraobtenerlalongitud deunalista,independientemente de sulongitud.
Iterando sobre una lista
Python admite el uso de un bucle for directamente en una lista:
    627/1068
    563
for (index, item) in enumerate(my_list):
print('The item in position {} is: {}'.format(index, item))
# Output: The item in position 0 is: foo 
# Output: The item in position 1 is: bar 
# Output: The item in position 2 is: baz
for i in range(0,len(my_list)): 
print(my_list[i])
#output:
>>>
foo 
bar 
baz
for item in my_list: 
if item == 'foo':
del my_list[0] 
print(item)
# Output: foo 
# Output: baz
lst = ['test', 'twest', 'tweast', 'treast']
'test' in lst 
#Out: True
'toast' in lst 
# Out: False
También puede obtener la posición de cada elemento al mismo tiempo:
La otra forma de iterar una lista basada en el valor del índice:
Tenga en cuenta que cambiar elementos en una lista mientras se iteran en ella puede tener 
resultados inesperados:
En este último ejemplo, eliminamos el primer elemento en la primera iteración, pero eso hizo que 
se omitiera la bar .
Comprobando si un artículo está en una lista
Python hace que sea muy sencillo comprobar si un elemento está en una lista. Simplemente use 
el operador in .
Nota:eloperadorinenconjuntosesasintóticamentemásrápidoqueenlaslistas.Si 
necesitausarlo muchas veces en listas potencialmente grandes,puede convertir su 
list en un set y probar la presencia de elementos en el set .
# Output: bar 
# Output: baz
    628/1068
    564
In [3]: rev = reversed(numbers)
In [4]: rev
Out[4]: [9, 8, 7, 6, 5, 4, 3, 2, 1]
In [1]: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
In [2]: numbers[::-1]
Out[2]: [9, 8, 7, 6, 5, 4, 3, 2, 1]
lst = []
if not lst:
print("list is empty")
# Output: list is empty
merged = list1 + list2
alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3']
for a, b in zip(alist, blist):
Elementos de la lista de inversión
Puede utilizar la función reversed que devuelve un iterador a la lista invertida:
Tenga en cuenta que la lista de "números" permanece sin cambios por esta operación, y 
permanece en el mismo orden en que estaba originalmente.
Para invertir en su lugar, también puede utilizar el método reverse .
También puede revertir una lista (al obtener una copia, la lista original no se ve afectada) 
utilizando la sintaxis de corte, estableciendo el tercer argumento (el paso) como -1:
Comprobando si la lista está vacía
ElvacíodeunalistaestáasociadoalbooleanoFalse ,porloquenotienequemarcarlen(lst) == 
0 , sino solo lst o notlst
Concatenar y fusionar listas
1. La forma más sencilla de concatenar list1 y list2 :
2. zip devuelve una lista de tuplas , donde la i-th tupla contiene el elemento i-th de cadauna 
de las secuencias de argumentos o iterables:
slst = set(lst) 
'test' in slst 
# Out:True
    629/1068
    565
alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3', 'b4'] 
for a, b in zip(alist, blist):
print(a, b)
# Output:
# a1 b1 
# a2 b2 
# a3 b3
alist = [] 
len(list(zip(alist, blist)))
# Output: 
# 0
alist = ['a1', 'a2', 'a3'] 
blist = ['b1']
clist = ['c1', 'c2', 'c3', 'c4']
for a,b,c in itertools.zip_longest(alist, blist, clist): 
print(a, b, c)
# Output:
# a1 b1 c1
# a2 None c2 
# a3 None c3
# None None c4
alist = [123, 'xyz', 'zara', 'abc'] 
alist.insert(3, [2009]) 
print("Final List :", alist)
Final List : [123, 'xyz', 'zara', 2009, 'abc']
Si las listas tienen diferentes longitudes, el resultado incluirá solo tantos elementos como el 
más corto:
Para listas de relleno de longitud desigual a la más larga con None s use
itertools.zip_longest ( itertools.izip_longest en Python 2)
3. Insertar en un índice de valores específicos:
Salida:
Todos y cada uno
print(a, b)
# Output: 
# a1 b1 
# a2 b2
# a3 b3
    630/1068
    566
nums = [1, 1, 0, 1]
all(nums) 
# False
chars = ['a', 'b', 'c', 'd'] 
all(chars)
# True
nums = [1, 1, 0, 1]
any(nums) 
# True
vals = [None, None, None, False] 
any(vals)
# False
vals = [1, 2, 3, 4]
any(val > 12 for val in vals) 
# False
any((val * 2) > 6 for val in vals) 
# True
names = ["aixk", "duke", "edik", "tofp", "duke"] 
list(set(names))
# Out: ['duke', 'tofp', 'aixk', 'edik']
alist = [[[1,2],[3,4]], [[5,6,7],[8,9,10], [12, 13, 14]]]
Puede usar all() para determinar si todos los valores en una evaluación iterable a True
Del mismo modo, any() determina si uno o más valores en una evaluación iterable a True
Si bien este ejemplo utiliza una lista, es importante tener en cuenta que estos elementos 
integrados funcionan con cualquier iterable, incluidos los generadores.
Eliminar valores duplicados en la lista
Laeliminacióndevaloresduplicadosenunalistasepuedehacerconvirtiendolalistaenunset 
(esdecir,unacoleccióndesordenadadeobjetosdistintos).Si senecesita unaestructura dedatos 
delist,entoncesel conjuntosepuede convertirdenuevo a unalistausandolalist()funciones 
list() :
Tenga en cuenta que al convertir una lista en un conjunto, el pedido original se pierde. 
Para preservar el orden de la lista, se puede usar un OrderedDict
Acceso a valores en lista anidada
Comenzando con una lista tridimensional:
import collections
>>> collections.OrderedDict.fromkeys(names).keys() 
# Out: ['aixk', 'duke', 'edik', 'tofp']
    631/1068
    567
for row in range(len(alist)): #A less Pythonic way to loop through lists 
for col in range(len(alist[row])):
print(alist[row][col])
print(alist[0][0][1]) 
#2
#Accesses second element in the first list in the first list
print(alist[1][1][2]) 
#10
#Accesses the third element in the second list in the second list
alist[0][0].append(11)
print(alist[0][0][2]) 
#11
#Appends 11 to the end of the first list in the first list
for row in alist: #One way to loop through nested lists 
for col in row:
print(col) 
#[1, 2, 11]
#[3, 4]
#[5, 6, 7]
#[8, 9, 10]
#[12, 13, 14]
[col for row in alist for col in row]
#[[1, 2, 11], [3, 4], [5, 6, 7], [8, 9, 10], [12, 13, 14]]
alist[1].insert(2, 15)
#Inserts 15 into the third position in the second list
Accediendo a los elementos de la lista:
Realizando operaciones de soporte:
Usando anidados para bucles para imprimir la lista:
Tenga en cuenta que esta operación se puede utilizar en una lista de comprensión o incluso como 
un generador para producir eficiencias, por ejemplo:
No todos los elementos en las listas externas tienen que ser listas ellos mismos:
Otra forma de utilizar anidados para bucles. La otra forma es mejor, pero he necesitado usar esto 
en ocasiones:
#[1, 2, 11]
#[3, 4]
#[5, 6, 7]
#[8, 9, 10]
#15
#[12, 13, 14]
    632/1068
    568
print(alist[1][1:])
#[[8, 9, 10], 15, [12, 13, 14]]
#Slices still work
print(alist)
#[[[1, 2, 11], [3, 4]], [[5, 6, 7], [8, 9, 10], 15, [12, 13, 14]]]
[1, 10, 100] < [2, 10, 100]
# True, because 1 < 2
[1, 10, 100] < [1, 10, 100]
# False, because the lists are equal 
[1, 10, 100] <= [1, 10, 100]
# True, because the lists are equal 
[1, 10, 100] < [1, 10, 101]
# True, because 100 < 101
[1, 10, 100] < [0, 10, 100]
# False, because 0 < 1
[1, 10] < [1, 10, 100]
# True
my_list = [None] * 10 
my_list = ['test'] * 10
>>> my_list=[{1}] * 10
>>> print(my_list)
[{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}]
>>> my_list[0].add(2)
>>> print(my_list)
[{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}]
Usando rebanadas en la lista anidada:
La lista final:
Comparacion de listas
Es posible comparar listas y otras secuencias lexicográficamente usando operadores de 
comparación. Ambos operandos deben ser del mismo tipo.
Si una de las listas está contenida al comienzo de la otra, la lista más corta gana.
Inicializando una lista a un número fijo de elementos
Para elementos inmutables (por ejemplo, None , literales de cadenas, etc.):
Para elementos mutables , la misma construcción dará como resultado que todos los elementos 
de la lista se refieran al mismo objeto, por ejemplo, para un conjunto:
En su lugar, para inicializar la lista con un número fijo de objetos mutables diferentes , use:
    633/1068
    569
my_list=[{1} for _ in range(10)]
    634/1068
    570
[<expression> for <element> in <iterable> if <condition>]
[x for x in range(10) if x % 2 == 0] 
# Out: [0, 2, 4, 6, 8]
Capítulo 112: Lista de Comprensiones
Introducción
Una lista de comprensión es una herramienta sintáctica para crearlistas de forma natural y 
concisa, como seilustra en el siguiente códigoparahaceruna lista de cuadradosde los números 
del 1 al 10: [i ** 2 for i in range(1,11)] El dummy i de un range lista existente se usa para 
hacerunnuevopatróndeelemento.Seusadondeunbucleforseríanecesarioenlenguajes 
menos expresivos.
Sintaxis
• [i for i in range (10)] # lista de comprensión básica
• [i for i in xrange (10)] # lista de comprensión básica con objeto generador en Python 2.x
• [i for i in range (20) if i% 2 == 0] # con filtro
• [x + y para x en [1, 2, 3] para y en [3, 4, 5]] # bucles anidados
• [i if i> 6 else 0 for i in range (10)] # expresión ternaria
• [i if i> 4 else 0 para i en el rango (20) if i% 2 == 0] # con filtro y expresión ternaria
• [[x + y para x en [1, 2, 3]] para y en [3, 4, 5]] # comprensión de lista anidada
Observaciones
La lista de comprensión se describió en PEP 202 y se introdujo en Python 2.0.
Examples
Lista de comprensiones condicionales
Dada una lista de comprensión , puede agregar uno o más if condiciones para filtrar los valores.
Para cada <element> en <iterable> ; Si <condition> evalúa como True , agregue <expression>
(generalmente una función de <element> ) a la lista devuelta.
Por ejemplo, esto se puede usar para extraer solo números pares de una secuencia de enteros:
Demo en vivo
El código anterior es equivalente a:
    635/1068
    571
[x if x % 2 == 0 else None for x in range(10)]
# Out: [0, None, 2, None, 4, None, 6, None, 8, None]
<value-if-condition-is-true> if <condition> else <value-if-condition-is-false>
[2 * (x if x % 2 == 0 else -1) + 1 for x in range(10)] 
# Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1]
[2 * (x if x % 2 == 0 else -1) + 1 for x in xrange(10)] 
# Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1]
numbers = []
for x in range(10): 
if x % 2 == 0:
temp = x 
else:
temp = -1
Además,unacomprensióncondicionaldelalistadelaforma[efor xin y ifc](dondeeycson 
expresionesentérminosdex)esequivalentealist(filter(lambdax:c,map(lambdax: e,y))).
A pesar de proporcionar el mismo resultado, preste atención al hecho de que el ejemplo anterior 
es casi 2 veces más rápido que el segundo. Para aquellos que tienen curiosidad, esta es una 
buena explicación de la razón.
Tengaencuentaqueestoesbastantediferentedelaexpresióncondicional...if...else...(a 
vecesconocidacomoexpresión ternaria ) quepuedeusarparalaparte<expression> delalistade 
comprensión. Considere el siguienteejemplo:
Demo en vivo
Aquí, la expresión condicional no es un filtro, sino un operador que determina el valor que se 
utilizará para los elementos de la lista:
Esto se vuelve más obvio si lo combinas con otros operadores:
Demo en vivo
Siestá utilizandoPython2.7, xrangepuedesermejorqueelrange porvariosmotivos,como se 
describe en la documentación de xrange .
El código anterior es equivalente a:
even_numbers = [] 
for x in range(10):
if x % 2 == 0:
even_numbers.append(x)
print(even_numbers) 
# Out: [0, 2, 4, 6, 8]
    636/1068
    572
[x if x > 2 else '*' for x in range(10) if x % 2 == 0] 
# Out: ['*', '*', 4, 6, 8]
[x if (x > 2 and x % 2 == 0) else '*' for x in range(10)] 
# Out:['*', '*', '*', '*', 4, '*', 6, '*', 8, '*']
[ expression for target1 in iterable1 [if condition1] 
for target2 in iterable2 [if condition2]... 
for targetN in iterableN [if conditionN] ]
data = [[1, 2], [3, 4], [5, 6]]
output = []
for each_list in data:
for element in each_list: 
output.append(element)
print(output)
# Out: [1, 2, 3, 4, 5, 6]
data = [[1, 2], [3, 4], [5, 6]]
output = [element for each_list in data for element in each_list] 
print(output)
# Out: [1, 2, 3, 4, 5, 6]
Sepuede combinar expresiones ternarios y if las condiciones.El operadorternario trabaja en el 
resultado filtrado:
Lo mismo no podría haberse logrado solo por el operador ternario:
Vea también: Filtros , que a menudo proporcionan una alternativa suficiente a las comprensiones 
de listas condicionales.
Lista de Comprensiones con Bucles Anidados
Las Comprensiones de lista pueden usar anidados for bucles.Puede codificar cualquier número 
de bucles for anidados dentro de una lista por comprensión, y cada uno for bucle puede tener 
una opción asociada if la prueba. Al hacerlo, el orden de la for las construcciones es del mismo 
orden que la hora de escribir una serie de anidado for declaraciones. La estructura general de las 
listas de comprensión se veasí:
Por ejemplo, el siguiente código aplanamiento una lista de listas utilizando múltiples for
declaraciones:
se puede escribir de forma equivalente como una lista de comprensión con múltiples for
construcciones:
numbers.append(2 * temp + 1) 
print(numbers)
# Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1]
    637/1068
    573
In [1]: data = [[1,2],[3,4],[5,6]]
In [2]: def f():
...: output=[]
...: for each_list in data:
...: for element in each_list:
...: output.append(element)
...: returnoutput 
In [3]: timeitf()
1000000 loops, best of 3: 1.37 µs per loop
In [4]: timeit [inner for outer in data for inner in outer] 
1000000 loops, best of 3: 632 ns per loop
data = [[1], [2, 3], [4, 5]]
output = [element for each_list in data
if len(each_list) == 2 
for element in each_list 
if element != 5]
print(output) 
# Out: [2, 3, 4]
Demo en vivo
Tanto en la forma expandida como en la lista de comprensión, el bucle externo (primero para la 
declaración) aparece primero.
Además de ser más compacto, la comprensión anidada también es significativamente más rápida.
La sobrecarga para la llamada de función anterior es de aproximadamente 140 ns .
Enlíneaif sestánanidadosdemanerasimilar,ypuedeocurrirencualquierposicióndespuésde 
la primera for :
Demo en vivo
Sin embargo, por razones de legibilidad, debe considerar el uso de bucles for tradicionales. Esto 
es especialmente cierto cuando el anidamiento tiene más de 2 niveles de profundidad y / o la 
lógica de la comprensión es demasiado compleja. la comprensión de múltiples listas de bucles 
anidadas podría ser propensa a errores o dar un resultado inesperado.
Refactorización de filtro y mapa para enumerar las comprensiones.
Las funciones de filter o map menudo deben serreemplazadas porlistas de comprensión . Guido 
Van Rossum describe esto bien en una carta abierta en 2005 :
filter(P, S) casi siempre se escribe más claro como [x for x in S if P(x)] , y esto 
tienelagranventajadequelosusosmáscomunesincluyenpredicadosqueson 
comparaciones, por ejemplo, x==42 , y la definición de un lambda para eso solo 
requieremuchomásesfuerzoparaellector(másellambdaesmáslentoquelalista 
de comprensión). Más aún para el map(F, S) que se convierte en [F(x) for x in S] . 
Por supuesto, en muchos casos podrías usar expresiones generadoras.
    638/1068
    574
filter(lambda x: x % 2 == 0, range(10)) # even numbers < 10 
map(lambda x: 2*x, range(10)) # multiply each number by two 
reduce(lambda x,y: x+y, range(10)) # sum of all elements in list
# Filter:
# P(x) = x % 2 == 0
# S = range(10)
[x for x in range(10) if x % 2 == 0]
# Map
# F(x) = 2*x
# S = range(10)
[2*x for x in range(10)]
# Map & Filter
filtered = filter(lambda x: x % 2 == 0, range(10)) 
results = map(lambda x: 2*x, filtered)
# List comprehension
results = [2*x for x in range(10) if x % 2 == 0]
map(F, S) == [F(x) for x in S]
filter(P, S) == [x for x in S if P(x)]
Las siguientes líneas de código se consideran " no pythonic " y generarán errores en muchos 
linters de python.
Tomando lo que hemos aprendido de la cita anterior, podemos desglosar estas expresiones de 
filter y map en sus listas de comprensión equivalentes; También elimina las funciones lambda de 
cada una, lo que hace que el código sea más legible en el proceso.
La legibilidad se vuelve aún más evidente cuando se trata de funciones de encadenamiento. 
Donde debido a la legibilidad, los resultados de un mapa o función de filtro deben pasarse como 
resultado al siguiente; con casos simples, estos pueden ser reemplazados por una sola lista de 
comprensión. Además, podemos decir fácilmente de la comprensión de la lista cuál es el 
resultado de nuestro proceso, dónde hay más carga cognitiva al razonar sobre el proceso de 
Mapa y Filtro encadenado.
Refactorización - Referencia rápida
• Mapa
• Filtrar
donde F y P son funciones que transforman respectivamente los valores de entrada y devuelven 
un bool
    639/1068
    575
#List Comprehension with nested loop
[x + y for x in [1, 2, 3] for y in [3, 4, 5]]
#Out: [4, 5, 6, 5, 6, 7, 6, 7, 8]
#Nested List Comprehension
[[x + y for x in [1, 2, 3]] for y in [3, 4, 5]]
#Out: [[4, 5, 6], [5, 6, 7], [6, 7, 8]]
l = []
for y in [3, 4, 5]: 
temp = []
for x in [1, 2, 3]: 
temp.append(x + y)
l.append(temp)
matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
[[row[i] for row in matrix] for i in range(len(matrix))] 
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
[[[i + j + k for k in 'cd'] for j in 'ab'] for i in '12']
# Out: [[['1ac', '1ad'], ['1bc', '1bd']], [['2ac', '2ad'], ['2bc', '2bd']]]
>>> list_1 = [1, 2, 3 , 4]
>>> list_2 = ['a', 'b', 'c', 'd']
>>> list_3 = ['6', '7', '8', '9']
# Two lists
>>> [(i, j) for i, jin zip(list_1, list_2)] 
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
# Three lists
Comprensiones de lista anidadas
Las comprensiones de listas anidadas, a diferencia de las comprensiones de listas con bucles 
anidados, son comprensiones de listas dentro de una comprensión de listas. La expresión inicial 
puede ser cualquier expresión arbitraria, incluida otra lista de comprensión.
El ejemplo anidado es equivalente a
Un ejemplo donde se puede usar una comprensión anidada para transponer una matriz.
Al igual que anidado for bucles, no hay límite a cómo se pueden anidarlas comprensiones 
profundas.
Iterar dos o más listas simultáneamente dentro de la comprensión de la lista
Paraiterar más de dos listas simultáneamente dentro de lacomprensión dela lista , se puede 
usar zip() como:
    640/1068
    576
>>> [(i, j, k) for i, j, k in zip(list_1, list_2, list_3)] 
[(1, 'a', '6'), (2, 'b', '7'), (3, 'c', '8'), (4, 'd', '9')]
# so on ...
    641/1068
    577
a, b = (1, 2)
print(a) 
# Prints:1 
print(b)
# Prints: 2
a, b, c = [1]
# Raises: ValueError: not enough values to unpack (expected 3, got 1)
head, *tail = [1, 2, 3, 4, 5]
print(head) 
# Prints: 1 
print(tail)
# Prints: [2, 3, 4, 5]
l = [1, 2, 3, 4, 5]
head = l[0] 
tail = l[1:]
Capítulo 113: Lista de desestructuración 
(también conocido como embalaje y 
desembalaje)
Examples
Tarea de destrucción
En las asignaciones, puede dividir un Iterable en valores usando la sintaxis de "desempaquetar":
La destrucción como valores.
Si intenta desempaquetar más de la longitud del iterable, obtendrá un error:
Python 3.x 3.0
La destrucción como lista
Puede desempaquetar una lista de longitud desconocida usando la siguiente sintaxis:
Aquí, extraemos el primer valor como un escalar, y los otros valores como una lista:
Lo que equivale a:
    642/1068
    578
a, b, *other, z = [1, 2, 3, 4, 5] 
print(a, b, z, other)
# Prints: 1 2 5 [3, 4]
a, _ = [1, 2]
print(a) 
#Prints: 1
a, _, c = (1, 2, 3)
print(a) 
# Prints:1 
print(c)
# Prints: 3
a, *_ = [1, 2, 3, 4, 5]
print(a) 
#Prints: 1
a, *_, b = [1, 2, 3, 4, 5]
print(a, b) 
# Prints: 15
a, _, b, _, c, *_ = [1, 2, 3, 4, 5, 6]
print(a, b, c) 
# Prints: 1 3 5
def fun1(arg1, arg2, arg3): 
return (arg1,arg2,arg3)
También funciona con múltiples elementos o elementos del final de la lista:
Ignorar valores en las tareas de desestructuración.
Si solo está interesado en un valor dado, puede usar _ para indicar que no está interesado. Nota: 
esto aún establecerá _ , solo la mayoría de la gente no lo usa como una variable.
Python 3.x 3.0
Ignorar listas en tareas de desestructuración.
Finalmente, puede ignorar muchos valores usando la sintaxis *_ en la asignación:
lo que no es realmente interesante, ya que podría usar la indexación en la lista. Donde se pone 
agradable es mantener el primer y último valor en una tarea:
o extraer varios valores a la vez:
Argumentos de la función de embalaje
En funciones, puede definir una serie de argumentos obligatorios:
    643/1068
    579
fun1(1, 2, 3)
def fun2(arg1='a', arg2='b', arg3='c'): 
return (arg1,arg2,arg3)
fun2(arg2=2, arg3=3) → (a,2,3)
...
→ (1,b,c)
→ (1,2,c)
fun2(1) 
fun2(1, 2)
l = [1,2,3]
fun1(*l)
# Returns: (1,2,3) 
fun1(*['w', 't', 'f'])
# Returns: ('w','t','f')
fun1(*['oops'])
# Raises: TypeError: fun1() missing 2 required positional arguments: 'arg2' and 'arg3'
d = {
'arg1': 1,
'arg2': 2,
'arg3': 3
}
fun1(**d)
# Returns: (1, 2, 3)
lo que hará que la función se pueda llamar solo cuando se den los tres argumentos:
y puede definir los argumentos como opcionales, utilizando valores predeterminados:
por lo que puede llamar a la función de muchas maneras diferentes, como:
Perotambiénpuedeusarlasintaxisdedesestructuraciónparaempacarargumentos,de modo 
que puede asignar variables usando una list o un dict .
Empaquetando una lista de argumentos
Considera que tienes una lista de valores.
Puede llamar a la función con la lista de valores como un argumento usando la sintaxis * :
Pero si no proporciona una lista cuya longitud coincida con el número de argumentos:
Packing argumentos de palabras clave
Ahora, también puede empaquetar argumentos utilizando un diccionario. Puede usar el operador
** para decirle a Python que descomprima el dict como valores de parámetros:
    644/1068
    580
fun1(**{'arg1':1, 'arg2':2})
# Raises: TypeError: fun1() missing 1 required positional argument: 'arg3' 
fun1(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun1() got an unexpected keyword argument 'arg4'
fun2(**d)
# Returns: (1, 2, 3)
fun2(**{'arg2': 2})
# Returns: ('a', 2, 'c')
fun2(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun2() got an unexpected keyword argument 'arg4'
def fun3(arg1, arg2='b', arg3='c') 
return (arg1, arg2, arg3)
fun3(*[1])
# Returns: (1, 'b', 'c') 
fun3(*[1,2,3])
# Returns: (1, 2, 3)
fun3(**{'arg1':1})
# Returns: (1, 'b', 'c') 
fun3(**{'arg1':1, 'arg2':2, 'arg3':3}) 
# Returns: (1, 2, 3)
fun3(*[1,2], **{'arg3':3}) 
# Returns: (1,2,3)
cuando la función solo tiene argumentos posicionales (los que no tienen valores 
predeterminados), necesita que el diccionario contenga todos los parámetros esperados y no 
tenga un parámetro adicional, o obtendrá un error:
Para las funciones que tienen argumentos opcionales, puede empaquetar los argumentos como 
un diccionario de la misma manera:
Pero allí puede omitir valores, ya que serán reemplazados por los valores predeterminados:
Y al igual que antes, no puede dar valores adicionales que no sean parámetros existentes:
En el uso del mundo real, las funciones pueden tener argumentos tanto posicionales como 
opcionales, y funciona de la misma manera:
Puedes llamar a la función con solo un iterable:
o con solo un diccionario:
o puedes usar ambos en la misma llamada:
    645/1068
    581
fun3(*[1,2], **{'arg2':42, 'arg3':3})
# Raises: TypeError: fun3() got multiple values for argument 'arg2'
def fun1(*args, **kwargs): 
print(args, kwargs)
fun1(1,2,3)
# Prints: (1, 2, 3) {}
fun1(a=1, b=2, c=3)
# Prints: () {'a': 1, 'b': 2, 'c': 3}
fun1('x', 'y', 'z', a=1, b=2, c=3)
# Prints: ('x', 'y', 'z') {'a': 1, 'b': 2, 'c': 3}
class MyString(str):
def init (self, *args, **kwarg): 
print('Constructing MyString') 
super(MyString,self). init (*args, **kwarg)
Tenga en cuenta que no puede proporcionar varios valores para el mismo argumento:
Desempaquetando argumentos de funciones
Cuando desee crear una función que pueda aceptar cualquier número de argumentos y no 
imponer la posición o el nombre del argumento en el momento de la "compilación", es posible y a 
continuación le indicamos cómo:
Los parámetros *args y **kwargs son parámetros especiales que se establecen en una tuple y un
dict , respectivamente:
Si observa suficiente código de Python, descubrirá rápidamente que se está utilizando 
ampliamente al pasar argumentos a otra función. Por ejemplo, si desea extender la clase de 
cadena:
    646/1068
    582
Capítulo 114: Listar comprensiones
Introducción
Las comprensiones de listas en Python son construcciones sintácticas concisas. Se pueden 
utilizar para generar listas de otras listas aplicando funciones a cada elemento de la lista. La 
siguiente sección explica y demuestra el uso de estas expresiones.
Sintaxis
• [x + 1 para x en (1, 2, 3)] # comprensión de lista, da [2, 3, 4]
• (x + 1 para x en (1, 2, 3)) # expresión del generador, producirá 2, luego 3, luego 4
• [x para x en (1, 2, 3) si x% 2 == 0] # enumerar comprensión con filtro, da [2]
• [x + 1 si x% 2 == 0 sino x para x en (1, 2, 3)] # lista comprensión con ternario
• [x + 1 si x% 2 == 0 sino x para x en el rango (-3,4) si x> 0] # lista comprensión con ternario y 
filtrado
• {x para x en (1, 2, 2, 3)} # establecer comprensión, da {1, 2, 3}
• {k: v para k, v en [('a', 1), ('b', 2)]} # dict comprensión, da {'a': 1, 'b': 2} (python 2.7+ y 3.0+ 
solamente)
• [x + y para x en [1, 2] para y en [10, 20]] # Bucles anidados, da [11, 21, 12, 22]
• [x + y para x en [1, 2, 3] si x> 2 para y en [3, 4, 5]] # Condición verificada al principio para 
bucle
• [x + y para x en [1, 2, 3] para y en [3, 4, 5] si x> 2] # Condición verificada en 2da para bucle
• [x para x en xrange (10) si x% 2 == 0] # Condición verificada si los números en bucle son 
números impares
Observaciones
Las comprensiones son construcciones sintácticas que definen estructuras de datos o 
expresiones exclusivas de un idioma en particular. El uso adecuado de las comprensiones las 
reinterpreta en expresiones fáciles de entender. Como expresiones, se pueden utilizar:
• en el lado derecho de las tareas
• como argumentos para llamadas de funcion
• en el cuerpo de una función lambda
• como declaraciones independientes. (Por ejemplo: [print(x) for x in range(10)] )
Examples
Lista de Comprensiones
Una lista de comprensión crea una nueva list al aplicar una expresión a cada elemento de un 
iterable . La forma más básica es:
    647/1068
    583
[ <expression> for <element> in <iterable> if <condition> ]
squares = [x * x for x in (1, 2, 3, 4)]
# squares: [1, 4, 9, 16]
squares = []
for x in (1, 2, 3, 4): 
squares.append(x * x)
# squares: [1, 4, 9, 16]
# Get a list of uppercase characters from a string 
[s.upper() for s in "Hello World"]
# ['H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D']
# Strip off any commas from the end of strings in a list
[w.strip(',') for w in ['these,', 'words,,', 'mostly', 'have,commas,']] 
# ['these', 'words', 'mostly', 'have,commas']
# Organize letters in words more reasonably - in an alphabetical order 
sentence = "Beautiful is better than ugly"
["".join(sorted(word, key=lambdax: x.lower()))for wordin sentence.split()] 
# ['aBefiltuu', 'is', 'beertt', 'ahnt', 'gluy']
También hay una condición opcional "si":
Cada <element> en el <iterable> se conecta a la <expression> si el <condition> (opcional) se evalúa
como verdadero . Todos los resultados se devuelven a la vez en la nueva lista. Las expresiones
de los generadores se evalúan perezosamente, pero las comprensiones de la lista evalúan todo el
iterador inmediatamente, consumiendo memoria proporcional a la longitud del iterador.
Para crear una list de enteros cuadrados:
Laexpresiónforestablecexacadavalorporturnode(1,2,3,4).Elresultadodelaexpresión 
x * x seanexaaunalistinterna. Lalistinternaseasignaalossquaresvariablescuandose 
completa.
Además de un aumento de velocidad (como se explica aquí ), una comprensión de la lista es 
aproximadamente equivalente al siguiente bucle for:
La expresión aplicada a cada elemento puede ser tan compleja como sea necesario:
más
else se puede utilizar en las construcciones de comprensión de listas, pero tenga cuidado con la 
sintaxis. Las cláusulas if / else deben usarse antes for bucle, no después:
[ <expression> for <element> in <iterable> ]
    648/1068
    584
def foo(i):
return i, i + 0.5
for i in range(3): 
for x in foo(i):
yield str(x)
[str(x)
for i in range(3) 
for x in foo(i)
]
Tenga en cuenta que esto utiliza una construcción de lenguaje diferente, una expresión
condicional , que en sí misma no es parte de la sintaxis de comprensión .Considerando que el if 
after the for…in es parte de la lista de comprensión y se utiliza para filtrar elementos de la fuente 
iterable.
Doble iteración
Elordendedoble iteración [... for x in ... for y in ...]esnaturalocontraintuitivo.Laregla 
de oro es seguir un equivalente for bucle:
Esto se convierte en:
Esto se puede comprimir en una línea como [str(x) for i in range(3) for x in foo(i)]
Mutación in situ y otros efectos secundarios
Antes de usar la comprensión de lista, comprenda la diferencia entre las funciones solicitadas por 
sus efectos secundarios (funciones mutantes o en el lugar ) que generalmente devuelven None y 
las funciones que devuelven un valor interesante.
Muchas funciones (especialmente funciones puras ) simplemente toman un objeto y devuelven 
algún objeto. Una función en el lugar modifica el objeto existente, que se denomina efecto 
secundario . Otros ejemplos incluyen operaciones de entrada y salida, como la impresión.
list.sort() ordena una lista en el lugar (lo que significa que modifica la lista original) y devuelve el
# create a list of characters in apple, replacing non vowels with '*' 
# Ex - 'apple' --> ['a', '*', '*', '*' ,'e']
[x for x in 'apple' if x in 'aeiou' else '*'] 
#SyntaxError: invalid syntax
#Whenusingif/else togetherusethembeforethe loop 
[x if x in 'aeiou' else '*' for x in 'apple']
#['a', '*', '*', '*', 'e']
    649/1068
    585
[x.sort() for x in [[2, 1], [4, 3], [0, 1]]] 
# [None, None,None]
[sorted(x) for x in [[2, 1], [4, 3], [0, 1]]]
# [[1, 2], [3, 4], [0, 1]]
[print(x) for x in (1, 2, 3)]
for x in (1, 2, 3): 
print(x)
from random import randrange 
[randrange(1, 7) for _ in range(10)] 
# [2, 3, 2, 1, 1, 5, 2, 4, 3, 5]
[
x for x 
in 'foo'
if x not in 'bar'
]
valor None . Por lo tanto, no funcionará como se espera en una lista de comprensión:
En su lugar, sorted() devuelve una list ordenada en lugar de ordenar in situ:
Es posible el uso de comprensiones para efectos secundarios, como I / O o funciones in situ. Sin 
embargo, un bucle for suele ser más legible. Mientras esto funciona en Python 3:
En su lugar, utilice:
En algunas situaciones, las funciones de efectos secundarios son adecuadas para la 
comprensión de listas. random.randrange() tiene el efecto secundario de cambiar el estado del 
generadordenúmerosaleatorios,perotambiéndevuelveunvalorinteresante.Además,se puede 
llamar a next() en un iterador.
El siguiente generador de valores aleatorios no es puro, pero tiene sentido ya que el generador 
aleatorio se restablece cada vez que se evalúa la expresión:
Los espacios en blanco en la lista de 
comprensión
Las comprensiones de listas más complicadas pueden alcanzar una longitud no deseada o 
volverse menos legibles. Aunque es menos común en los ejemplos, es posible dividir una lista de 
comprensión en varias líneas, como por ejemplo:
    650/1068
    586
{x: x * x for x in (1, 2, 3, 4)}
# Out: {1: 1, 2: 4, 3: 9, 4: 16}
dict((x, x * x) for x in (1, 2, 3, 4))
# Out: {1: 1, 2: 4, 3: 9, 4: 16}
{name:len(name)for name in ('Stack', 'Overflow', 'Exchange')if len(name)> 6} 
# Out: {'Exchange': 8, 'Overflow': 8}
dict((name, len(name)) for name in ('Stack', 'Overflow', 'Exchange') if len(name) > 6) 
# Out: {'Exchange': 8, 'Overflow': 8}
initial_dict = {'x': 1, 'y': 2}
{key: value for key, value in initial_dict.items() if key == 'x'} 
# Out: {'x': 1}
my_dict = {1: 'a', 2: 'b', 3: 'c'}
Diccionario de Comprensiones
Una comprensión de diccionario es similar a una comprensión de lista, excepto que produce un 
objeto de diccionario en lugar de una lista.
Un ejemplo básico:
Python 2.x 2.7
que es solo otra forma de escribir:
Al igual que con una lista de comprensión, podemos usar una declaración condicional dentro de la 
comprensión de dict para producir solo los elementos de dict que cumplan con algún criterio.
Python 2.x 2.7
O, reescrito usando una expresión generadora.
Comenzando con un diccionario y utilizando la comprensión del diccionario como un filtro 
de par clave-valor
Python 2.x 2.7
Tecla de conmutación y valor del diccionario (diccionario invertido)
Si tiene un dict que contiene valores hashables simples (los valores duplicados pueden tener 
resultados inesperados):
y quería intercambiar las claves y los valores, puede adoptar varios enfoques dependiendo de su
    651/1068
    587
{**dict1, **dict2}
# Out: {'w': 1, 'x': 2, 'y': 2, 'z': 2}
print(swapped)
# Out: {a: 1, b: 2, c: 3}
dict1 = {'w': 1, 'x': 1}
dict2 = {'x': 2, 'y': 2, 'z': 2}
{k: v for d in [dict1, dict2] for k, v in d.items()} 
# Out: {'w': 1, 'x': 2, 'y': 2, 'z': 2}
# list comprehension 
[x**2 for x in range(10)]
# Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
estilo de codificación:
• swapped = {v: k for k, v in my_dict.items()}
• swapped = dict((v, k) for k, v in my_dict.iteritems())
• swapped = dict(zip(my_dict.values(), my_dict))
• swapped = dict(zip(my_dict.values(), my_dict.keys()))
• swapped = dict(map(reversed, my_dict.items()))
Python 2.x 2.3
Si su diccionario es grande, considere la importación itertools y utilizar izip o imap .
Fusionando diccionarios
Combine diccionarios y, opcionalmente, anule valores antiguos con una comprensión de 
diccionario anidado.
Sin embargo, el desempaque del diccionario ( PEP 448 ) puede ser el preferido. 
Python 3.x 3.5
Nota : las comprensiones de diccionarios se agregaron en Python 3.0 y se respaldaron a 2.7+, a 
diferencia de las comprensiones de listas, que se agregaron en 2.0. Las versiones <2.7 pueden 
usar expresiones generadoras y el dict() incorporado para simular el comportamiento de las 
comprensiones de diccionario.
Expresiones del generador
Las expresiones generadoras son muy similares a las listas de comprensión. La principal 
diferencia es que no crea un conjunto completo de resultados a la vez; crea un objeto generador
que luego puede ser iterado.
Por ejemplo, vea la diferencia en el siguiente código:
Python 2.x 2.4
    652/1068
    588
for i in [x**2 for x in range(10)]: 
print(i)
"""
g = (x**2 for x in xrange(10)) 
print(g[0])
Traceback (most recent call last): 
File "<stdin>", line 1, in<module>
TypeError: 'generator' object has no attribute ' getitem '
Traceback (most recent call last): 
File "<stdin>", line 1, in<module>
StopIteration
Estos son dos objetos muy diferentes:
• lalistadecomprensióndevuelveunobjetodelistmientrasquelacomprensióndel 
generador devuelve un generator .
• generator objetos generator no se pueden indexar y hace uso de la next función para ordenar 
los artículos.
Nota : Utilizamos xrange ya que también crea un objeto generador. Si usaríamos el rango, se 
crearía una lista. Además, xrange solo existe en la versión posterior de python 2. En python 3, 
range solo devuelve un generador. Para obtener más información, consulte el ejemplo de
Diferencias entre las funciones de rango y rango .
Python 2.x 2.4
g.next() # 0
g.next() # 1
g.next() # 4
...
g.next() # 81
g.next() # Throws StopIteration Exception
Python 3.x 3.0
NOTA: La función g.next() debe sustituirse por next(g) y xrange con range ya que
Iterator.next() y xrange() no existen en Python 3. 
Aunqueambospuedenseriteradosdemanerasimilar:
# generator comprehension 
(x**2 for x in xrange(10))
# Output: <generator object <genexpr> at 0x11b4b7c80>
    653/1068
    589
for i in (x**2 for x in xrange(10)): 
print(i)
"""
Out:
0
1
4
.
.
. 
81 
"""
for square in (x**2 for x in range(1000000)): 
#do something
def get_objects():
"""Gets objects from an API one by one""" 
while True:
yield get_next_item()
def object_matches_pattern(obj):
# perform potentially complex calculation 
return matches_pattern
def right_item_exists():
items = (object_matched_pattern(each) for each in get_objects()) 
for item in items:
if item.is_the_right_one:
Python 2.x 2.4
Casos de uso
Las expresiones del generador se evalúan perezosamente, lo que significa que generan y 
devuelven cada valor solo cuando el generador está iterado. Esto suele ser útil cuando se itera a 
través de grandes conjuntos de datos, evitando la necesidad de crear un duplicado del conjunto 
de datos en la memoria:
Otro caso de uso común es evitar la iteración en todo un iterable si no es necesario hacerlo. En 
este ejemplo, un elemento se recupera de una API remota con cada iteración de get_objects() . 
Pueden existir miles de objetos, deben recuperarse uno por uno, y solo necesitamos saber si 
existe un objeto que coincida con un patrón. Al usar una expresión generadora, cuando 
encontramos un objeto que coincide con el patrón.
Out:
0
1
4
... 
81 
"""
    654/1068
    590
# A set containing every value in range(5):
{x for x in range(5)} 
# Out: {0, 1, 2, 3, 4}
# A set of even numbers between 1 and 10:
{x for x in range(1, 11) if x % 2 == 0} 
# Out: {2, 4, 6, 8, 10}
# Unique alphabetic characters in a string of text:
text = "When in the Course of human events it becomes necessary for one people..."
{ch.lower() for ch in text if ch.isalpha()}
# Out: set(['a', 'c', 'b', 'e', 'f', 'i', 'h', 'm', 'l', 'o',
# 'n', 'p', 's', 'r', 'u', 't', 'w', 'v', 'y'])
set(x for x in range(5)) 
# Out: {0, 1, 2, 3, 4}
>>> [f(x)for x in range(1000) if f(x) > 10] 
[16, 25, 36, ...]
# Simulate expensive function
import time 
time.sleep(.1)
return x**2
...
...
...
>>> def f(x):
Establecer Comprensiones
La comprensión del conjunto es similar a la lista y la comprensión del diccionario , pero produce 
un conjunto , que es una colección desordenada de elementos únicos.
Python 2.x 2.7
Demo en vivo
Tenga en cuenta que los conjuntos están desordenados. Esto significa que el orden de los 
resultados en el conjunto puede diferir del presentado en los ejemplos anteriores.
Nota : la comprensión de configuración está disponible desde python 2.7+, a diferencia de las 
comprensiones de lista, que se agregaron en 2.0. En Python 2.2 a Python 2.6, la función set() se 
puede usar con una expresión generadora para producir el mismo resultado:
Python 2.x 2.2
Evite operaciones repetitivas y costosas usando cláusula condicional
Considere la siguiente lista de comprensión:
Esto da como resultado dos llamadas a f(x) para 1,000 valores de x : una llamada para generar
return True 
return False
    655/1068
    591
>>> [v for v in (f(x) for x in range(1000)) if v > 10] 
[16, 25, 36, ...]
>>> [v for v in map(f, range(1000)) if v > 10] 
[16, 25, 36, ...]
>>> [v for x in range(1000) for v in [f(x)] if v > 10] 
[16, 25, 36, ...]
>>> def process_prime_numbers(iterable):
... for x in iterable:
... if is_prime(x):
... yield f(x)
...
>>> [x for x in process_prime_numbers(range(1000)) ifx > 10] 
[11, 13, 17, 19, ...]
l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
elvalorylaotraparaverificarlacondiciónif.Sif(x)esunaoperaciónparticularmentecostosa, 
estopuedetenerimplicacionessignificativasenelrendimiento.Peoraún,sillamaraf()tiene 
efectos secundarios, puede tener resultados sorprendentes.
En su lugar, debe evaluar la operación costosa solo una vez para cada valor de x generando un 
iterable intermedio ( expresión del generador ) de la siguiente manera:
O, usando el mapa incorporado equivalente:
Otra forma que podría resultar en un código más legible es colocar el resultado parcial ( v en el 
ejemplo anterior) en un iterable (como una lista o una tupla) y luego iterar sobre él. Como v será el 
único elemento en el iterable, el resultado es que ahora tenemos una referencia a la salida de 
nuestra función lenta calculada solo una vez:
Sin embargo, en la práctica, la lógica del código puede ser más complicada y es importante 
mantenerlo legible. En general, se recomienda una función de generador por separado en un 
complejo de una sola línea:
Otramaneradeevitar el cálculodef(x) variasveces es utilizar el @functools.lru_cache() (Python 
3.2+)decoradorenf(x).Deestamanera, dadoquelasalidadefparalaentradax yaseha 
calculadouna vez, lainvocación dela segunda función de la comprensión dela lista original será 
tanrápidacomolabúsquedadeundiccionario.Esteenfoqueutilizalamemoriaparamejorarla 
eficiencia, que es comparable al uso de expresiones generadoras.
Di que tienes que aplanar una lista
Algunos de los métodos podrían ser:
    656/1068
    592
[item for sublist in l for item in sublist]
[x + y for x, y in [(1, 2), (3, 4), (5, 6)]]
# Out: [3, 7, 11]
[x + y for x, y in zip([1, 3, 5], [2, 4, 6])]
# Out: [3, 7, 11]
for x, y in [(1,2), (3,4), (5,6)]:
print(x+y)
# 3
# 7
# 11
[x, y for x, y in [(1, 2), (3, 4), (5, 6)]]
# SyntaxError: invalid syntax
[(x, y) for x, y in [(1, 2), (3, 4), (5, 6)]]
# Out: [(1, 2), (3, 4), (5, 6)]
Sin embargo, la comprensión de la lista proporcionaría la mejor complejidad de tiempo.
Los accesos directos basados en + (incluido el uso implícito en la suma) son, por necesidad, O (L
^ 2) cuando hay L sublistas: a medida que la lista de resultados intermedios se hace más larga, 
en cada paso se obtiene un nuevo objeto de lista de resultados intermedios. asignados, y todos 
los elementos en el resultado intermedio anterior deben copiarse (así como algunos nuevos 
agregados al final). Entonces (por simplicidad y sin pérdida de generalidad real) digamos que 
tiene L sublistas de I elementos cada uno: los primeros elementos I se copian una y otra vez L-1 
veces, el segundo I elementos L-2 veces, y así sucesivamente; el número total de copias es I 
veces la suma de x para x de 1 a L excluidas, es decir, I * (L ** 2) / 2.
La lista de comprensión solo genera una lista, una vez, y copia cada elemento (de su lugar de 
residencia original a la lista de resultados) también una sola vez.
Comprensiones que involucran tuplas
La cláusula for de una lista de comprensión puede especificar más de una variable:
Esto es como regular for bucles:
Sin embargo, tenga en cuenta que si la expresión que comienza la comprensión es una tupla, 
debe estar entre paréntesis:
Contando Ocurrencias Usando Comprensión
reduce(lambda x, y: x+y, l) 
sum(l, [])
list(itertools.chain(*l))
    657/1068
    593
# Count the numbers in `range(1000)` that are even and contain the digit `9`: 
print (sum(
1 for x in range(1000) 
if x % 2 == 0 and
'9' in str(x)
))
# Out: 95
# Convert a list of strings to integers. 
items = ["1","2","3","4"]
[int(item) for item in items] 
# Out: [1, 2, 3, 4]
# Convert a list of strings to float. 
items = ["1","2","3","4"]
map(float, items)
# Out:[1.0, 2.0, 3.0, 4.0]
Cuando queremos contar el número de elementos en un iterable, que cumplan con alguna 
condición, podemos usar la comprensión para producir una sintaxis idiomática:
El concepto básico se puede resumir como:
1. Iterar sobre los elementos en range(1000) .
2. Concatenar todo lo necesario if condiciones.
3. Utilice 1 como expresión para devolver un 1 por cada elemento que cumpla con las 
condiciones.
4. Resuma todos los 1 s para determinar la cantidad de elementos que cumplen con las 
condiciones.
Nota : Aquí no estamos recolectando los 1 s en una lista (note la ausencia de corchetes), pero 
pasamos los directamente a la función de sum que los está sumando. Esto se denomina expresión 
generadora , que es similar a una comprensión.
Cambio de tipos en una lista
Los datos cuantitativos a menudo se leen como cadenas que deben convertirse en tipos 
numéricos antesde procesarlos.Los tiposde todos loselementos delalistasepueden convertir 
con una Comprensión de lista o la función map() .
    658/1068
    594
class Node:
def init (self, val): 
self.data = val 
self.next = None
def getData(self): 
return self.data
def getNext(self): 
return self.next
def setData(self, val): 
self.data = val
def setNext(self, val): 
self.next = val
class LinkedList: 
def init (self):
self.head= None
def isEmpty(self):
"""Check if the list is empty""" 
return self.head is None
def add(self, item):
"""Add the item to the list""" 
new_node = Node(item) 
new_node.setNext(self.head) 
self.head = new_node
def size(self):
"""Return the length/size of the list""" 
count = 0
current = self.head
while current is not None: 
count += 1
Capítulo 115: Listas enlazadas
Introducción
Una lista enlazada es una colección de nodos, cada uno compuesto por una referencia y un valor. 
Los nodos se unen en una secuencia utilizando sus referencias. Las listas vinculadas se pueden 
utilizar para implementar estructuras de datos más complejas como listas, pilas, colas y matrices 
asociativas.
Examples
Ejemplo de lista enlazada única
Este ejemplo implementa una lista enlazada con muchos de los mismos métodos que el objeto de 
lista integrado.
    659/1068
    595
current = current.getNext() 
return count
def search(self,item):
"""Search foritemin list.Iffound,returnTrue.If notfound,returnFalse""" 
current = self.head
found = False
while current is not None and not found: 
if current.getData() is item:
found = True 
else:
current = current.getNext() 
return found
def remove(self, item):
"""Remove item from list. If item is not found in list, raise ValueError""" 
current = self.head
previous = None 
found = False
while current is not None and not found: 
if current.getData() is item:
found = True 
else:
previous = current
current = current.getNext() 
if found:
if previous is None:
self.head = current.getNext() 
else:
previous.setNext(current.getNext())
else:
raise ValueError
print 'Value not found.'
def insert(self, position, item): 
"""
Insert item at position specified. If position specified is 
out of bounds, raise IndexError
"""
if position > self.size() - 1: 
raise IndexError
print "Index out of bounds." 
current = self.head
previous = None 
pos = 0
if position is 0: 
self.add(item)
else:
new_node = Node(item) 
while pos < position:
pos += 1
previous = current
current = current.getNext() 
previous.setNext(new_node) 
new_node.setNext(current)
def index(self, item): 
"""
Return the index where item isfound. 
If item is not found, return None. 
"""
    660/1068
    596
current = self.head 
pos = 0
found = False
while current is not None and not found: 
if current.getData() is item:
found = True 
else:
current = current.getNext() 
pos += 1
if found:
pass 
else:
pos = None 
return pos
def pop(self, position = None): 
"""
If no argument is provided, return and remove the item at the head. 
If position is provided, return and remove the item at that position.
If index is out of bounds, raise IndexError 
"""
if position > self.size(): 
print 'Index out of bounds' 
raise IndexError
current = self.head 
if position is None:
ret = current.getData() 
self.head = current.getNext()
else:
pos = 0
previous = None
while pos < position: 
previous = current
current = current.getNext() 
pos += 1
ret = current.getData() 
previous.setNext(current.getNext())
print ret 
return ret
def append(self, item):
"""Append item to the end of the list""" 
current = self.head
previous = None 
pos = 0
length = self.size() 
while pos < length:
previous = current
current = current.getNext() 
pos += 1
new_node = Node(item) 
if previous is None:
new_node.setNext(current) 
self.head = new_node
else:
previous.setNext(new_node)
def printList(self): 
"""Print the list""" 
current = self.head
    661/1068
    597
ll=LinkedList() 
ll.add('l')
ll.add('H')
ll.insert(1,'e')
ll.append('l')
ll.append('o') 
ll.printList()
H
e 
l 
l 
o
El uso funciona muy parecido al de la lista incorporada.
while current is not None: 
print current.getData() 
current = current.getNext()
    662/1068
    598
BsonDocument argsBson = BsonDocument.Parse("{ 'x' : '1', 'y' : '2' }");
string argsFile = string.Format("{0}\\{1}.txt", Path.GetDirectoryName(pyScriptPath), 
Guid.NewGuid());
filename = sys.argv[ 1 ]
with open( filename ) as data_file: 
input_args = json.loads( data_file.read() )
x, y = [ float(input_args.get( key )) for key in [ 'x', 'y' ] ]
print json.dumps( { 'sum' : x + y , 'subtract' : x - y } )
Capítulo 116: Llama a Python desde C #
Introducción
La documentación proporciona una implementación de muestra de la comunicación entre 
procesos entre C # y los scripts de Python.
Observaciones
Tenga en cuenta que en el ejemplo anterior, los datos se serializan utilizando la biblioteca
MongoDB.Bson que se puede instalar a través del administrador NuGet.
De lo contrario, puede utilizar cualquier biblioteca de serialización JSON de su elección.
A continuación se presentan los pasos de implementación de la comunicación entre procesos:
• Los argumentos de entrada se serializan en una cadena JSON y se guardan en un archivo 
de texto temporal:
• Python interpreter python.exe ejecuta la secuencia de comandos de python que lee la 
cadena JSON desde un archivo de texto temporal y los argumentos de entrada de 
retroceso:
• El script de Python se ejecuta y el diccionario de salida se serializa en una cadena JSON y 
se imprime en la ventana de comandos:
• Lea la cadena JSON de salida de la aplicación C #:
    663/1068
    599
import sys 
import json
# load input arguments from the text file 
filename = sys.argv[ 1 ]
with open( filename ) as data_file: 
input_args = json.loads( data_file.read())
# cast strings to floats
Estoy utilizando la comunicación entre procesos entre C # y los scripts de Python en uno de mis 
proyectos que permite llamar a los scripts de Python directamente desde hojas de cálculo de 
Excel.
El proyecto utiliza el complemento ExcelDNA para C # - enlace Excel. 
El código fuente se almacena en el repositorio de GitHub.
A continuación se encuentran enlaces a páginas wiki que brindan una descripción general del 
proyecto y ayudan a comenzar en 4 sencillos pasos .
• Empezando
• Descripción general de la implementación
• Ejemplos
• Asistente de objetos
• Funciones
Espero que encuentre útil el ejemplo y el proyecto.
Examples
Script de Python para ser llamado por la aplicación C #
using (StreamReader myStreamReader = process.StandardOutput)
{
outputString = myStreamReader.ReadLine(); 
process.WaitForExit();
}
    664/1068
    600
Código C # llamando al script Python
using MongoDB.Bson; 
using System;
using System.Diagnostics; 
using System.IO;
namespace python_csharp
{
class Program
{
static void Main(string[] args)
{
// full path to .py file
string pyScriptPath = "......../sum.py";
// convert input arguments to JSON string
BsonDocument argsBson=BsonDocument.Parse("{ 'x' : '1', 'y' :'2' }"); 
bool saveInputFile = false;
string argsFile = string.Format("{0}\\{1}.txt", 
Path.GetDirectoryName(pyScriptPath), Guid.NewGuid());
string outputString = null;
// create new process start info
ProcessStartInfo prcStartInfo = new ProcessStartInfo
{
};
try
{
// full path of the Python interpreter 'python.exe'
FileName="python.exe",//string.Format(@"""{0}""","python.exe"), 
UseShellExecute = false,
RedirectStandardOutput = true, 
CreateNoWindow = false
// write input arguments to .txt file
using (StreamWriter sw = new StreamWriter(argsFile))
{
sw.WriteLine(argsBson);
prcStartInfo.Arguments = string.Format("{0} {1}", 
string.Format(@"""{0}""", pyScriptPath), string.Format(@"""{0}""", argsFile));
}
// start process
using (Process process = Process.Start(prcStartInfo))
{
// read standard output JSON string
using (StreamReader myStreamReader = process.StandardOutput)
{
outputString = myStreamReader.ReadLine(); 
process.WaitForExit();
}
}
}
finally
x, y = [ float(input_args.get( key )) for key in [ 'x', 'y' ] ]
print json.dumps( { 'sum' : x + y , 'subtract' : x - y } )
    665/1068
    601
{
//delete/save temporary.txtfile 
if (!saveInputFile)
{
File.Delete(argsFile);
}
}
Console.WriteLine(outputString);
}
}
}
    666/1068
    602
finally:
# --- Cleanup on exit ---
stdscr.keypad(0) 
curses.echo() 
curses.nocbreak()
curses.endwin()
# print trace back log of the error
except:
traceback.print_exc()
import curses 
import traceback
try:
# -- Initialize --
stdscr = curses.initscr() # initialize curses screen
curses.noecho() # turn off auto echoing of keypress on to screen 
curses.cbreak() # enter break mode where pressing Enter key
# after keystroke is not required for it to register 
stdscr.keypad(1) # enable special Key values such as curses.KEY_LEFT etc
# -- Perform an action with Screen --
stdscr.border(0)
stdscr.addstr(5, 5, 'Hello from Curses!', curses.A_BOLD) 
stdscr.addstr(6, 5, 'Press q to close this screen', curses.A_NORMAL)
while True:
# stay in this loop till the user presses 'q' 
ch = stdscr.getch()
if ch == ord('q'): 
break
# -- End of user code --
Capítulo 117: Maldiciones básicas con pitón
Observaciones
Curses es un módulo básico de manejo de terminal (o visualización de caracteres) de Python. 
Esto se puede utilizar para crear interfaces de usuario basadas en terminal o TUI.
Este es un puerto python de una biblioteca C más popular 'ncurses'
Examples
Ejemplo básico de invocación
La función de ayuda wrapper ().
Si bien la invocación básica anterior es bastante fácil, el paquete curses proporciona la 
wrapper(func, ...)ayudade wrapper(func, ...).Elsiguienteejemplocontieneelequivalentede 
arriba:
    667/1068
    603
Aquí, la envoltura inicializará las cursas, creará stdscr , un objeto WindowObject y pasará ambos 
stdscr, y cualquier argumento adicional a func . Cuando la func vuelve, la wrapper restaurará el 
terminal antes de que el programasalga.
main(scr, *args):
# -- Perform an action with Screen --
scr.border(0)
scr.addstr(5, 5, 'Hello from Curses!', curses.A_BOLD) 
scr.addstr(6, 5, 'Press q to close this screen', curses.A_NORMAL)
while True:
# stay in this loop till the user presses 'q' 
ch = scr.getch()
if ch == ord('q'):
curses.wrapper(main)
    668/1068
    604
import xml.etree.ElementTree as ET 
tree = ET.parse("yourXMLfile.xml") 
root = tree.getroot()
for child in root: 
print(child.tag, child.attrib)
print(root[0][1].text)
print(root.findall("myTag")) 
print(root[0].find("myOtherTag"))
import xml.etree.ElementTree as ET 
tree = ET.parse('sample.xml') 
root=tree.getroot()
element = root[0] #get first child of root element
Capítulo 118: Manipulando XML
Observaciones
No todos los elementos de la entrada XML terminarán como elementos del árbol analizado. 
Actualmente, este módulo omite los comentarios XML, las instrucciones de procesamiento y las 
declaraciones de tipo de documento en la entrada. Sin embargo, los árboles construidos 
utilizando la API de este módulo en lugar de analizar a partir de texto XML pueden tener 
comentarios e instrucciones de procesamiento; Se incluirán al generar la salida XML.
Examples
Abriendo y leyendo usando un ElementTree
Importe el objeto ElementTree, abra el archivo .xml relevante y obtenga la etiqueta raíz:
Hay algunas maneras de buscar a través del árbol. Primero es por iteración:
De lo contrario, puede hacer referencia a ubicaciones específicas como una lista:
Para buscar etiquetas específicas por nombre, use .find o .findall :
Modificar un archivo XML
Importar módulo de árbol de elementos y abrir archivo xml, obtener un elemento xml
El objeto elemento se puede manipular cambiando sus campos, agregando y modificando 
atributos, agregando y eliminando elementos secundarios
    669/1068
    605
root.remove(element)
tree.write('output.xml')
import xml.etree.ElementTree as ET
p=ET.Element('parent')
c = ET.SubElement(p, 'child1')
ET.dump(p)
# Output will be like this 
#<parent><child1 /></parent>
tree = ET.ElementTree(p) 
tree.write("output.xml")
comment = ET.Comment('user comment')
p.append(comment) #this comment will be appended to parent element
Si desea eliminar un elemento use el método Element.remove ()
Método ElementTree.write () utilizado para generar un objeto xml en archivos xml.
Crear y construir documentos XML
Módulo de árbol de elementos de importación
La función Element () se utiliza para crear elementos XML
Función de elemento secundario () utilizada para crear subelementos a un elemento dado
La función dump () se utiliza para volcar elementos xml.
Si desea guardar en un archivo, cree un árbol xml con la función ElementTree () y guarde en un 
archivo con el método write ()
La función Comentario () se utiliza para insertar comentarios en un archivo xml.
Abrir y leer archivos XML grandes utilizando iterparse (análisisincremental)
A veces no queremos cargar el archivo XML completo para obtener la información que 
necesitamos. En estos casos, es útil poder cargar incrementalmente las secciones relevantes y 
luego eliminarlas cuando hayamos terminado. Con la función iterparse puede editar el árbol de
element.set('attribute_name', 'attribute_value') #set the attribute to xml element 
element.text="string_text"
    670/1068
    606
for event, elem in ET.iterparse("yourXMLfile.xml"):
... do something ...
events=("start", "end", "start-ns", "end-ns")
for event, elem in ET.iterparse("yourXMLfile.xml", events=events):
... do something ...
for event, elem in ET.iterparse("yourXMLfile.xml", events=("start","end")): 
if elem.tag == "record_tag" and event == "end":
print elem.text 
elem.clear()
... do something else ...
<Catalog>
<Books>
<Book id="1" price="7.95">
<Title>Do Androids Dream of Electric Sheep?</Title>
<Author>Philip K. Dick</Author>
</Book>
<Book id="5" price="5.95">
<Title>The Colour of Magic</Title>
<Author>Terry Pratchett</Author>
</Book>
<Book id="7" price="6.95">
<Title>The Eye of The World</Title>
<Author>Robert Jordan</Author>
</Book>
</Books>
</Catalog>
elementos que se almacena mientras se analiza el XML. 
Importe el objeto ElementTree:
Abra el archivo .xml e itere sobre todos los elementos:
Alternativamente, solo podemos buscar eventos específicos, como etiquetas de inicio / 
finalización o espacios de nombres. Si esta opción se omite (como anteriormente), solo se 
devuelven eventos "finales":
Aquí está el ejemplo completo que muestra cómo borrar elementos del árbol en memoria cuando 
terminemos con ellos:
Buscando el XML con XPath
A partir de la versión 2.7, ElementTree tiene un mejor soporte para consultas XPath. XPath es una 
sintaxis que le permite navegar a través de un xml como SQL se utiliza para buscar a través de 
una base de datos. Tanto las funciones find y findall son compatibles con XPath. El siguiente 
XML se utilizará para este ejemplo.
import xml.etree.ElementTree as ET
    671/1068
    607
import xml.etree.cElementTree as ET 
tree = ET.parse('sample.xml') 
tree.findall('Books/Book')
tree.find("Books/Book[Title='The Colour of Magic']") 
# always use '' in the right side of the comparison
tree.find("Books/Book[@id='5']")
# searches with xml attributes must have '@' before the name
tree.find("Books/Book[2]") 
# indexes starts at 1, not 0
tree.find("Books/Book[last()]")
# 'last' is the only xpath function allowed in ElementTree
tree.findall(".//Author")
#searches with // must use a relative path
Buscando todos los libros:
Buscando el libro con el título = 'El color de la magia':
Buscando el libro con id = 5:
Busca el segundo libro:
Buscar el último libro:
Búsqueda de todos los autores:
    672/1068
    608
import cmath
z = 2+3j # A complex number 
cmath.phase(z) # 0.982793723247329
cmath.polar(z) # (3.605551275463989, 0.982793723247329)
cmath.rect(2, cmath.pi/2) # (0+2j)
cmath.exp(z) # (-7.315110094901103+1.0427436562359045j) 
cmath.log(z) # (1.2824746787307684+0.982793723247329j) 
cmath.log10(-100) # (2+1.3643763538418412j)
cmath.sqrt(z) # (1.6741492280355401+0.8959774761298381j)
cmath.sin(z) # (9.15449914691143-4.168906959966565j) 
cmath.cos(z) # (-4.189625690968807-9.109227893755337j) 
cmath.tan(z) # (-0.003764025641504249+1.00323862735361j) 
cmath.asin(z) # (0.5706527843210994+1.9833870299165355j) 
cmath.acos(z) # (1.0001435424737972-1.9833870299165355j) 
cmath.atan(z) # (1.4099210495965755+0.22907268296853878j)
cmath.sin(z)**2 + cmath.cos(z)**2 # (1+0j)
Capítulo 119: Matemáticas complejas
Sintaxis
• cmath.rect (AbsoluteValue, Phase)
Examples
Aritmética compleja avanzada
El módulo cmath incluye funciones adicionales para usar números complejos.
Este módulo puede calcular la fase de un número complejo, en radianes:
Permite la conversión entre las representaciones cartesianas (rectangulares) y polares de 
números complejos:
El módulo contiene la versión compleja de
• Funciones exponenciales y logarítmicas (como es habitual, log es el logaritmo natural y
log10 el logaritmo decimal):
• Raíces cuadradas:
• Funciones trigonométricas y sus inversos:
    673/1068
    609
cmath.sinh(z) # (-3.59056458998578+0.5309210862485197j) 
cmath.cosh(z) # (-3.7245455049153224+0.5118225699873846j) 
cmath.tanh(z) # (0.965385879022133-0.009884375038322495j) 
cmath.asinh(z) # (0.5706527843210994+1.9833870299165355j) 
cmath.acosh(z) # (1.9833870299165355+1.0001435424737972j) 
cmath.atanh(z) # (0.14694666622552977+1.3389725222944935j)
cmath.cosh(z)**2 - cmath.sin(z)**2 # (1+0j) 
cmath.cosh((0+1j)*z) - cmath.cos(z) # 0j
z = 2+3j # A complex number
w = 1-7j # Another complex number
z + w # (3-4j) 
z - w # (1+10j)
z * w # (23-11j)
z / w # (-0.38+0.34j)
z**3 # (-46+9j)
z.real # 2.0
z.imag # 3.0
abs(z) # 3.605551275463989
z.conjugate() # (2-3j)
• Funciones hiperbólicas y sus inversos:
Aritmética compleja básica
Python ha incorporado soporte para aritmética compleja. La unidad imaginaria se denota por j :
Los números complejos pueden sumarse, restarse, multiplicarse, dividirse y exponerse:
Python también puede extraer las partes reales e imaginarias de números complejos, y calcular 
su valor absoluto y su conjugado:
    674/1068
    610
# Imports the Flask class 
from flask import Flask
# Creates an app and checks if its the main or imported 
app = Flask( name )
# Specifies what URL triggers hello_world() 
@app.route('/')
# The function run on the index route 
def hello_world():
# Returns the text to be displayed 
return "Hello World!"
# If this script isn't an import 
if name == " main ":
# Run the app until stopped 
app.run()
Capítulo 120: Matraz
Introducción
Flask es un marco micro web de Python que se utiliza para ejecutar los principales sitios web, 
incluidos Pintrest, Twilio y Linkedin. Este tema explica y demuestra la variedad de características 
que Flask ofrece para el desarrollo web tanto en la parte frontal como en la posterior.
Sintaxis
• @ app.route ("/ urlpath", métodos = ["GET", "POST", "DELETE", "PUTS", "HEAD", 
"OPTIONS"])
• @ app.route ("/ urlpath / <param>", methods = ["GET", "POST", "DELETE", "PUTS", 
"HEAD", "OPTIONS"])
Examples
Los basicos
El siguiente ejemplo es un ejemplo de un servidor básico:
La ejecución de este script (con todas las dependencias correctas instaladas) debe iniciar un 
servidor local. El host es 127.0.0.1 comúnmente conocido como localhost . Este servidor se 
ejecuta por defecto en el puerto 5000 .Para acceder a suservidor web, abra un navegador web e 
ingrese la URL localhost:5000 o 127.0.0.1:5000 (no hay diferencia). Actualmente, solo su 
computadora puede acceder al servidor web.
app.run() tiene tres parámetros, host , puerto y depuración . El host es 127.0.0.1 forma 
predeterminada, pero si lo establece en 0.0.0.0 podrá acceder a su servidor web desde cualquier 
dispositivo de su red usando su dirección IP privada en la URL. el puerto es por defecto 5000, 
pero si el parámetro se establece en el puerto 80 , los usuarios no necesitarán especificar un
    675/1068
    611
if name == " main ": app.run(host="0.0.0.0", 
port=80, debug=True)
@app.route("/") 
def index():
return "You went to www.example.com"
@app.route("/about") 
def about():
return "You went to www.example.com/about"
@app.route("/users/guido-van-rossum")
return "You went to www.example.com/guido-van-rossum"
@app.route("/users/<username>") 
def profile(username):
return "Welcome to the profile of " + username
cities = ["OMAHA", "MELBOURNE", "NEPAL", "STUTTGART", "LIMA", "CAIRO", "SHANGHAI"]
@app.route("/stores/locations/<city>") 
def storefronts(city):
if city in cities:
return "Yes! We are located in " + city 
else:
return "No. We are not located in " + city
número de puerto ya que los navegadores usan el puerto 80 de manera predeterminada. En 
cuanto a la opción de depuración, durante el proceso de desarrollo (nunca en producción), ayuda 
a establecer este parámetro en Verdadero, ya que su servidor se reiniciará cuando se realicen 
cambios en su proyecto de Flask.
URL de enrutamiento
Con Flask, el enrutamiento de URL se realiza tradicionalmente con decoradores. Estos 
decoradores se pueden usar para enrutamiento estático, así como enrutamiento de URL con 
parámetros. Para el siguiente ejemplo, imagine que este script de Flask está ejecutando el sitio 
web www.example.com .
Con esa última ruta, puede ver que dada una URL con / users / y el nombre del perfil, podríamos 
devolver un perfil. Como sería horriblemente ineficiente y desordenado incluir una @app.route() 
para cada usuario, Flask ofrece tomar parámetros de la URL:
Métodos HTTP
Los dos métodos HTTP más comunes son GET y POST . Flask puede ejecutar un código 
diferente de la misma URL dependiendo del método HTTP utilizado. Por ejemplo, en un servicio 
web con cuentas, es más conveniente enrutar la página de inicio de sesión y el proceso de inicio 
de sesión a través de la misma URL. Una solicitud GET, la misma que se realiza al abrir una URL 
en su navegador, debe mostrar el formulario de inicio de sesión, mientras que una solicitud POST 
(que lleva datos de inicio de sesión) debe procesarse por separado. También se crea una ruta
    676/1068
    612
@app.route("/login", methods=["GET"]) 
def login_form():
return "This is the login form" 
@app.route("/login", methods=["POST"]) 
def login_auth():
return "Processing your data" 
@app.route("/login", methods=["DELETE", "PUT"]) 
def deny():
return "This method is not allowed"
from flask import request
@app.route("/login", methods=["GET", "POST", "DELETE", "PUT"]) 
def login():
if request.method == "DELETE" or request.method == "PUT": 
return "This method is not allowed"
elif request.method == "GET": 
return "This is the login forum"
elif request.method == "POST": 
return "Processing your data"
from flask import request
@app.route("/login", methods=["GET", "POST", "DELETE", "PUT"]) 
def login():
if request.method == "DELETE" or request.method == "PUT": 
return "This method is not allowed"
elif request.method == "GET": 
return "This is the login forum"
elif request.method == "POST":
return "Username was " + request.form["username"] + " and password was " + 
request.form["password"]
from flask import Flask
from flask import render_template 
app = Flask( name )
@app.route("/about") 
def about():
return render_template("about-us.html")
if name == " main ": app.run(host="0.0.0.0", 
port=80, debug=True)
para manejar el método DELETE y PUT HTTP.
Para simplificar un poco el código, podemos importar el paquete de request desde el matraz.
Para recuperar datos de la solicitud POST, debemos usar el paquete de request :
Archivos y plantillas
EnlugardeescribirnuestromarcadoHTMLenlasdeclaracionesdedevolución,podemos usarla 
función render_template() :
Esto utilizará nuestro archivo de plantilla about-us.html . Para garantizar que nuestra aplicación
    677/1068
    613
- application.py
/templates
- about-us.html
- login-form.html
/static
/styles
- about-style.css
- login-style.css
/scripts
- about-script.js
- login-script.js
@app.route("/users/<username>) 
def profile(username):
joinedDate = get_joined_date(username) # This function's code is irrelevant 
awards = get_awards(username) # This function's code is irrelevant
# The joinDate is a string and awards is an array of strings
return render_template("profile.html", username=username, joinDate=joinDate, 
awards=awards)
<!DOCTYPE html>
<html>
<head>
# if username
<title>Profile of {{ username }}</title> 
# else
<title>No User Found</title> 
# endif
<head>
<body>
pueda encontrar este archivo, debemos organizar nuestro directorio en el siguiente formato:
Lo más importante, las referencias a estos archivos en el HTML deben tener este aspecto:
<link rel="stylesheet" type="text/css", href="{{url_for('static', filename='styles/aboutstyle.css')}}">
que dirigirá la aplicación para buscar about-style.css en la carpeta de estilos debajo de la carpeta 
estática. El mismo formato de ruta se aplica a todas las referencias a imágenes, estilos, scripts o 
archivos.
Jinja Templando
Al igual que Meteor.js, Flask se integra bien con los servicios de plantillas front-end. Frasco utiliza 
por defecto la plantilla de jinja. Las plantillas permiten que se utilicen pequeños fragmentos de 
código en el archivo HTML, como condicionales o bucles.
Cuando representamos una plantilla, todos los parámetros más allá del nombre del archivo de la 
plantilla se pasan al servicio de plantillas HTML. La siguiente ruta pasará el nombre de usuario y 
la fecha de ingreso (desde una función en otro lugar) al HTML.
Cuando esta plantilla se representa, puede usar las variables que se le pasan desde la función
render_template() . Aquí están los contenidos deprofile.html :
    678/1068
    614
from flask import request
@app.route("/api/users/<username>") 
def user_api(username):
try:
token = request.args.get("key") 
if key == "pA55w0Rd":
if isUser(username): # The code of this method is irrelevant
joined = joinDate(username) # The code of this method is irrelevant 
return "User " + username + " joined on " + joined
else:
return "User not found"
else:
return "Incorrect key" 
# If there is no key parameter 
except KeyError:
Los siguientes delimitadores se utilizan para diferentes interpretaciones:
• {% ... %} denota una declaración
• {{... }} denota una expresión donde se emite una plantilla
• {# ... #} denota un comentario (no incluido en la salida de la plantilla)
• {# ... ## implica que el resto de la línea debe interpretarse como una declaración
El objeto de solicitud
El objeto de request proporciona información sobre la solicitud que se realizó a la ruta. Para 
utilizar este objeto, debe importarse desde el módulo del matraz:
Parámetros de URL
En ejemplos anteriores se utilizaron request.method y request.form , sin embargo, también 
podemos usarla propiedad request.args pararecuperar un diccionariodelas claves / valoresen 
los parámetros de laURL.
{% if username %}
<h1>{{ username }} joined on the date {{ date }}</h1>
{% if len(awards) > 0 %}
<h3>{{ username }} has the following awards:</h3>
<ul>
{% for award in awards %}
<li>{{award}}</li>
{% endfor %}
</ul>
{% else %}
<h3>{{ username }} has no awards</h3>
{% endif %}
{% else %}
<h1>No user was found under that username</h1>
{% endif %}
{# This is a comment and doesn't affect the output #}
</body>
</html>
    679/1068
    615
@app.route("/upload", methods=["POST"]) 
def upload_file():
f = request.files["wordlist-upload"]
f.save("/var/www/uploads/" + f.filename) # Store with the original filename
@app.route("/home") 
def home():
try:
username = request.cookies.get("username") 
return "Your stored username is " + username
except KeyError:
return "No username cookies was found")
Para autenticarse correctamente en este contexto, se necesitaría la siguiente URL (reemplazando 
el nombre de usuario con cualquier nombre de usuario):
www.example.com/api/users/guido-van-rossum?key=pa55w0Rd
Cargas de archivos
Si la carga de un archivo era parte del formulario enviado en una solicitud POST, los archivos se 
pueden manejar usando el objeto de request :
Galletas
La solicitud también puede incluir cookies en un diccionario similar a los parámetros de URL.
return "No key provided"
    680/1068
    616
lst=[[1,2,3],[4,5,6],[7,8,9]]
print (lst[0])
#output: [1, 2, 3]
print (lst[1])
#output: [4, 5, 6]
print (lst[2])
#output: [7, 8, 9]
print (lst[0][0]) 
#output: 1
print (lst[0][1]) 
#output: 2
lst[0]=[10,11,12]
lst[1][2]=15
Capítulo 121: Matrices multidimensionales
Examples
Listas en listas
Una buena manera de visualizar una matriz 2D es como una lista de listas. Algo como esto:
aquílalistaexternalsttienetres cosasenél. cadaunadeesascosasesotralista:laprimeraes: 
[1,2,3] , la segunda es: [4,5,6] y la tercera es: [7,8,9] . Puede acceder a estas listas de la misma 
manera que accedería a otro elemento de una lista, como este:
A continuación, puede acceder a los diferentes elementos en cada una de esas listas de la misma 
manera:
Aquí el primer número dentro de los corchetes [] significa obtener la lista en esa posición. En el 
ejemplo anterior, usamos el número 0 para obtener la lista en la posición 0, que es [1,2,3] . El 
segundo conjunto de []corchetes significa obtener el elemento en esa posiciónde lalista interna. 
En este caso, utilizamos 0 y 1 la posición 0 en la lista que obtuvimos es el número 1 y en la 1ª 
posición es 2
También puede establecer valores dentro de estas listas de la misma manera:
Ahora la lista es [[10,11,12],[4,5,6],[7,8,9]] . En este ejemplo, cambiamos toda la primera lista 
para que sea una lista completamente nueva.
    681/1068
    617
[[[111,112,113],[121,122,123],[131,132,133]],\
[[211,212,213],[221,222,223],[231,232,233]],\
[[311,312,313],[321,322,323],[331,332,333]]]
myarray[1]=new_n-1_d_list 
myarray[2][1]=new_n-2_d_list
myarray[1][0][2]=new_n-3_d_list #or a single number if you're dealing with 3D arrays 
etc.
Ahora la lista es [[10,11,12],[4,5,15],[7,8,9]] . En este ejemplo, cambiamos un solo elemento 
dentro de una de las listas internas. Primero ingresamos a la lista en la posición 1 y cambiamos el 
elemento dentro de la posición 2, que era 6 ahora es 15.
Listas en listas en listas en ...
Este comportamiento puede ser extendido. Aquí hay una matriz tridimensional:
[[[111,112,113],[121,122,123],[131,132,133]],[[211,212,213],[221,222,223],[231,232,233]],[[311,312,313
Como probablemente sea obvio, esto se vuelve un poco difícil de leer. Usa barras invertidas para 
dividir las diferentes dimensiones:
Al anidar las listas como esta, puede extenderse a dimensiones arbitrariamente altas. 
El acceso es similar a las matrices 2D:
Y la edición también es similar:
print(myarray) 
print(myarray[1]) 
print(myarray[2][1]) 
print(myarray[1][0][2]) 
etc.
    682/1068
    618
Dummy = type('OtherDummy', (), dict(x=1)) 
Dummy. class # <type 'type'> 
Dummy(). class . class # <type 'type'>
class mytype(type):
def init (cls, name, bases, dict): 
# call the base initializer
type. init (cls, name, bases, dict)
# perform custom initialization... 
cls. custom_attribute = 2
MyDummy = mytype('MyDummy', (), dict(x=2))
MyDummy. class # <class ' main .mytype'> 
MyDummy(). class . class # <class ' main .mytype'> 
MyDummy. custom_attribute # 2
Capítulo 122: Metaclases
Introducción
Las metaclases le permiten modificar profundamente el comportamiento de las clases de Python 
(en términos de cómo se definen, se crean instancias, se accede a ellas, y más) al reemplazar la 
metaclase de type que las nuevas clases usan de forma predeterminada.
Observaciones
Al diseñar su arquitectura, tenga en cuenta que muchas cosas que se pueden lograr con las 
metaclases también se pueden lograr utilizando una semántica más simple:
• La herencia tradicional es a menudo más que suficiente.
• Los decoradores de clase pueden combinar la funcionalidad en una clase con un enfoque 
ad hoc.
• Python 3.6 introduce init_subclass () que permite a una clase participar en la creación 
de su subclase.
Examples
Metaclases basicas
Cuando se llama a type con tres argumentos, se comporta como la clase (meta) que es y crea 
una nueva instancia, es decir. produce una nueva clase / tipo.
Es posible subclase type para crear una metaclase personalizado.
Ahora, tenemos una nueva metaclase mytype personalizada que se puede utilizar para crear 
clases de la misma manera que el type .
    683/1068
    619
>>> class Foo(object):
... pass
>>> type(Foo) 
type
class MyDummy(object):
 metaclass = mytype
type(MyDummy) # <class ' main .mytype'>
class MyDummy(metaclass=mytype): 
pass
type(MyDummy) # <class ' main .mytype'>
class SingletonType(type):
def call (cls, *args, **kwargs): 
try:
return cls. instance 
except AttributeError:
cls. instance = super(SingletonType, cls). call (*args, **kwargs) 
return cls. instance
class MySingleton(object):
 metaclass = SingletonType
Cuando creamos una nueva clase utilizando la palabra clave de class la metaclase se elige de 
forma predeterminada en función de las clases básicas.
En el ejemplo anterior, la única clase de base es el object por lo que nuestra metaclase será el 
tipo de object , que es el type . Es posible anular el valor predeterminado, sin embargo, depende 
de si usamos Python 2 o Python3:
Python 2.x 2.7
Un atributo de nivel de clase especial metaclass se puede usar para especificar la metaclase.
Python 3.x 3.0
Un argumento especial de palabra clave de metaclass especifica la metaclase.
Cualquierargumentodepalabraclave(excepto metaclass)enladeclaración declasesepasaráa 
lametaclase.Así,laclass MyDummy(metaclass=mytype, x=2)pasaráx=2 comoargumentodepalabra 
clave al constructor mytype.
Lea esta descripción detallada de las meta-clases de python para más detalles.
Singletons utilizando metaclases
Un singleton es un patrón que restringe la creación de instancias de una clase a una instancia / 
objeto. Para más información sobre los patrones de diseño singleton de python, consulte aquí .
Python 2.x 2.7
    684/1068
    620
class MySingleton(metaclass=SingletonType): 
pass
MySingleton() is MySingleton() # True, only one instantiation occurs
class MyClass(object):
 metaclass = SomeMetaclass
class MyClass(metaclass=SomeMetaclass): 
pass
import six
class MyClass(six.with_metaclass(SomeMetaclass)): 
pass
class VerboseMetaclass(type):
def new (cls, class_name, class_parents, class_dict): 
print("Creating class ", class_name)
new_class = super(). new (cls, class_name, class_parents, class_dict) 
return new_class
class Spam(metaclass=VerboseMetaclass): 
def eggs(self):
print("[insert example string here]") 
s = Spam()
s.eggs()
Python 3.x 3.0
Usando una metaclase
Sintaxis de metaclase
Python 2.x 2.7
Python 3.x 3.0
Compatibilidad de Python 2 y 3 con six
Funcionalidad personalizada con metaclases.
La funcionalidad de las metaclases se puede cambiar de modo que cada vez que se construye 
una clase, se imprime una cadena en la salida estándar o se lanza una excepción. Esta 
metaclase imprimirá el nombre de la clase que se está construyendo.
Puedes usar la metaclase así:
    685/1068
    621
Creating class Spam
[insert example string here]
>>> type(5)
<type 'int'>
>>> type(str)
<type 'type'>
>>> type([1, 2, 3])
<type 'list'>
>>> class C(object):
... pass
...
>>> type(C)
<type 'type'>
class SimplestMetaclass(type): 
pass
class MyClass(object):
 metaclass = SimplestMetaclass
>>> type(MyClass)
<class ' main .SimplestMetaclass'>
La salida estándar será:
Introducción a las metaclases
¿Qué es una metaclase?
En Python, todo es un objeto: enteros, cadenas, listas, incluso las funciones y las clases en sí son 
objetos. Y cada objeto es una instancia de una clase.
Para verificar la clase de un objeto x, se puede llamar al type(x) , entonces:
La mayoría de las clases en python son instancias de type . type sí mismo es también una clase. 
Tales clases cuyas instancias son también clases se llaman metaclases.
La metaclase mas simple
OK, entonces ya hay una metaclase en Python: type . ¿Podemos crear otro?
Eso no agrega ninguna funcionalidad, pero es una nueva metaclase, vea que MyClass ahora es 
una instancia de SimplestMetaclass:
Una metaclase que hace algo
Una metaclase el que hace algo por lo general prevalece sobre type 's new , modificar algunas
    686/1068
    622
class AnotherMetaclass(type):
def new (cls, name, parents, dct): 
# cls is this class
# name is the name of the class to be created
# parents is the list of the class's parent classes
# dct is the list of class's attributes (methods, static variables)
# here all of the attributes can be modified before creating the class, e.g. 
dct['x'] = 8 # now the class will have a static variable x = 8
# return value is the new class. super will take care of that 
return super(AnotherMetaclass, cls). new (cls, name, parents, dct)
>>> type(1) 
int
>>> class Foo(object):
... pass
...
>>> bar = Foo()
>>> type(bar) 
Foo
>>> type(Foo) 
type
>>> type(type) 
type
propiedades de la clase que se creen, antes de llamar al original new que crea la clase:
La metaclase por defecto.
Es posible que hayas oído que todo en Python es un objeto. Es cierto, y todos los objetos tienen 
una clase:
El literal 1 es una instancia de int . Vamos a declarar una clase:
Ahora vamos a instanciarlo:
¿Cuál es la clase de bar ?
Agradable, el bar es una instancia de Foo . Pero, ¿cuál es la clase de Foo sí?
Ok, Foo sí es una instancia de type . ¿Qué tal el type sí mismo?
Entonces, ¿qué es una metaclase? Por ahora, simulemos que es solo un nombre elegante para la 
clase de una clase. Para llevar:
    687/1068
    623
• Todo es un objeto en Python, así que todo tiene una clase.
• La clase de una clase se llama metaclase.
• La metaclase predeterminada es de type y, con mucho, es la metaclase más común.
Pero ¿por qué debería saber acerca de las metaclases? Bueno, Python en sí mismo es bastante 
"hackeable", y el concepto de metaclase es importante si estás haciendo cosas avanzadas como 
meta-programación o si quieres controlar cómo se inicializan tus clases.
    688/1068
    624
class Parent(object): 
def introduce(self):
print("Hello!")
def print_name(self): 
print("Parent")
class Child(Parent):
def print_name(self): 
print("Child")
p = Parent() 
c = Child()
p.introduce() 
p.print_name()
c.introduce() 
c.print_name()
$ python basic_override.py 
Hello!
Parent 
Hello! 
Child
Capítulo 123: Método Anulando
Examples
Método básico anulando
Este es un ejemplo de anulaciónbásica enPython (por motivosdeclaridady compatibilidadcon 
Python 2 y 3, usando una nueva clase de estilo e print con() ):
Cuando el Child se crea la clase, que hereda los métodos de la Parent clase. Esto significa que 
cualquier método que tenga la clase padre, la clase hija también tendrá. En el ejemplo, la 
introduce se define para la clase Child porque está definida para Parent , a pesar de no estar 
definida explícitamente en la definición de clase de Child .
En este ejemplo, la anulación se produce cuando Child define su propio método print_name .Si 
este método no fue declarado, entonces c.print_name() habría impreso "Parent" . Sin embargo, 
Child ha anulado el Parent definición 's de print_name , y por eso ahora al llamar c.print_name() , la 
palabra "Child" se imprime.
    689/1068
    625
Capítulo 124: Métodos de cuerda
Sintaxis
• str.capitalize () -> str
• str.casefold () -> str [solo para Python> 3.3]
• str.center (ancho [, fillchar]) -> str
• str.count (sub [, start [, end]]) -> int
• str.decode (encoding = "utf-8" [, errores]) -> unicode [solo en Python 2.x]
• str.encode (codificación = "utf-8", errores = "estricto") -> bytes
• str.endswith (sufijo [, inicio [, final]]) -> bool
• str.expandtabs (tabsize = 8) -> str
• str.find (sub [, start [, end]]) -> int
• str.format (* args, ** kwargs) -> str
• str.format_map (mapeo) -> str
• str.index (sub [, start [, end]]) -> int
• str.isalnum () -> bool
• str.isalpha () -> bool
• str.isdecimal () -> bool
• str.isdigit () -> bool
• identificador str. () -> bool
• str.islower () -> bool
• str.isnumeric () -> bool
• str.isprintable () -> bool
• str.isspace () -> bool
• str.istitle () -> bool
• str.isupper () -> bool
• str.join (iterable) -> str
• str.ljust (ancho [, fillchar]) -> str
• str.lower () -> str
• str.lstrip ([caracteres]) -> str
• str.maketrans estático (x [, y [, z]])
• str.partition (sep) -> (head, sep, tail)
• str.replace (antiguo, nuevo [, cuenta]) -> str
• str.rfind (sub [, start [, end]]) -> int
• str.rindex (sub [, inicio [, final]]) -> int
• str.rjust (ancho [, fillchar]) -> str
• str.rpartition (sep) -> (head, sep, tail)
• str.rsplit (sep = None, maxsplit = -1) -> lista de cadenas
• str.rstrip ([caracteres]) -> str
• str.split (sep = None, maxsplit = -1) -> lista de cadenas
• str.splitlines ([keepends]) -> lista de cadenas
• str.startswith (prefijo [, inicio [, final]]) -> libro
• str.strip ([caracteres]) -> str
    690/1068
    626
"XßΣ".casefold() 
# 'xssσ'
"XßΣ".lower() 
# 'xßς'
• str.swapcase () -> str
• str.title () -> str
• str.translate (tabla) -> str
• str.upper () -> str
• str.zfill (ancho) -> str
Observaciones
Los objetos de cadena son inmutables, lo que significa que no se pueden modificar en su lugar 
como lo hace una lista. Debido a esto, los métodos en el tipo incorporado str siempre devuelven 
un nuevo objeto str , que contiene el resultado de la llamada al método.
Examples
Cambiar la capitalización de una cadena
El tipo de cadena de Python proporciona muchas funciones que actúan sobre la capitalización de 
una cadena. Éstos incluyen :
• str.casefold
• str.upper
• str.lower
• str.capitalize
• str.title
• str.swapcase
Con cadenas de Unicode (el valor predeterminado en Python 3), estas operaciones no son 
asignaciones 1: 1 o reversibles. La mayoría de estas operaciones están destinadas a fines de 
visualización, en lugar de a la normalización.
Python 3.x 3.3
str.casefold()
str.casefold crea una cadena en minúsculas que es adecuada para comparaciones que no 
distinguen entre mayúsculas y minúsculas. Esto es más agresivo que str.lower y puede modificar 
cadenas que ya están en minúsculas o hacer que las cadenas crezcan en longitud, y no está 
diseñada para fines de visualización.
Las transformaciones que tienen lugar en Casefolding están definidas por Unicode Consortium en 
el archivo CaseFolding.txt en su sitio web.
    691/1068
    627
"This is a 'string'.".upper() 
# "THIS IS A'STRING'."
"This IS a 'string'.".lower() 
# "this is a 'string'."
"this Is A 'String'.".capitalize() # Capitalizes the first character and lowercases all others 
# "This is a 'string'."
"this Is a 'String'".title() 
# "This Is A'String'"
"this iS A STRiNG".swapcase() #Swaps case of each character 
# "THIS Is a strIng"
str.upper()
str.uppertoma todos los caracteresde unacadenaylos convierte asu equivalente en 
mayúsculas, por ejemplo:
str.lower()
str.lower hace locontrario;toma todos los caracteres deunacadenaylos conviertea su 
equivalente en minúsculas:
str.capitalize()
str.capitalize devuelve una versión en mayúscula de la cadena, es decir, hace que el primer 
carácter tenga mayúsculas y el resto sea inferior:
str.title()
str.title devuelve el título de la versión de la cadena, es decir, todas las letras al principio de una 
palabra están en mayúsculas y las demás enminúsculas:
str.swapcase()
str.swapcase devuelve un nuevo objeto de cadena en el que todos los caracteres en minúsculas 
se cambian a mayúsculas y todos los caracteres en mayúsculas a inferiores:
Uso como métodos de clase str
Vale la pena señalar que estos métodos pueden llamarse en objetos de cadena (como se 
muestra arriba) o como un método de clase de la clase str (con una llamada explícita a str.upper
, etc.)
    692/1068
    628
map(str.upper,["These","are","some","'strings'"])
# ['THESE', 'ARE', 'SOME', "'STRINGS'"]
>>>" ".split()
[]
['This','is','a','sentence.']
>>> " Thisis a sentence. ".split()
>>>"Thisis a sentence.".split() 
['This', 'is', 'a', 'sentence.']
['', 'This', 'is', '', '', '', 'a', 'sentence.', '', '']
>>>"Thisis asentence.".split('e') 
['This is a s', 'nt', 'nc', '.']
>>>"Thisisasentence.".split('en') 
['This is a s', 't','ce.']
>>> " Thisis a sentence. ".split(' ')
>>>"Thisis a sentence.".split(' ') 
['This', 'is', 'a', 'sentence.']
>>> "Earth,Stars,Sun,Moon".split(',')
['Earth', 'Stars', 'Sun', 'Moon']
Esto es más útil cuando se aplica uno de estos métodos a muchas cadenas a la vez, por ejemplo, 
una función de map .
Dividir una cadena basada en un delimitador en una lista de cadenas
str.split(sep=None, maxsplit=-1)
str.split toma una cadena y devuelve una lista de subcadenas de la cadena original. El 
comportamiento difiere dependiendo de si el argumento sep se proporciona u omite.
Si no se proporciona sep , o es None , entonces la división tiene lugar donde hay espacios en 
blanco.Sinembargo,los espacios en blanco inicialesy finales seignoran,y varios caracteresde 
espacios en blanco consecutivos se tratan igual que un solo espacio en blanco:
El parámetro sep se puede usar para definir unacadena delimitadora. La cadena original se divide 
donde se produce la cadena delimitadora, y el propio delimitador se descarta. Varios 
delimitadores consecutivos no se tratan de la misma manera que una solaocurrencia, sino que 
hacen que se creen cadenas vacías.
El valor predeterminado es dividir en cada aparición del delimitador, sin embargo, el parámetro 
maxsplit limita el número de divisiones que se producen. El valor predeterminado de -1 significa 
que no hay límite:
str.upper("This is a 'string'") 
# "THIS IS A 'STRING'"
    693/1068
    629
>>> "Thisis a sentence.".rsplit('e', maxsplit=1) 
['This is a sentenc', '.']
>>>"Thisisasentence.".rsplit('e',maxsplit=2) 
['This is a sent', 'nc', '.']
>>> "Make sure to foo your sentence.".replace('foo', 'spam') 
"Make sure to spam your sentence."
>>> "It can foo multiple examples of foo if you want.".replace('foo', 'spam') 
"It can spam multiple examples of spam if you want."
str.rsplit(sep=None, maxsplit=-1)
str.rsplit ("división derecha") difiere de str.split ("división izquierda") cuando se especifica
maxsplit . La división comienza al final de la cadena en lugar de al principio:
Nota : Python especifica el número máximo de divisiones realizadas, mientras que la mayoría de 
los otros lenguajes de programación especifican el número máximo de subcadenas creadas. Esto 
puede crear confusión al portar o comparar código.
Reemplace todas las ocurrencias de una subcadena por otra subcadena
El tipo str dePython también tiene un método para reemplazarlas ocurrencias de una subcadena 
con otra subcadena en una cadena dada. Para casos más exigentes, uno puede usar re.sub .
str.replace(old, new[, count]) :
str.replace toma dos argumentos old y new que contiene el old sub-secuencia que va a ser 
reemplazado por el new sub-secuencia.El count argumentos opcional especifica el número de 
reemplazos que se realizarán:
Por ejemplo, para reemplazar 'foo' con 'spam' en la siguiente cadena, podemos llamar a
str.replace con old = 'foo' y new = 'spam' :
Si la cadena dada contiene múltiples ejemplos que coinciden con el old argumento, todas las
apariciones se reemplazan por el valor suministrado en new :
>>> "This is a sentence.".split('e', maxsplit=0) 
['This is a sentence.']
>>> "This is a sentence.".split('e', maxsplit=1) 
['This is a s', 'ntence.']
>>> "This is a sentence.".split('e', maxsplit=2) 
['This is a s', 'nt', 'nce.']
>>>"Thisisasentence.".split('e',maxsplit=-1) 
['This is a s', 'nt', 'nc', '.']
    694/1068
    630
>>> """It can foo multiple examples of foo if you want, \
... or you can limit the foo with the third argument.""".replace('foo', 'spam', 1)
'It can spam multiple examples of foo if you want, or you can limit the foo with the third 
argument.'
"10 1.5 foo ['a', 1, 2] {'a': 1, 2: 'foo'}"
>>> "{} {} {} {} {}".format(i, f, s, l, d)
>>> str.format("{} {} {} {} {}", i, f, s, l, d)
>>> "{0} {1} {2} {3} {4}".format(i, f, s, l, d)
>>> "{0:d} {1:0.1f} {2} {3!r} {4!r}".format(i, f, s, l, d)
>>> "{i:d} {f:0.1f} {s} {l!r} {d!r}".format(i=i, f=f, s=s, l=l, d=d)
>>> f"{i} {f} {s} {l} {d}"
>>> f"{i:d} {f:0.1f} {s} {l!r} {d!r}"
"%d %0.1f %s %r %r" % (i, f, s, l, d)
"%(i)d %(f)0.1f %(s)s %(l)r %(d)r" % dict(i=i, f=f, s=s, l=l, d=d)
A menos que, por supuesto, proporcionemos un valor para el count .En este caso, las ocurrencias 
de count serán reemplazadas:
str.format y f-strings: formatea valores en una cadena
Python proporciona interpolación de cadenas y funcionalidad de formato a través de la función
str.format , introducida en laversión 2.6 y f-cadenas introducidas en la versión3.6. 
Dadas las siguientes variables:
Las siguientes afirmaciones son todas equivalentes
Para referencia, Python también admite calificadores de estilo C para el formato de cadenas. Los 
ejemplos a continuación son equivalentes a los anteriores, pero se prefieren las versiones de 
str.format debido a los beneficios en flexibilidad, consistencia de notación y extensibilidad:
Lasllavesqueseusanparalainterpolación enstr.format destr.format tambiénsepueden 
numerar para reducirla duplicación al formatear cadenas.Por ejemplo, los siguientes son 
equivalentes:
i = 10
f = 1.5
s = "foo"
l = ['a', 1, 2]
d = {'a': 1, 2: 'foo'}
    695/1068
    631
>>> "I am from {}. I love cupcakes from {}!".format("Australia", "Australia")
>>> "I am from {0}. I love cupcakes from {0}!".format("Australia")
"{'a': 5, 'b': 6}"
>>> "{{'{}': {}, '{}': {}}}".format("a", 5, "b", 6)
>>> f"{{'{'a'}': {5}, '{'b'}': {6}}"
>>> s = "She sells seashells by the seashore."
>>> s.count("sh") 
2
>>> s.count("se") 
3
>>> s.count("sea") 
2
>>> s.count("seashells") 
1
>>> s.count("sea", start) 
1
Si bien la documentación oficial de Python es, como es habitual, lo suficientemente exhaustiva, 
pyformat.info tiene un gran conjunto de ejemplos con explicaciones detalladas.
Además, los caracteres { y } pueden escaparse utilizando corchetes dobles:
Consulte Formato de cadena para obtener información adicional. str.format() se propuso en PEP
3101 y f-strings en PEP 498 .
Contando el número de veces que una subcadena aparece en una cadena
Hayun métododisponible paracontar el númerodeapariciones deunastr.counten otracadena,
str.count .
str.count(sub[, start[, end]])
str.count devuelve unint indica el númerode apariciones nosuperpuestas delastr.count suben 
otracadena.Losargumentosopcionalesstartyendindicanelprincipioyelfinalenelquese 
realizará la búsqueda. De forma predeterminada, start =0 y end=len(str) significa que se 
buscará en toda la cadena:
Al especificar un valor diferente para el start , al end , podemos obtener una búsqueda más 
localizada y contar, por ejemplo, si el start es igual a 13 la llamadaa:
es equivalente a:
"I am from Australia. I love cupcakes from Australia!"
    696/1068
    632
>>> s = "This is a test string"
>>> s.startswith("T") 
True
>>>s.startswith("Thi") 
True
>>> s.startswith("thi") 
False
>>> s.startswith("is", 2) 
True
>>> s.startswith(('This', 'That')) 
True
>>> s.startswith(('ab', 'bc')) 
False
>>> s = "this ends in a full stop."
>>> s.endswith('.') 
True
>>> s.endswith('!') 
False
Prueba los caracteres iniciales y finales de una cadena.
Para probar el principio y el final de una cadena dada en Python, uno puede usar los métodos
str.startswith() y str.endswith() .
str.startswith(prefix[, start[, end]])
Como su nombre lo indica, str.startswith se usa para probar si una cadena dada comienza con 
los caracteres dados en el prefix.
Los argumentos opcionales de start y end especifican los puntos de inicio y finalización a partir de 
los cuales se iniciarán y finalizarán las pruebas.En el siguiente ejemplo, al especificar un valor de 
inicio de 2 , se buscará nuestra cadena desde la posición 2 y después:
Esto da como resultado True desde s[2] == 'i' y s[3] == 's' .
También puede usar una tuple para verificar si comienza con alguna de un conjunto de cadenas
str.endswith(prefix[, start[, end]])
str.endswith es exactamente similar a str.startswith la única diferencia es que busca caracteres 
finales y no caracteres iniciales. Por ejemplo, para probar si una cadena termina en una parada 
completa, se podría escribir:
>>> t = s[start:]
>>> t.count("sea") 
1
    697/1068
    633
>>> s.endswith('stop.') 
True
>>> s.endswith('Stop.') 
False
>>> s.endswith(('.', 'something')) 
True
>>> s.endswith(('ab', 'bc')) 
False
>>> "HeLLO WORLD".isupper() 
False
>>> "HELLO WORLD".isupper()
True
>>> "".isupper() 
False
al igual que con startswith se pueden usar más de un carácter como secuencia final:
También puede usar una tuple para verificar si termina con cualquiera de un conjunto de cadenas
Probando de qué está compuesta una cuerda
EltipostrdePythontambiénpresentaunaseriedemétodosquesepuedenusarparaevaluarel 
contenido de una cadena. Estos son str.isalpha , str.isdigit , str.isalnum , str.isspace . La 
capitalización se puede probar con str.isupper , str.islower y str.istitle .
str.isalpha
str.isalpha no toma argumentos y devuelve True si todos los caracteres de una cadena dada son 
alfabéticos, por ejemplo:
>>> "Hello World".isalpha() 
False
>>> "Hello2World".isalpha() 
False
>>> "HelloWorld!".isalpha() 
False
>>> "HelloWorld".isalpha() 
True
# contains a space 
# contains a number
# contains punctuation
Comouncasodeborde,lacadenavacíaseevalúacomoFalse cuandoseusacon"".isalpha() .
str.isupper , str.islower , str.istitle
Estos métodos prueban el uso de mayúsculas en una cadena dada.
str.isupper es un método quedevuelve True si todos los caracteres de una cadena dada están en 
mayúsculas y False caso contrario.
    698/1068
    634
isdecimal isdigit isnumeric
>>> "Hello world".islower() 
False
>>> "hello world".islower() 
True
>>> "".islower() 
False
>>>"hello world".istitle() 
False
>>> "Hello world".istitle() 
False
>>> "HelloWorld".istitle() 
True
>>> "".istitle() 
False
Alainversa, str.islower es un método que devuelve True si todos los caracteres de una cadena 
dada son minúsculas y Falsecontrario.
str.istitle devuelve True si la cadena dada es un título cargado; es decir, cada palabra comienza 
con un carácter en mayúscula seguido de caracteres en minúscula.
str.isdecimal , str.isdigit , str.isnumeric
str.isdecimal devuelve si la cadena es una secuencia de dígitos decimales, adecuada para 
representar un número decimal.
str.isdigit incluye dígitos que no están en una forma adecuada para representar un número 
decimal, como los dígitos en superíndice.
str.isnumeric incluye cualquiervalor numérico,incluso si no son dígitos, como valores fuera del 
rango 0-9.
12345 True True True
□2□□5 True True True
①²³□₅ False True True
⑩□ False False True
Five False False False
Bytestrings(bytesenPython3,strenPython2),soloadmiteisdigit,quesoloverificalosdígitos 
ASCII básicos.
Al igual que con str.isalpha , la cadena vacía se evalúa como False .
str.isalnum
Esta es una combinación de str.isalpha y str.isnumeric , específicamente se evalúa como True si 
todos los caracteres en la cadena dada son alfanuméricos , es decir, consisten en caracteres
    699/1068
    635
>>> "Hello2World".isalnum() 
True
>>> "HelloWorld".isalnum() 
True
>>> "2016".isalnum() 
True
>>> "Hello World".isalnum() # contains whitespace 
False
>>> "\t\r\n".isspace() 
True
>>> " ".isspace() 
True
>>> "".isspace() 
False
>>> my_str = ''
>>> my_str.isspace() 
False
>>> my_str.isspace() or not my_str 
True
>>> not my_str.strip() 
True
str.translate(table[, deletechars])
alfabéticos o numéricos:
str.isspace
Se evalúa como True si la cadena solo contiene caracteres de espacio en blanco.
A veces, una cadena se ve "vacía" pero no sabemos si es porque solo contiene espacios en 
blanco o ningún carácter.
Para cubrir este caso necesitamos una prueba adicional.
Pero la forma más corta de probar si una cadena está vacía o simplemente contiene caracteres 
de espacio en blanco es usar la strip (sin argumentos elimina todos los caracteres de espacio en 
blanco iniciales y finales)
str.translate: Traducir caracteres en una cadena
Python admite un método de translate en el tipo str que le permite especificar la tabla de 
traducción(utilizadaparalos reemplazos),asícomocualquier carácterquedebaeliminarseenel 
proceso.
    700/1068
    636
>>> 'this syntax is very useful'.translate(None, 'aeiou') 
'ths syntx s vry sfl'
>>> translation_table = str.maketrans("aeiou", "12345")
>>> my_string = "This is a string!"
>>> translated = my_string.translate(translation_table) 
'Th3s 3s 1 str3ng!'
'a line with leading and trailing space'
>>> " a line with leading and trailing space ".strip()
>>> ">>> a Python prompt".strip('> ') # strips '>' character and space character 
'a Python prompt'
Parámetro Descripción
table Es una tabla de búsqueda que define la asignación de un carácter a otro.
deletechars Una lista de caracteres que se eliminarán de la cadena.
El método maketrans ( str.maketrans en Python 3 y string.maketrans en Python 2) le permite 
generar una tabla de traducción.
El método de translate devuelve una cadena que es una copia traducida de la cadena original. 
Puede establecer el argumento de la table en None si solo necesita eliminar caracteres.
Eliminar caracteres iniciales / finales no deseados de una cadena
Se proporcionan tres métodos que ofrecen la posibilidad de eliminar los caracteres str.strip y 
finales de una cadena: str.strip , str.rstrip y str.lstrip . Los tres métodos tienen la misma firma 
y los tres devuelven un nuevo objeto de cadena con caracteres no deseados eliminados.
str.strip([chars])
str.strip actúa sobre una cadena dada y elimina (elimina) cualquier carácter str.strip o final 
contenido en los charsargumento;Si no se suministranchars o es None , todos los caracteresde 
espacios en blanco se eliminan de forma predeterminada. Por ejemplo:
Si se proporcionan chars , todos los caracteres contenidos en él se eliminan de la cadena, que se 
devuelve. Por ejemplo:
str.rstrip([chars]) y str.lstrip([chars])
Estosmétodostienenunasemánticayargumentossimilaresconstr.strip() ,sudiferenciaradica 
en la dirección desde la que comienzan. str.rstrip() comienza desde el final de la cadena,
    701/1068
    637
'spaciousstring '
>>> " spacious string ".rstrip()
>>> "ß".lower() 
'ß'
>>> "ß".upper().lower() 
'ss'
>>> help(str.casefold) 
"""
Help on method_descriptor:
casefold(...)
S.casefold() -> str
Return a version of S suitable for caseless comparisons.
"""
>>> "ê" == " ê"
mientrasquestr.lstrip() dividedesdeelprincipiodelacadena. 
Por ejemplo, usando str.rstrip :
Mientras, usando str.lstrip :
Comparaciones de cadenas insensibles al caso
La comparación de cadenas en una forma que no distingue entre mayúsculas y minúsculas 
parece algo trivial, pero no lo es. Esta sección solo considera las cadenas Unicode (la 
predeterminada en Python 3). Tenga en cuenta que Python 2 puede tener debilidades sutiles en 
relación con Python 3; el manejo de Unicode de este último es mucho más completo.
Loprimeroquehayquetener encuentaesquelasconversionesdeeliminacióndecasosen 
Unicode no son triviales. Hay texto para el que text.lower() != text.upper().lower() , como "ß" :
Pero digamos que quería comparar "BUSSE" y "Buße" .Demonios, es probable que también quieras 
comparar "BUSSE" y "BU□E" iguales, esa es la forma de capital más nueva.La forma recomendada 
es usar casefold :
Python 3.x 3.3
No se limite a usar lower . Si la casefold no está disponible, hacer .upper().lower() ayuda (pero 
solo un poco).
Entoncesdeberíasconsiderarlosacentos.Si suprocesadordefuentesesbueno,probablemente 
piense que "ê" == "ê" , pero no lo hace:
spacious string ".rstrip()
spacious string'
>>>" 
'
    702/1068
    638
>>> import unicodedata
>>> [unicodedata.name(char) for char in "ê"] 
['LATINSMALLLETTEREWITHCIRCUMFLEX']
>>> [unicodedata.name(char) for char in "ê"]
['LATIN SMALL LETTER E', 'COMBINING CIRCUMFLEX ACCENT']
>>> unicodedata.normalize("NFKD", "ê") == unicodedata.normalize("NFKD", "ê") 
True
import unicodedata
def normalize_caseless(text):
return unicodedata.normalize("NFKD", text.casefold())
def caseless_equal(left, right):
return normalize_caseless(left) == normalize_caseless(right)
>>> " ".join(["once","upon","a","time"]) 
"once upon a time"
>>> "---".join(["once", "upon", "a", "time"]) 
"once---upon---a---time"
>>> import string
Esto es porque en realidad son
La forma más sencilla de lidiar con esto es unicodedata.normalize . Probablemente desee utilizar la 
normalización NFKD , pero no dude en consultar la documentación. Entonces uno hace
Para finalizar, aquí esto se expresa en funciones:
Unir una lista de cadenas en una cadena
Una cadena puede usarse como separador para unir una lista de cadenas en una sola cadena 
usando el método join() . Por ejemplo, puede crear una cadena en la que cada elemento de una 
lista esté separado por un espacio.
El siguiente ejemplo separa los elementos de cadena con tres guiones.
Constantes útiles del módulo de cadena
El módulo de string de Python proporciona constantes para operaciones relacionadas con 
cadenas. Para usarlos, importa el módulo de string:
False
    703/1068
    639
>>> string.ascii_letters 
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.ascii_lowercase 
'abcdefghijklmnopqrstuvwxyz'
>>> string.ascii_uppercase 
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits 
'0123456789'
>>> string.hexdigits 
'0123456789abcdefABCDEF'
>>> string.octaldigits 
'01234567'
string.ascii_letters :
Concatenación de ascii_lowercase y ascii_uppercase :
string.ascii_lowercase
Contiene todos los caracteres ASCII en minúsculas:
string.ascii_uppercase :
Contiene todos los caracteres ASCII en mayúsculas:
string.digits :
Contiene todos los caracteres de dígitos decimales:
string.hexdigits :
Contiene todos los caracteres de dígitos hexadecimales:
string.octaldigits :
Contiene todos los caracteres de dígitos octales:
string.punctuation :
    704/1068
    640
>>> string.punctuation '!"#$%&\'()*+,-
./:;<=>?@[\\]^_`{|}~'
>>> string.whitespace 
' \t\n\r\x0b\x0c'
>>> string.printable 
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-
./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
>>> reversed('hello')
<reversed object at 0x0000000000000000>
>>>[charfor charin reversed('hello')] 
['o', 'l', 'l', 'e', 'h']
>>> ''.join(reversed('hello')) 
'olleh'
>>> def reversed_string(main_string):
... return main_string[::-1]
...
>>> reversed_string('hello')
Contiene todos los caracteres que se consideran puntuación en la configuración regional de C :
string.whitespace :
Contiene todos los caracteres ASCII considerados espacios en blanco:
Enelmododescript, print(string.whitespace) imprimiráloscaracteres reales,usestrpara 
obtener la cadena devueltaarriba.
string.printable :
Contiene todos los caracteres que se consideran imprimibles; una combinación de string.digits ,
string.ascii_letters , string.punctuation y string.whitespace .
Invertir una cadena
Una cadena puede revertirse usando la función reversed() incorporada, que toma una cadena y 
devuelve un iterador en orden inverso.
reversed() puede envolverse en una llamada a ''.join() para crear una cadena desde el iterador.
Si bienel uso de reversed()puede ser máslegible paralos usuariosnoiniciados dePython,el 
uso del corte extendido con un paso de -1es más rápido y conciso.Aquí, intenteimplementarlo 
como función:
    705/1068
    641
interstates_lengths = { 
5: (1381, 2222),
}
for road, length in interstates_lengths.items(): 
miles,kms = length
print('{} -> {} mi. ({} km.)'.format(str(road).rjust(4), str(miles).ljust(4),
str(kms).ljust(4)))
# You get "© abc" encoded in UTF-8 from a file, network, or other data source
s = '\xc2\xa9 abc' # s is a byte array, not a string of characters
# Doesn't know the original was UTF-8
Justificar cuerdas
Python proporciona funciones para justificar cadenas, permitiendo el relleno de texto para que la 
alineación de varias cadenas sea mucho más fácil.
A continuación se muestra un ejemplo de str.ljust y str.rjust :
19: (63, 102),
40: (2555, 4112),
93: (189,305),
40 -> 2555 mi. (4112 km.)
19 -> 63 mi. (102 km.)
5 -> 1381 mi. (2222 km.)
93 -> 189 mi. (305 km.)
ljust y rjust son muy similares. Ambos tienen un parámetro de width y un parámetro de fillchar
opcional.Cualquier cadena creada porestas funcioneses al menos tanlarga comoel parámetro 
dewidthquesepasóalafunción.Silacadenaesmáslargaqueelwidthalread,nosetrunca.El 
argumentofillchar,quepordefectoeselcarácterdeespacio' 'debeserunsolocarácter,no 
una cadena de caracteresmúltiples.
La función ljust el final de la cadena con la que se llama con el fillchar hasta que tenga una 
width caracteres.Lafunciónrjustelprincipiodelacadenadeuna manerasimilar.Porlotanto,ly 
renlosnombresdeestasfuncionesserefierenalladoenelquelacadenaoriginal,noelfillchar
, está posicionado en la cadena de salida.
Conversión entre str o bytes de datos y caracteres Unicode
El contenido de los archivos y mensajes de la red puede representar caracteres codificados. A 
menudo necesitan ser convertidos a Unicode para una visualización adecuada.
EnPython2,esposible quenecesiteconvertirdatosdestr acaracteresUnicode.Elvalor 
predeterminado('', "",etc.)esunacadenaASCII,concualquiervalorfueradelrangoASCII 
mostrado como valores escapados. Las cadenas Unicode sonu''(o u"" , etc.).
Python 2.x 2.3
'olleh'
    706/1068
    642
characters.
# b'\xc2\xa9 abc'
# str.encode produces a byte array, showing ASCII-range bytes as unescaped
u.encode('utf-8')
# You get from file or network "© abc" encoded in UTF-8
s = b'\xc2\xa9 abc' # s is a byte array, not characters
# In Python 3, the default string literal is Unicode; byte array literals
need a leading b
s[0] # b'\xc2' - meaningless byte (without context such as an encoding) 
type(s) # bytes - now that byte arrays are explicit, Python can show that.
u = s.decode('utf-8') # '© abc' on a Unicode terminal
# bytes.decode converts a byte array to a string (which will, in Python
3, be Unicode)
u[0] # '\u00a9' - Unicode Character 'COPYRIGHT SIGN' (U+00A9)'©'
type(u) # str
# The default string literal in Python 3 is UTF-8 Unicode
>>> "foo" in "foo.baz.bar" 
True
>>> "" in "test"
EnPython3 es posiblequenecesiteconvertir matrices debytes (denominadas 'literal debyte')a 
cadenasdecaracteresUnicode.ElvalorpredeterminadoesahoraunacadenaUnicode,ylos 
literales de bytestring ahora debeningresarse como b'' , b"" ,etc. Unliteral de byte devolverá 
True a isinstance(some_val, byte) , asumiendo que some_val es una cadena que podría estar 
codificada como bytes.
Python 3.x 3.0
Cadena contiene
Python hace que sea extremadamente intuitivo comprobar si una cadena contiene una subcadena 
dada. Solo usa el operador in :
Nota: probar una cadena vacía siempre resultará en True :
characters
# '\xc2\xa9 abc'
# unicode.encode produces a string with escaped bytes for non-ASCII
u.encode('utf-8')
u = s.decode('utf-8') # u'\xa9 abc'
# Now we have a Unicode string, which can be read as UTF-8 and printed
properly
# In Python 2, Unicode string literals need a leading u
# str.decode converts a string which may contain escaped bytes to a
Unicode string
u[0] # u'\xa9' - Unicode Character 'COPYRIGHT SIGN' (U+00A9) '©' 
type(u) # unicode
# Default form of string literals in Python 2
# '\xc2' - meaningless byte (without context such as an encoding)
# str - even though it's not a useful one w/o having a known encoding
s[0]
type(s)
    707/1068
    643
True
    708/1068
    644
class A(object):
# func: A user-defined function object 
#
# Note that func is a function object when it's defined, 
# and an unbound method object when it'sretrieved.
def func(self): 
pass
# classMethod: A class method 
@classmethod
def classMethod(self): 
pass
class B(object):
# unboundMeth: A unbound user-defined method object 
#
# Parent.func is an unbound user-defined method object here, 
# because it's retrieved.
unboundMeth = A.func
a = A()
b = B()
print A.func
# output: <unbound method A.func> 
print a.func
# output: <bound method A.func of < main .A object at 0x10e9ab910>> 
print B.unboundMeth
# output: <unbound method A.func> 
print b.unboundMeth
# output: <unbound method A.func> 
print A.classMethod
#output:<boundmethodtype.classMethodof<class'main.A'>> 
print a.classMethod
# output: <bound method type.classMethod of <class 'main .A'>>
Capítulo 125: Métodos definidos por el 
usuario
Examples
Creando objetos de método definidos por el usuario
Los objetos de método definidos por el usuario pueden crearse cuando se obtiene un atributo de 
una clase (quizás a través de una instancia de esa clase), si ese atributo es un objeto de función 
definido por el usuario, un objeto de método definido por el usuario no vinculado o un objeto de 
método de clase.
Cuando el atributo es un objeto de método definido por el usuario, un nuevo objeto de método 
solo se crea si la clase de la cual se está recuperando es la misma clase que la clase almacenada 
en el objeto de método original, o una clase derivada de la misma; de lo contrario, el objeto del 
método original se usa tal como es.
    709/1068
    645
Ejemplo de tortuga
El siguiente es un ejemplo del uso de una función definida por el usuario para ser llamada varias 
veces (∞) en un script con facilidad.
import turtle, time, random #tell python we need 3 different modules 
turtle.speed(0) #set draw speed to the fastest
turtle.colormode(255) #special colormode 
turtle.pensize(4) #size of the lines that will be drawn
def triangle(size): #This is our own function, in the parenthesis is a variable we have 
defined that will be used in THIS FUNCTION ONLY. This fucntion creates a right triangle
turtle.forward(size) #to begin this function we go forward, the amount to go forward by is
the variable size
turtle.right(90) #turn right by 90 degree 
turtle.forward(size) #go forward, again with variable 
turtle.right(135) #turn right again
turtle.forward(size * 1.5) #close the triangle. thanks to the Pythagorean theorem we know
that this line must be 1.5 times longer than the other two(if they are equal)
while(1): #INFINITE LOOP
turtle.setpos(random.randint(-200, 200), random.randint(-200, 200)) #set the draw point to 
a random (x,y) position
turtle.pencolor(random.randint(1, 255), random.randint(1, 255), random.randint(1, 255)) 
#randomize the RGB color
triangle(random.randint(5, 55)) #use our function, because it has only one variable we can 
simply put a value in the parenthesis. The value that will be sent will be random between 5 -
55, end the end it really just changes ow big the triangle is.
turtle.pencolor(random.randint(1, 255), random.randint(1, 255), random.randint(1, 255)) 
#randomize color again
# False, new object created
# False, new object created 
# False, new object created
# True, original object used
print Parent.func is Parent.func 
print Parent.func2 is Parent.func2 
print Child.func is Child.func
print AnotherClass.func is AnotherClass.func
# Parent: The class stored in the original method object 
class Parent(object):
# func: The underlying function of original method object 
def func(self):
pass 
func2 = func
# Child: A derived class of Parent 
class Child(Parent):
func = Parent.func
# AnotherClass: A different class, neither subclasses nor subclassed 
class AnotherClass(object):
func = Parent.func
    710/1068
    646
class Vehicle(object):
"""A generic vehicle class."""
def init (self, position): 
self.position = position
def travel(self, destination):
route = calculate_route(from=self.position, to=destination) 
self.move_along(route)
class Car(Vehicle):
...
class Boat(Vehicle):
...
class Plane(Vehicle):
Capítulo 126: Mixins
Sintaxis
• class ClassName ( MainClass , Mixin1 , Mixin2 , ...): # Se utiliza para declarar una clase con 
el nombre ClassName , main (first) class MainClass y mixins Mixin1 , Mixin2 , etc.
• class ClassName ( Mixin1 , MainClass , Mixin2 , ...): # La clase 'main' no tiene que ser la 
primera clase; Realmente no hay diferencia entre esto y la mezcla
Observaciones
Agregarunmixinaunaclaseseparecemuchoaagregarunasuperclase,porqueesmáso 
menoseso.UnobjetodeunaclaseconlamezclaFootambiénseráunainstanciadeFoo,e 
isinstance(instance, Foo) devolverá verdadero
Examples
Mezclar
Un Mixin es un conjunto de propiedades y métodos que se pueden usar en diferentes clases, que 
no provienen de una clase base. En los lenguajes de programación orientada a objetos, 
normalmente se usa la herencia para dar a los objetos de diferentes clases la misma 
funcionalidad; si un conjunto de objetos tiene alguna habilidad, pones esa habilidad en una clase 
base de la cual ambos objetos heredan .
Por ejemplo, supongamos que tiene las clases Car , Boat y Plane . Los objetos de todas 
estas clases tienen la capacidad de viajar, por lo que obtienen la función de travel . En 
este escenario, todos viajan de la misma manera básica, también; consiguiendo una 
ruta, y moviéndose a lo largo de ella. Para implementar esta función, podría derivar 
todas las clases de Vehicle y poner la función en esa clase compartida:
    711/1068
    647
class Foo(main_super, mixin): ...
class RadioUserMixin(object): 
def init (self):
self.radio = Radio()
def play_song_on_station(self, station): 
self.radio.set_station(station) 
self.radio.play_song()
class Car(Vehicle, RadioUserMixin):
...
class Clock(Vehicle, RadioUserMixin):
...
Con este código, puedellamar a travel en un automóvil ( car.travel("Montana") ), 
barco ( boat.travel("Hawaii") ), y avión ( plane.travel("France") )
Sin embargo, ¿qué sucede si tiene una funcionalidad que no está disponible para una clase 
base? Digamos, por ejemplo, que quieres darle a Car una radio y la posibilidad de usarla para 
reproducir una canción en una estación de radio, con play_song_on_station , pero también tienes 
un Clock que puede usar una radio. Car y Clock podrían compartir una clase base ( Machine ). Sin 
embargo, no todas las máquinas pueden reproducir canciones; Boat y Plane no pueden (al menos 
en este ejemplo). Entonces, ¿cómo lograr sin duplicar el código? Puedes usar un mixin. En 
Python, dar una mezcla a una clase es tan simple como agregarla a la lista de subclases, como 
esto
Foo heredará todas las propiedades y métodos de main_super , pero también los de mixin .
Por lo tanto, para dar a las clases Car y reloj la posibilidad de usar una radio, puede 
anular Car del último ejemplo y escribir esto:
Ahora puedes llamar a car.play_song_on_station(98.7) y 
clock.play_song_on_station(101.3) , pero no a algo como 
boat.play_song_on_station(100.5)
Lo importante con los mixins es que le permiten agregar funcionalidad a objetos muy diferentes, 
que no comparten una subclase "principal" con esta funcionalidad, pero aún así comparten el 
código para ello. Sin los mixins, hacer algo como el ejemplo anterior sería mucho más difícil y / o 
podría requerir alguna repetición.
Métodos de anulación en Mixins
Los mixins son una clase de clase que se usa para "mezclar" propiedades y métodos adicionales 
en una clase. Por lo general, esto está bien porque muchas veces las clases mixtas no se anulan 
entre sí, o los métodos de la clase base. Pero si anula métodos o propiedades en sus 
combinaciones, esto puede llevar a resultados inesperados porque en Python la jerarquía de
...
    712/1068
    648
>>> x = MyClass()
>>> x.test() 
Base
clases se define de derecha a izquierda. 
Por ejemplo, tome las siguientes clases
En este caso, la clase Mixin2 es la clase base, extendida por Mixin1 y finalmente por BaseClass. 
Por lo tanto, si ejecutamos el siguiente fragmento de código:
Vemos que el resultado devuelto es de la clase Base. Esto puede provocar errores inesperados 
en la lógica de su código y debe tenerse en cuenta y tenerse en cuenta.
class Mixin1(object): 
def test(self):
print "Mixin1"
class Mixin2(object): 
def test(self):
print "Mixin2"
class BaseClass(object): 
def test(self):
print "Base"
class MyClass(BaseClass, Mixin1, Mixin2): 
pass
    713/1068
    649
def add_student(): 
try:
students['count'] += 1 
except KeyError:
students['count'] = 1
def add_student():
students['count'] = students.get('count', 0) + 1
x = True 
y = False
x, y = y, x 
x
# False 
y
# True
# Good examples, using implicit truth testing 
if attr:
# do something
if not attr:
# do something
#Bad examples, using specific types 
if attr == 1:
Capítulo 127: Modismos
Examples
Inicializaciones clave del diccionario
Prefiera el métododict.get sinoestá seguro si laclave está presente.Le permite devolver un 
valorpredeterminadosinoseencuentralaclave.Elmétodotradicionaldict[key]generaríauna 
excepción KeyError .
En lugar de hacer
Hacer
Variables de conmutacion
Para cambiar el valor de dos variables puede usar el desempaquetado de la tupla.
Use la prueba de valor de verdad
Python convertirá implícitamente cualquier objeto a un valor booleano para la prueba, así que 
úsalo siempre que sea posible.
    714/1068
    650
import sys
def main():
# Your code starts here
# Don't forget to provide a return code 
return 0
if name == " main": 
sys.exit(main())
python my_program.py
# But you can run main() explicitly if you really want it to run: 
my_program.main()
# main() is not run
# A new program file 
import my_program
Esto generalmente produce un código más legible, y generalmente es mucho más seguro cuando 
se trata de tipos inesperados.
Haga clic aquí para obtener una lista de lo que se evaluará como False .
Prueba de " main " para evitar la ejecución inesperada del código
Es una buena práctica probar la variable name del programa que llama antes de ejecutar su 
código.
El uso de este patrón asegura que su código solo se ejecute cuando espera que lo sea; por 
ejemplo, cuando ejecuta su archivo explícitamente:
Sin embargo, el beneficio viene si decide import su archivo a otro programa (por ejemplo, si lo 
está escribiendo como parte de una biblioteca). Luego puede import su archivo, y la trampa
 main se asegurará de que no se ejecute ningún código inesperadamente:
# do something
if attr == True:
# do something
if attr != '':
# do something
# If you are looking to specifically check forNone, use 'is' or'is not' 
if attr is None:
# do something
    715/1068
    651
import random
laughs = ["Hi", "Ho", "He"]
random.shuffle(laughs) # Shuffles in-place! Don't do: laughs =random.shuffle(laughs) 
print(laughs)
# Out: ["He", "Hi", "Ho"] # Output may vary!
print(random.choice(laughs))
# Out: He # Output may vary!
Capítulo 128: Módulo aleatorio
Sintaxis
• random.seed (a = Ninguna, versión = 2) (la versión solo está disponible para Python 3.x)
• random.getstate ()
• random.setstate (estado)
• random.randint (a, b)
• random.randrange (detener)
• random.randrange (inicio, parada, paso = 1)
• elección aleatoria
• random.shuffle (x, random = random.random)
• muestra aleatoria (población, k)
Examples
Aleatorio y secuencias: barajar, selección y muestra.
barajar()
Puedeusarrandom.shuffle() para mezclar/aleatorizarloselementos en una secuencia mutable 
e indexable . Por ejemplo una list :
elección()
Toma un elemento aleatorio de una secuencia arbitraria:
muestra()
    716/1068
    652
# Output may vary!
laughs , 1 )) # Take one element
# |--sequence--|--number--|
print(random.sample(
# Out: ['Ho']
import random
random.randint(x, y)
random.randint(1, 8) # Out: 8
random.rangrange(10, 20, 3) # Random integer between 10 and 19 with step 3 (10, 13, 16 and 19)
# Random integer between 0 and 99 
# Random integer between 20 and 49
random.randrange(100) 
random.randrange(20, 50)
Como choice , toma elementos aleatorios de una secuencia arbitraria , pero puedes especificar 
cuántos:
no tomará el mismo elemento dos veces:
print(random.sample(laughs, 3)) # Take 3 random element from the sequence.
# Out: ['Ho', 'He', 'Hi']
print(random.sample(laughs, 4))
# Output may vary!
# Take 4 random element from the 3-item sequence.
ValueError: Muestra más grande que la población
Creación de enteros y flotadores aleatorios: randint, randrange, random y 
uniform
randint ()
Devuelve un entero aleatorio entre x y y (inclusive):
Por ejemplo obteniendo un número aleatorio entre 1 y 8 :
randrange ()
random.randrange tiene la misma sintaxis que range y, a diferencia de random.randint , el último valor
no es inclusivo:
    717/1068
    653
random.random() # Out: 0.66486093215306317
random.uniform(1, 8) # Out: 3.726062641730108
aleatorio
Devuelve un número de punto flotante aleatorio entre 0 y 1:
uniforme
Devuelve un número de punto flotante aleatorio entre x y y (inclusive):
Números aleatorios reproducibles: semilla y estado
Establecer una semilla específica creará una serie fija de números aleatorios:
    718/1068
    654
random.seed(5) # Reset the random module to the same fixed state. 
print(random.randrange(0, 10))
# Out: 9
print(random.randrange(0, 10))
# Out: 4
save_state = random.getstate() # Get the current state 
print(random.randrange(0, 10))
# Out: 5
print(random.randrange(0, 10))
# Out: 8
random.setstate(save_state) # Reset to saved state 
print(random.randrange(0, 10))
# Out: 5
print(random.randrange(0, 10))
# Out: 8
random.seed(None)
random.seed()
Restablecer la semilla creará la misma secuencia "aleatoria" de nuevo:
Dado que la semilla está fija, estos resultados son siempre 9 y 4 .Si no es necesario tener 
números específicos solo que los valores serán los mismos, también puede usar getstate y 
setstate para recuperar un estado anterior:
Para pseudoaleatorizar de nuevo la secuencia, se seed con None :
O llame al método seed sinargumentos:
Crear números aleatorios criptográficamente seguros
Por defecto, el módulo aleatorio de Python usa el PRNG Mersenne Twister para generar números 
aleatorios que, aunque son adecuados en dominios como simulaciones, no cumplen con los 
requisitos de seguridad en entornos más exigentes.
Para crear un número pseudoaleatorio seguro criptográficamente, se puede usar SystemRandom
que, mediante el uso de os.urandom , puede actuar como un generador de número pseudoaleatorio 
seguro criptográficamente, CPRNG .
La forma más fácil de usarlo consiste simplemente en inicializar la clase SystemRandom . Los 
métodos proporcionados son similares a los exportados por el módulo aleatorio.
random.seed(5) # Create a fixed state 
print(random.randrange(0, 10)) # Get a random integer between 0 and 9 
# Out: 9
print(random.randrange(0, 10))
# Out: 4
    719/1068
    655
print([secure_rand_gen.randrange(10) for i in range(10)]) 
# [9, 6, 9, 2, 2, 3, 8, 0, 9, 9]
print(secure_rand_gen.randint(0, 20))
# 5
from string import punctuation, ascii_letters, digits
symbols = ascii_letters + digits + punctuation
secure_random = random.SystemRandom()
password = "".join(secure_random.choice(symbols) for i in range(10)) 
print(password) # '^@g;J?]M6e'
Paracrearunasecuenciaaleatoriade10int senelrango[0, 20],simplementesepuedellamar 
a randrange() :
Para crear un entero aleatorio en un rango dado, uno puede usar randint :
y, en consecuencia para todos los demás métodos. La interfaz es exactamente la misma, el único 
cambio es el generador de números subyacente.
También puede usar os.urandom directamente para obtener bytes aleatorios criptográficamente 
seguros.
Creando una contraseña de usuario aleatoria
Paracrearunacontraseñade usuarioaleatoria,podemosutilizarlos símbolosproporcionadosen 
el módulo de string . Específicamente punctuation para los símbolos de puntuación, ascii_letters 
para las cartas y digits para dígitos:
Luego podemos combinar todos estos símbolos en un nombre llamado symbols :
Elimine cualquiera de estos para crear un conjunto de símbolos con menos elementos.
Después de esto, podemos usar random.SystemRandom para generar una contraseña. Para una 
contraseña de 10 longitudes:
Tenga en cuenta que otras rutinas puestos a disposición de inmediato por el random módulo
- como random.choice , random.randint , etc. - no son adecuados para los propósitos 
criptográficos.
Detrás de las cortinas, estas rutinas utilizan el PRNG de Mersenne Twister , que no satisface los 
requisitos de un CSPRNG . Por lo tanto, en particular, no debe usar ninguno de ellos para generar 
contraseñas que planea usar. Siempre use una instancia de SystemRandom como se muestra arriba.
from random import SystemRandom 
secure_rand_gen = SystemRandom()
    720/1068
    656
import string
alphabet = string.ascii_letters + string.digits 
while True:
password =''.join(choice(alphabet)fori in range(10)) 
if (any(c.islower() for c in password)
and any(c.isupper() for c in password)
and sum(c.isdigit() for c in password) >= 3): 
break
import random 
probability = 0.3
if random.random() < probability: 
print("Decision with probability 0.3")
else:
print("Decision with probability 0.7")
Python 3.x 3.6
A partir de Python 3.6, el módulo de secrets está disponible, lo que expone la funcionalidad 
criptográficamente segura.
Al citar la documentación oficial , para generar "una contraseña alfanumérica de diez caracteres 
con al menos un carácter en minúscula, al menos un carácter en mayúscula y al menos tres 
dígitos" , podría:
Decisión Binaria Aleatoria
    721/1068
    657
import asyncio
async def main(): 
print(await func())
async def func():
# Do time intensive stuff... 
return "Hello, world!"
if name == " main ":
loop = asyncio.get_event_loop() 
loop.run_until_complete(main())
import asyncio
@asyncio.coroutine 
def main():
print((yield from func()))
@asyncio.coroutine 
def func():
# Do time intensive stuff.. 
return "Hello, world!"
if name == " main ":
loop = asyncio.get_event_loop() 
loop.run_until_complete(main())
Capítulo 129: Módulo asyncio
Examples
Sintaxis de Coroutine y Delegación
Antes de que se lanzara Python asyncio , el módulo asyncio usaba generadores para imitar las 
llamadas asíncronas y, por lo tanto, tenía una sintaxis diferente a la versión actual de Python 3.5.
Python 3.x 3.5
Python 3.5 introdujo el async y await palabras clave. Tenga en cuenta la falta de paréntesis 
alrededor de la llamada await func() .
Python 3.x 3.3 3.5
Antesde Python 3.5, el decorador @asyncio.coroutine se usabaparadefinir unacoroutine. El 
rendimientodelaexpresiónseusóparaladelegacióndelgenerador.Notelosparéntesis 
alrededor del yield from func() .
Python 3.x 3.5
Aquí hay un ejemplo que muestra cómo dos funciones pueden ejecutarse de forma asíncrona:
    722/1068
    658
import asyncio
from concurrent.futures import ThreadPoolExecutor
def func(a, b):
# Do time intensive stuff... 
return a + b
async def main(loop):
executor = ThreadPoolExecutor()
result = await loop.run_in_executor(executor, func, "Hello,", " world!") 
print(result)
if name == " main ":
loop = asyncio.get_event_loop() 
loop.run_until_complete(main(loop))
import asyncio
from concurrent.futures import ThreadPoolExecutor
def func(a, b):
# Do time intensive stuff... 
return a + b
Ejecutores asincronos
Nota: utiliza la sintaxis de Python 3.5+ async / await
asyncio admite el uso de objetos Executor que se encuentran en concurrent.futures para 
programar tareas de formaasíncrona. Losbuclesdeeventostienen la función run_in_executor() 
que toma un objeto Executor , un Callable y los parámetros del Callable.
Programando una tarea para un Executor
CadaciclodeeventostambiéntieneunaranuradeExecutor"predeterminada"quesepuede 
asignar a un Executor . Para asignar un Executor y programar tareas desde el bucle, utiliceel 
método set_default_executor() .
import asyncio
async def cor1(): 
print("cor1 start") 
for i in range(10):
await asyncio.sleep(1.5) 
print("cor1", i)
async def cor2(): 
print("cor2 start") 
for i in range(15):
await asyncio.sleep(1) 
print("cor2", i)
loop = asyncio.get_event_loop()
cors = asyncio.wait([cor1(), cor2()]) 
loop.run_until_complete(cors)
    723/1068
    659
import asyncio 
import uvloop
if name == " main ": 
asyncio.set_event_loop(uvloop.new_event_loop()) 
# Do your stuff here ...
import asyncio 
import uvloop
if name == " main ": 
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) 
loop = asyncio.new_event_loop()
Hay dos tipos principales de Executor en concurrent.futures , ThreadPoolExecutor y 
ProcessPoolExecutor . ThreadPoolExecutor contiene unconjunto desubprocesosque sepueden 
establecer manualmenteenunnúmeroespecífico desubprocesosatravésdel constructoropor 
defectoelnúmerodenúcleos enlostiemposdelamáquina 5.ElThreadPoolExecutorutilizael 
conjuntodesubprocesos paraejecutartareasasignadasa él Engeneral, esmejor en 
operaciones vinculadasa laCPU en lugarde operaciones vinculadasdeE /S Contraste esocon 
el ProcessPoolExecutor que genera un nuevo proceso para cada tarea asignada.
ProcessPoolExecutor solo puede tomar tareas y parámetros que son seleccionables. Las tareas no 
recolectables más comunes son los métodos de los objetos. Si debe programar el método de un 
objeto como una tarea en un Executor , debe usar un ThreadPoolExecutor .
Usando UVLoop
uvloop esunaimplementaciónparaasyncio.AbstractEventLoop basadaenlibuv(utilizadapor 
nodejs).Cumpleconel99%deasyncio funcionesdeasyncio yesmuchomásrápidoqueel 
asyncio.EventLoop tradicional. asyncio.EventLoop . uvloop actualmente no está disponible en 
Windows, instálelo con pip install uvloop .
También se puede cambiar la fábrica de bucles de eventos configurando EventLoopPolicy a la de
uvloop .
Primitiva de sincronización: Evento
Concepto
async def main(loop):
# NOTE: Using `None` as the first parameter designates the `default` Executor. 
result = await loop.run_in_executor(None, func, "Hello,", " world!") 
print(result)
if name == " main ":
loop = asyncio.get_event_loop() 
loop.set_default_executor(ThreadPoolExecutor()) 
loop.run_until_complete(main(loop))
    724/1068
    660
import asyncio
# event trigger function 
def trigger(event):
print('EVENT SET')
event.set() # wake up coroutines waiting
# event consumers
async def consumer_a(event): 
consumer_name = 'Consumer A'
print('{} waiting'.format(consumer_name)) 
await event.wait()
print('{} triggered'.format(consumer_name))
async def consumer_b(event): 
consumer_name = 'Consumer B'
print('{} waiting'.format(consumer_name)) 
await event.wait()
print('{} triggered'.format(consumer_name))
# event
event = asyncio.Event()
# wrap coroutines in one future
main_future = asyncio.wait([consumer_a(event),
consumer_b(event)])
# event loop
event_loop = asyncio.get_event_loop()
event_loop.call_later(0.1, functools.partial(trigger, event)) # trigger event in 0.1 sec
# complete main_future
done, pending = event_loop.run_until_complete(main_future)
Utilice un Event para sincronizar la programación de múltiples coroutines .
En pocas palabras, un evento es como el disparo en una carrera: permite que los corredores 
salgan de los bloques de salida.
Ejemplo
Salida:
Consumidor B en espera 
Consumidor A esperando 
SET DE EVENTOS
Consumidor B activado 
Consumidor A activado
Un simple websocket
Aquí hacemos un simple websocket eco utilizando asyncio . Definimos las rutinas para conectarse 
a un servidor y enviar / recibir mensajes. Las comunicaciones del websocket se ejecutan en una
    725/1068
    661
if name == ' main ': #
The main loop
loop = asyncio.get_event_loop() 
loop.run_until_complete(main())
# "Hello World!"
async def main():
echo = EchoWebsocket() 
await echo.connect()
await echo.send("Hello World!")
print(await echo.receive())
async def connect(self):
self.websocket = await session.ws_connect("wss://echo.websocket.org")
async def send(self, message): 
self.websocket.send_str(message)
async def receive(self):
result = (await self.websocket.receive()) 
return result.data
# handles the context manager
import asyncio 
import aiohttp
session = aiohttp.ClientSession() 
class EchoWebsocket:
rutina main , que se ejecuta mediante un bucle de eventos. Este ejemplo es modificado de una 
publicación anterior .
Error común sobre asyncio
Probablemente, la idea errónea más común acerca de asnycio es que le permite ejecutar 
cualquier tarea en paralelo: eludir el GIL (bloqueo global del intérprete) y, por lo tanto, ejecutar 
trabajos de bloqueo en paralelo (en subprocesos separados). no lo hace!
asyncio (y las bibliotecas creadas para colaborar con asyncio ) se basan en coroutines: funciones 
que (en colaboración) devuelven el flujo de control a la función de llamada. asyncio.sleep en 
cuenta asyncio.sleep en los ejemplos anteriores. este es un ejemplo de una coroutina no 
bloqueanteque espera 'en el fondo' y devuelveel flujode control ala función de llamada (cuando 
se llama con await ). time.sleep es un ejemplo de una función de bloqueo. el flujo de ejecución del 
programa se detendrá allí y solo regresará después de que time.sleep hayaterminado.
un ejemplo real es la biblioteca de requests que consiste (por el momento) solo en funciones de 
bloqueo. no hay concurrencia si llama a cualquiera de sus funciones dentro de asyncio . aiohttp
por otro lado fue construido con asyncio en mente. sus coroutines correrán concurrentemente.
• Si tiene tareas vinculadas a la CPU de larga ejecución que le gustaría ejecutar en paralelo,
asyncio no es para usted. Para eso necesitas threads o multiprocessing .
• Si tiene trabajos en ejecución enlazados a IO, puede ejecutarlos simultáneamente usando
asyncio .
    726/1068
    662
    727/1068
    663
from Queue import Queue 
question_queue = Queue()
for x in range(1,10): 
temp_dict = ('key', x)
question_queue.put(temp_dict)
while(not question_queue.empty()): 
item = question_queue.get() 
print(str(item))
('key', 1)
('key', 2)
('key', 3)
('key', 4)
('key', 5)
('key', 6)
('key', 7)
('key', 8)
('key', 9)
Capítulo 130: Módulo de cola
Introducción
El módulo Queue implementa colas multi-productor, multi-consumidor. Es especialmente útil en la 
programación de subprocesos cuando la información se debe intercambiar de forma segura entre 
varios subprocesos. Hay tres tipos de colas que proporciona el módulo de colas, que son las 
siguientes: 1. Cola 2. LifoQueue 3. Excepción de PriorityQueue que podría venir: 1. Completa 
(desbordamiento de cola) 2. Vacía (desbordamiento de cola)
Examples
Ejemplo simple
Salida:
    728/1068
    664
import collections
counts = collections.Counter([1,2,3])
>>> collections.Counter('Happy Birthday')
Counter({'a': 2, 'p': 2, 'y': 2, 'i': 1, 'r': 1, 'B': 1, ' ': 1, 'H': 1, 'd': 1, 'h': 1, 't':
1})
Capítulo 131: Módulo de colecciones
Introducción
El paquete de collections incorporado proporciona varios tipos de colección flexibles y 
especializados que tienenun alto rendimientoy ofrecen alternativas a los tipos de colección 
generales de dict , list ,tupley set .El módulo también define clases básicas abstractas que 
describen diferentes tipos de funcionalidad de colección (como MutableSet y ItemsView ).
Observaciones
Hay otros tres tipos disponibles en el módulo de colecciones , a saber:
1. UserDict
2. Lista de usuarios
3. UserString
Cada una de ellas actúa como una envoltura alrededor del objeto atado, por ejemplo, UserDict 
actúa como una envoltura alrededor de un objeto dict . En cada caso, la clase simula su tipo 
nombrado. El contenido de la instancia se mantiene en un objeto de tipo regular, al que se puede 
acceder a través del atributo de datos de la instancia de contenedor. En cada uno de estos tres 
casos, la necesidad de estos tipos ha sido parcialmente suplantada por la capacidad de 
subclasificar directamente del tipo básico; sin embargo, puede ser más fácil trabajar con la clase 
contenedora porque el tipo subyacente es accesible como un atributo.
Examples
colecciones.
Contador es una subclase de dict que le permite contar objetos fácilmente. Tiene métodos de 
utilidad para trabajar con las frecuencias de los objetos que está contando.
elcódigoanterior crea un objeto, cuenta, que tienelas frecuenciasdetodos loselementos 
pasados al constructor. Este ejemplo tiene el valor Counter({1: 1, 2: 1, 3: 1})
Ejemplos de constructor
Contador de cartas
    729/1068
    665
>>> collections.Counter('I am Sam Sam I am That Sam-I-am That Sam-I-am! I do not like that 
Sam-I-am'.split())
Counter({'I': 3, 'Sam': 2, 'Sam-I-am': 2, 'That': 2, 'am': 2, 'do': 1, 'Sam-I-am!': 1, 'that':
1, 'not': 1, 'like': 1})
>>> c = collections.Counter({'a': 4, 'b': 2, 'c': -2, 'd': 0})
>>> c['a'] 
4
>>> c['c'] = -3
>>> c
Counter({'a': 4, 'b': 2, 'd': 0, 'c': -3})
>>> sum(c.itervalues()) # negative numbers are counted! 
3
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
>>> c - collections.Counter() 
Counter({'a': 4, 'b': 2})
>>> c.clear()
>>> c
Counter()
>>> c.update({'a': 3, 'b':3})
>>> c.update({'a': 2, 'c':2}) # adds to existing, sets if they don't exist
>>> c
Counter({'a': 5, 'b': 3, 'c': 2})
>>> c.subtract({'a': 3, 'b': 3, 'c': 3}) # subtracts (negative values are allowed)
Contador de palabras
Recetas
Consigue la cuenta del elemento individual.
Establecer la cuenta del elemento individual
Obtener el número total de elementos en el contador (4 + 2 + 0 - 3)
Obtener elementos (solo se mantienen los que tienen un contador positivo)
Eliminar claves con 0 o valor negativo.
Quitar todo
Añadir eliminar elementos individuales
    730/1068
    666
>>> state_capitals = collections.defaultdict(str)
>>> state_capitals 
defaultdict(<class 'str'>, {})
>>> str() 
''
>>> int() 
0
>>> list 
[]
>>> state_capitals['Alaska'] 
''
>>> state_capitals
defaultdict(<class 'str'>, {'Alaska': ''})
>>> fruit_counts = defaultdict(int)
>>> fruit_counts['apple'] += 2 # No errors should occur
>>> fruit_counts 
default_dict(int, {'apple': 2})
>>> fruit_counts['banana'] # No errors should occur 
0
>>> fruit_counts # A new key is created 
default_dict(int, {'apple': 2, 'banana': 0})
>>> state_capitals['Alabama'] = 'Montgomery'
>>> state_capitals
defaultdict(<class 'str'>, {'Alabama': 'Montgomery', 'Alaska': ''})
colecciones.defaultdict
collections.defaultdict (default_factory) devuelve una subclase de dict que tiene un valor 
predeterminado para las claves que faltan. El argumento debe ser una función que devuelve el 
valor predeterminado cuando se llama sin argumentos. Si no se pasa nada, el valor 
predeterminado es None .
devuelve una referencia a un defaultdict que creará un objeto de cadena con su método 
default_factory.
Un uso típico de defaultdict es usar uno de los tipos incorporados como str , int , list o dict
como default_factory, ya que estos devuelven tipos vacíos cuando se les llama sin argumentos:
Llamar al valor predeterminado con una clave que no existe no produce un error como lo haría en 
un diccionario normal.
Otroejemploconint:
Los métodos de diccionario normales funcionan con el diccionario predeterminado
>>> c
Counter({'a': 2, 'b': 0, 'c': -1})
    731/1068
    667
>>> s = [('NC', 'Raleigh'), ('VA', 'Richmond'), ('WA', 'Seattle'), ('NC', 'Asheville')]
>>> dd = collections.defaultdict(list)
>>> for k, v in s:
... dd[k].append(v)
>>> dd
defaultdict(<class 'list'>,
{'VA': ['Richmond'],
'NC': ['Raleigh', 'Asheville'],
'WA': ['Seattle']})
>>> d = {'foo': 5, 'bar': 6}
>>> print(d)
{'foo': 5, 'bar': 6}
>>> d['baz'] = 7
>>> print(a)
{'baz': 7, 'foo': 5, 'bar': 6}
>>> d['foobar'] = 8
>>> print(a)
{'baz': 7, 'foo': 5, 'bar': 6, 'foobar': 8}
```
>>> from collections import OrderedDict
>>> d = OrderedDict([('foo', 5), ('bar', 6)])
>>> print(d)
OrderedDict([('foo', 5), ('bar', 6)])
>>> d['baz'] = 7
>>> print(d)
OrderedDict([('foo', 5), ('bar', 6), ('baz', 7)])
>>> d['foobar'] = 8
>>> print(d)
OrderedDict([('foo', 5), ('bar', 6), ('baz', 7), ('foobar', 8)])
El uso de list como default_factory creará una lista para cada nueva clave.
colecciones.OrdenedDict
El orden de las claves en los diccionarios de Python es arbitrario: no se rigen por el orden en el 
que se agregan.
Por ejemplo:
(El orden arbitrario implícito arriba significa que puede obtener resultados diferentes con el código 
anterior al que se muestra aquí).
El orden en que aparecen las teclas es el orden en el que se iterarían, por ejemplo, utilizando un 
bucle for .
La clase collections.OrderedDict proporciona objetos de diccionario que conservan el orden de las 
claves. OrderedDict sse puedecrear comose muestraa continuaciónconunaserie deartículos 
ordenados (aquí, una lista de pares clave-valor de tupla):
O podemos crear un OrderedDict vacío y luego agregar elementos:
    732/1068
    668
>>> d['foo'] = 4
>>> print(d)
OrderedDict([('foo', 4), ('bar', 6), ('baz', 7), ('foobar', 8)])
Person = namedtuple('Person', ['age', 'height', 'name'])
Person = namedtuple('Person', 'age, height, name')
Person = namedtuple('Person', 'age height name')
dave = Person(30, 178, 'Dave')
jack = Person(age=30, height=178, name='Jack S.')
print(jack.age) # 30 
print(jack.name) # 'Jack S.'
La OrderedDict través de un OrderedDict permite el acceso de claves en el orden en que se 
agregaron.
¿Qué sucede si asignamos un nuevo valor a una clave existente?
La clave conserva su lugar original en el OrderedDict .
colecciones.namedu tupla
Defina un nuevo tipo de Person usando namedtuple como este:
El segundo argumento es la lista de atributos que tendrá la tupla. También puede enumerar estos 
atributos como espacios o cadenas separadas por comas:
o
Una vez definido, se puede crear una instancia de una tupla con nombre llamando al objeto con 
los parámetros necesarios, por ejemplo:
Los argumentos con nombre también se pueden utilizar:
Ahora puedes acceder a los atributos de la pareja nombrada:
Elprimerargumentoparaelconstructordeelementosnombrados(ennuestroejemplo'Person') 
esel typename .Estípicousarlamismapalabraparaelconstructoryelnombretipográfico,pero
>>> o = OrderedDict()
>>> o['key1'] = "value1"
>>> o['key2'] = "value2"
>>> print(o)
OrderedDict([('key1', 'value1'), ('key2', 'value2')])
    733/1068
    669
Human = namedtuple('Person', 'age, height, name') 
dave = Human(30, 178, 'Dave')
print(dave) # yields: Person(age=30, height=178, name='Dave')
#return and remove the leftmost item 
# list the contents of the deque
# peek at leftmost item
>>>d.pop() # return and remove the rightmost item
'j'
>>> d.popleft() 
'f'
>>> list(d) 
['g', 'h', 'i']
>>> d[0]
'g'
... print elem.upper() 
G
H 
I
>>> d.append('j') # add a new entry to the right side
>>> d.appendleft('f') # add a new entry to the left side
>>>d # show the representation of the deque 
deque(['f', 'g', 'h', 'i', 'j'])
# make a new deque with three items 
# iterate over the deque's elements
>>> from collections import deque
>>> d = deque('ghi')
>>> for elem in d:
pueden ser diferentes:
colecciones.deque
Devuelve unnuevo objeto deque inicializado de izquierdaa derecha (utilizando append ()) con 
datos de iterable. Si iterable no está especificado, el nuevo deque está vacío.
Deques es una generalización de pilas y colas (el nombre se pronuncia "deck" y es la abreviatura 
de "cola doble"). Deques es compatible con subprocesos seguros y eficientes con la memoria y 
hace estallar desde cualquier lado del deque con aproximadamente el mismo rendimiento O (1) en 
cualquier dirección.
Aunque los objetos de la lista admiten operaciones similares, están optimizados para operaciones 
rápidas de longitud fija e incurren en costos de movimiento de memoria O (n) para operaciones 
pop (0) e insertar (0, v) que cambian el tamaño y la posición de la representación de datos 
subyacente .
Nuevo en la versión 2.4.
Si maxlen no está especificado o es None , los deques pueden crecer hasta una longitud arbitraria. 
De lo contrario, el deque se limita a la longitud máxima especificada. Una vez que el deque longitud 
acotada está lleno, cuando se agregan nuevos elementos, un número correspondiente de 
elementos se descarta del extremo opuesto. Los deques de longitud limitada proporcionan una 
funcionalidad similar al filtro de cola en Unix. También son útiles para rastrear transacciones y 
otros grupos de datos donde solo interesa la actividad más reciente.
Cambiado en la versión 2.6: Se agregó el parámetro maxlen.
    734/1068
    670
Fuente: https://docs.python.org/2/library/collections.html
colecciones.ChainMap
ChainMap es nuevo en la versión 3.3
Devuelve un nuevo objeto ChainMap dado un número de maps . Este objeto agrupa varios dicts u 
otras asignaciones para crear una vista única y actualizable.
ChainMap son útiles para administrar contextos y superposiciones anidadas. Un ejemplo en el 
mundo de python se encuentra en la implementación de la clase de Context en el motor de 
plantillas de Django. Es útil para vincular rápidamente varias asignaciones para que el resultado 
se pueda tratar como una sola unidad. A menudo es mucho más rápido que crear un nuevo 
diccionario y ejecutar varias llamadas de update() .
Cada vez que uno tiene una cadena de valores de búsqueda, puede haber un caso para ChainMap
. Un ejemplo incluye tener valores especificados por el usuario y un diccionario de valores 
predeterminados. Otro ejemplo son los mapas de parámetros POST y GET que se encuentran en el 
uso web, por ejemplo, Django o Flask. Mediante el uso de ChainMap uno devuelve una vista 
combinada de dos diccionarios distintos.
La lista de parámetros de maps se ordena desde la primera búsqueda hasta la última búsqueda. 
Las búsquedas buscan sucesivamente las asignaciones subyacentes hasta que se encuentra una 
clave. Por el contrario, las escrituras, actualizaciones y eliminaciones solo funcionan en la primera
>>> d.extendleft('abc') # extendleft() reverses the input order
>>> d
deque(['c', 'b', 'a'])
File "<pyshell#6>", line 1, in -topleveld.pop()
IndexError: pop from an empty deque
#makeanewdequeinreverseorder
# empty the deque
# cannot pop from an empty deque
>>> deque(reversed(d)) 
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear()
>>> d.pop()
Traceback (most recent call last):
>>> d.rotate(-1) # left rotation
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1) # right rotation
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
deque(['g', 'h', 'i', 'j', 'k','l'])
# list the contents of a deque in reverse 
# search the deque
# add multiple elements at once
>>>list(reversed(d)) 
['i', 'h', 'g']
>>> 'h' in d 
True
>>> d.extend('jkl')
>>> d
>>> d[-1] # peek at rightmost item
'i'
    735/1068
    671
import collections
# define two dictionaries with at least some keys overlapping. 
dict1 = {'apple': 1, 'banana': 2}
dict2 = {'coconut': 1, 'date': 1, 'apple': 3}
# create two ChainMaps with different ordering of those dicts. 
combined_dict = collections.ChainMap(dict1, dict2) 
reverse_ordered_dict = collections.ChainMap(dict2, dict1)
for k, v in combined_dict.items(): 
print(k, v)
date 1
apple 1
banana 2
coconut 1
for k, v in reverse_ordered_dict.items(): 
print(k, v)
date 1
apple 3
banana 2
coconut 1
asignación.
Tenga en cuenta el impacto del orden en el que el valor se encuentra primero en la búsqueda 
posterior
    736/1068
    672
>>> from functools import partial
>>> unhex = partial(int, base=16)
>>> unhex. doc = 'Convert base16 string to int'
>>> unhex('ca11ab1e') 
3390155550
In [2]: from functools import partial
In [3]: def f(a, b, c, x):
...: return 1000*a + 100*b + 10*c + x
...:
In [4]: g = partial(f, 1, 1, 1) 
In [5]: print g(2)
1112
@total_ordering
Capítulo 132: Módulo de funciones
Examples
parcial
La función partial crea una aplicación de función parcial desde otra función. Se utiliza para 
vincular valores a algunos de los argumentos de la función (o argumentos de palabras clave) y 
producir una llamada sin los argumentos ya definidos.
partial() , como su nombre indica, permite una evaluación parcial de una función. Veamos el 
siguiente ejemplo:
Cuandosecreag,f,quetomacuatroargumentos( a, b, c, x),tambiénseevalúaparcialmente 
paralosprimerostresargumentos, a, b, c,Evaluacióndefsecompletacuandogesllamado, 
g(2) , que pasa el cuarto argumento a f .
Una forma de pensar en partial es un registro de desplazamiento; empujando en un argumento 
en el momento en alguna función. partial es útil para los casos en que los datos entran como 
flujo y no podemos pasar más de unargumento.
ordenamiento total
Cuando queremos crear una clase ordenable, normalmente necesitamos definir los métodos
 eq() , lt () , le () , gt () y ge ().
Eldecoradordetotal_ordering,aplicadoaunaclase,permiteladefinicióndeeq()ysolouno 
entre lt () , le () , gt () y ge () , y aún permite todas las operaciones de 
ordenamiento en la clase.
    737/1068
    673
from functools import reduce 
def factorial(n):
return reduce(lambda a, b: (a*b), range(1, n+1))
@lru_cache(maxsize=None) # Boundless cache 
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
>>> fibonacci(15)
El decorador utiliza una composición de los métodos proporcionados y las operaciones 
algebraicasparaderivarlosotrosmétodosdecomparación.Porejemplo,sidefinimos lt ()y
 eq() y queremos derivar gt () , simplemente podemos verificar not lt () and not
 eq() .
Nota : la función total_ordering solo está disponible desde Python 2.7.
reducir
EnPython 3.x, la función de reduce ya explicada aquí se ha eliminado de las funciones integradas 
y ahora debe importarse desde functools .
lru_cache
El decorador @lru_cache se puede usar para envolver una función costosa y de uso intensivo de 
computación con un caché deuso menos reciente .Estopermite quelas llamadas de funciónse 
memoricen, de modo que las llamadas futuras con los mismos parámetros puedan retornar 
instantáneamente en lugar de tener que volver a calcularse.
En el ejemplo anterior, el valor de fibonacci(3) solo se calcula una vez, mientras que si fibonacci 
no tuviera un caché LRU, fibonacci(3) se habría calculado más de 230 veces. Por lo tanto, 
@lru_cache es especialmente bueno para funciones recursivas o programación dinámica, donde 
unafunción costosa podría llamarse varias veces con los mismosparámetros exactos.
@lru_cache tiene dos argumentos
• maxsize : Número de llamadas a guardar. Cuando el número de llamadas únicas supera el
maxsize , el caché LRU eliminará las llamadas menos utilizadas recientemente.
• typed (agregado en 3.3): marca para determinar si los argumentos equivalentes de
class Employee:
...
def eq (self, other):
return ((self.surname, self.name) == (other.surname, other.name))
def lt (self, other):
return ((self.surname, self.name) < (other.surname, other.name))
    738/1068
    674
>>> fib.cache_info()
CacheInfo(hits=13, misses=16, maxsize=None, currsize=16)
diferentes tipos pertenecen a diferentes registros de caché (es decir, si 3.0 y 3 cuentan 
como argumentos diferentes)
Podemos ver las estadísticas de caché también:
NOTA :Ya que @lru_cache usa los diccionarios para almacenar en caché los resultados, todos los 
parámetros para la función deben estar habilitados para que la caché funcione.
Documentos oficiales de Python para @lru_cache . @lru_cache fue agregado en 3.2.
cmp_to_key
Python cambió sus métodos de clasificación para aceptar una función clave. Esas funciones 
toman un valor y devuelven una clave que se usa para ordenar las matrices.
Las antiguas funciones de comparación utilizadas para tomar dos valores y devolver -1, 0 o +1 si 
el primer argumento es pequeño, igual o mayor que el segundo argumento, respectivamente.
Esto es incompatible con la nueva función clave. 
Ahí es donde entra functools.cmp_to_key :
Ejemplo tomado y adaptado de la documentación de la biblioteca estándar de Python .
>>> import functools
>>> import locale
>>> sorted(["A", "S", "F", "D"], key=functools.cmp_to_key(locale.strcoll)) 
['A', 'D', 'F', 'S']
    739/1068
    675
x = 1.55
y = -1.55
# round to the nearest integer 
round(x) # 2
round(y) # -2
# the second argument gives how many decimal placesto round to (defaults to 0) 
round(x, 1) # 1.6
round(y, 1) # -1.6
#math is amodule so import it first, then use it. 
import math
# get the largest integer less than x 
math.floor(x) # 1
math.floor(y) # -2
# get the smallest integer greater than x 
math.ceil(x) # 2
math.ceil(y) # -1
# drop fractional part of x
math.trunc(x) # 1, equivalent to math.floor for positive numbers 
math.trunc(y) # -1, equivalent to math.ceil for negative numbers
round(1.3) # 1.0
round(0.5) # 1.0
round(1.5) # 2.0
Capítulo 133: Módulo de matemáticas
Examples
Redondeo: redondo, suelo, ceil, trunc
Ademásdela función roundincorporada, el módulo mathproporciona las funciones floor , ceil y
trunc .
Python 2.x 2.7
floor , el ceil , el trunc y el round siempre devuelven un float .
round siempre rompe empates lejos de cero.
Python 3.x 3.0
floor , ceil y trunc siempre devuelven un valor Integral , mientras que round devuelve un valor
Integral si se llama con un argumento.
    740/1068
    676
round(0.5) # 0
round(1.5) # 2
round(2.675, 2) # 2.67, not 2.68!
>>> math.floor(-1.7)
-2.0
>>> -5 // 2
-3
math.log(math.e) # 1.0
math.log(1) # 0.0
math.log(100) # 4.605170185988092
math.log(1 + 1e-20) # 0.0 
math.log1p(1e-20) # 1e-20
math.log10(10) # 1.0
Rupturas round empates hacia el número par más cercano.Esto corrige el sesgo hacia números 
más grandes cuando se realizan una gran cantidad de cálculos.
¡Advertencia!
Al igual que con cualquier representación de punto flotante, algunas fracciones no se pueden 
representar exactamente . Esto puede llevar a algún comportamiento de redondeo inesperado.
Advertencia sobre la división de números negativos en el piso, corte y 
número entero
Python (y C ++ y Java) se alejan de cero para los números negativos. Considerar:
Logaritmos
math.log(x) da el logaritmo natural (base e ) de x .
math.log puede perder precisión con números cercanos a 1, debido a las limitaciones de los 
números de punto flotante. Para calcular con precisión los registros cercanos a 1, use math.log1p , 
que evalúa el logaritmo natural de 1 más el argumento:
math.log10 puede usarse para logs base 10:
Python 2.x 2.3.0
Cuando se usa con dos argumentos, math.log(x, base) da el logaritmo de x en la base dada (es
round(1.33, 1) # 1.3
round(1.3) # 1
    741/1068
    677
math.log(100, 10) #2.0
math.log(27, 3) # 3.0
math.log(1, 10) # 0.0
math.hypot(2, 4) # Just a shorthand for SquareRoot(2**2 + 4**2) 
# Out: 4.47213595499958
math.radians(45) # Convert 45 degrees to radians
# Out: 0.7853981633974483
math.degrees(math.asin(1)) # Convert the result of asin to degrees
# Out: 90.0
# "= pi / 2"
math.asin(1)
# Out: 1.5707963267948966
math.asin(1)/ math.pi 
# Out: 0.5
# Sine of 90 degrees
# Sine and arc sine 
math.sin(math.pi / 2)
# Out: 1.0
math.sin(math.radians(90)) 
# Out: 1.0
decir, log(x) / log(base) .
Copiando carteles
En Python 2.6 y superior, math.copysign(x, y) devuelve x con el signo de y . El valor devuelto es 
siempre un float .
Python 2.x 2.6
math.copysign(-2, 3) # 2.0
math.copysign(3, -3) # -3.0
math.copysign(4, 14.2) # 4.0
math.copysign(1, -0.0) # -1.0, on a platform which supports signed zero
Trigonometría
Cálculo de la longitud de la hipotenusa.
Convertir grados a / desde radianes
Todas las funciones math esperan radianes, por lo que necesitas convertir grados a radianes:
Todos los resultados de las funciones trigonométricas inversas devuelven el resultado en 
radianes, por lo que es posible que deba volver a convertirlo en grados:
Funciones seno, coseno, tangente e inversa.
    742/1068
    678
math.atan(math.inf)
# Out: 1.5707963267948966 # This is just "pi / 2"
math.atan(float('inf'))
# Out: 1.5707963267948966 # This is just "pi / 2"
math.atan2(1, 2) # Equivalent to "math.atan(1/2)"
# Out: 0.4636476090008061 # ≈ 26.57 degrees, 1st quadrant
math.atan2(-1, -2) # Not equal to "math.atan(-1/-2)" == "math.atan(1/2)"
# Out: -2.677945044588987 # ≈ -153.43 degrees (or 206.57 degrees), 3rd quadrant
math.atan2(1, 0) # math.atan(1/0) would raise ZeroDivisionError 
# Out: 1.5707963267948966 # This is just "pi / 2"
# Hyperbolic sine function 
math.sinh(math.pi) # = 11.548739357257746 
math.asinh(1) # =0.8813735870195429
# Hyperbolic cosine function 
math.cosh(math.pi) # = 11.591953275521519 
math.acosh(1) # = 0.0
# Hyperbolic tangent function 
math.tanh(math.pi) # = 0.99627207622075 
math.atanh(0.5) # =0.5493061443340549
Python 3.x 3.5
Aparte de math.atan también hay una función math.atan2 dos argumentos, que calcula el cuadrante 
correcto y evita los escollos de la división por cero:
Seno hiperbólico, coseno y tangente.
Constantes
math módulos math incluyen dos constantes matemáticas de uso común.
• math.pi - La constante matemática pi
• math.e - La constante matemática e (base del logaritmo natural)
# Cosine and arc cosine:
math.cos(math.pi /2)
# Out: 6.123233995736766e-17
# Almost zero but not exactly because "pi" is a float with limited precision!
math.acos(1) 
# Out: 0.0
# Tangent and arc tangent:
math.tan(math.pi/2)
# Out: 1.633123935319537e+16
# Very large but not exactly "Inf" because "pi" is a float with limited precision
    743/1068
    679
pos_inf = math.inf 
neg_inf = -math.inf 
not_a_num = math.nan
math.inf == float('inf') 
# Out: True
-math.inf == float('-inf') 
# Out: True
# NaN never compares equal to anything, even itself 
math.nan == float('nan')
# Out: False
# Equivalent to the square root of -1. 
# = (-1+0j)
1j
1j * 1j
pos_inf = float('inf') # positive infinity 
neg_inf = float('-inf') # negative infinity 
not_a_num = float('nan') #NaN("notanumber")
pos_inf, neg_inf, not_a_num 
# Out: (inf, -inf, nan)
Python 3.5 y superiortienen constantespara infinito yNaN ("noes unnúmero"). La sintaxis 
anterior de pasar una cadena a float() aún funciona.
Python 3.x 3.5
Números imaginarios
Los números imaginarios en Python están representados por una "j" o "J" detrás del número 
objetivo.
Infinito y NaN ("no es un número")
En todas las versiones de Python, podemos representar infinito y NaN ("no un número") de la 
siguiente manera:
En Python 3.5 y superior, también podemos usar las constantes definidas math.inf y math.nan : 
Python 3.x 3.5
Las representaciones de cadena se muestran como inf y -inf y nan :
>>> from math import pi, e
>>> pi 
3.141592653589793
>>> e 
2.718281828459045
>>>
    744/1068
    680
math.isinf(pos_inf) 
# Out: True
math.isinf(neg_inf) 
# Out: True
neg_inf == float('-inf') # or ==-math.infinPython 3.5+ 
# Out: True
neg_inf == pos_inf 
# Out: False
pos_inf == float('inf') # or == math.inf in Python 3.5+
# Out: True
math.isfinite(pos_inf) 
# Out: False
math.isfinite(0.0) 
# Out: True
import sys
sys.float_info.max
# Out: 1.7976931348623157e+308 (this is system-dependent)
pos_inf > sys.float_info.max 
# Out: True
neg_inf < -sys.float_info.max 
# Out: True
pos_inf == sys.float_info.max * 1.0000001 
# Out: True
neg_inf == -sys.float_info.max * 1.0000001
# Out: True
Podemos probar el infinito positivo o negativo con el método isinf :
Podemos probar específicamente el infinito positivo o el infinito negativo por comparación directa:
Python 3.2 y superior también permite verificar la finitud:
Python 3.x 3.2
Los operadores de comparación funcionan como se espera para el infinito positivo y negativo:
Pero si una expresión aritmética produce un valor más grande que el máximo que se puede 
representar como un float , se convertirá en infinito:
Sinembargo, la divisiónpor cero no da un resultado de infinito (o infinito negativo cuando sea 
apropiado), sino que genera una excepción ZeroDivisionError .
    745/1068
    681
-5.0 * pos_inf == neg_inf 
# Out: True
-5.0 * neg_inf == pos_inf 
# Out: True
pos_inf * neg_inf == neg_inf 
# Out: True
0.0 * pos_inf 
# Out: nan
0.0 * neg_inf 
# Out: nan
pos_inf /pos_inf 
# Out: nan
not_a_num == not_a_num 
# Out: False
math.isnan(not_a_num) 
Out: True
not_a_num>5.0 or not_a_num < 5.0 or not_a_num == 5.0
# Out: False
not_a_num != 5.0 # or any random value 
# Out: True
5.0 * not_a_num 
# Out: nan
float('-nan') 
# Out: nan
Las operaciones aritméticas en el infinito solo dan resultados infinitos, o algunas veces NaN:
NaN nunca es igual a nada, ni siquiera a sí mismo. Podemos probar que es con el método isnan :
NaN siempre se compara como "no igual", pero nunca menor o mayor que:
Las operaciones aritméticas en NaN siempre dan NaN. Esto incluye la multiplicación por -1: no 
hay "NaN negativo".
Python 3.x 3.5
try:
x = 1.0 / 0.0
print(x)
except ZeroDivisionError: 
print("Division by zero")
# Out: Division by zero
    746/1068
    682
math.inf is math.inf, math.nan is math.nan 
# Out: (True, True)
float('inf') is float('inf'), float('nan') is float('nan') 
# Out: (False, False)
> python -m timeit 'for x in xrange(50000): b = x**3' 
10 loops, best of 3: 51.2 msec per loop
> python -m timeit 'from math import pow' 'for x in xrange(50000): b = pow(x,3)' 
100 loops, best of 3: 9.15 msec per loop
> from math import pow
> pow(5,5) 
3125.0
z = 1 + 3j
1j * 1j
Out: (-1+0j)
1j ** 1j
Hay una diferencia sutil entre las versiones float antiguas de NaN e infinito y las constantes de la 
biblioteca math Python 3.5+:
Python 3.x 3.5
Pow para una exponenciación más rápida
Usando el módulo timeit desde la línea de comando:
El operador ** integrado a menudo es útil, pero si el rendimiento es esencial, use math.pow. Sin 
embargo, asegúrese de tener en cuenta que pow devuelve flotantes, incluso si los argumentos 
son enteros:
Números complejos y el módulo cmath.
El módulo cmath es similar al módulo math , pero define funciones adecuadamente para el plano 
complejo.
En primer lugar, los números complejos son un tipo numérico que forma parte del lenguaje Python 
en lugar de ser proporcionado por una clase de biblioteca. Por lo tanto, no necesitamos import 
cmath para expresiones aritméticas ordinarias.
Tenga en cuenta que usamos j (o J ) y no i .
Debemos usar 1j ya que j sería el nombre de una variable en lugar de un literal numérico.
-math.nan 
# Out: nan
    747/1068
    683
# z.conjugate() == z.real - z.imag * 1j
z.conjugate() 
# Out: (1-3j)
# real part and imaginary part are bothfloat type 
z.real, z.imag
# Out: (1.0, 3.0)
complex(1)
# Out: (1+0j)
complex(imag=1) 
# Out: (1j)
complex(1, 1) 
# Out: (1+1j)
# square root of 2
abs(1 + 1j)
# Out: 1.4142135623730951
complex('1+1j') 
# Out: (1+1j)
complex('1 + 1j')
# Exception: ValueError: complex() arg is a malformed string
import cmath
cmath.sqrt(-1) 
# Out: 1j
import math
math.sqrt(-1)
# Exception: ValueError: math domain error
# == (sqrt(1 + 1), atan2(1, 1))
cmath.polar(1 + 1j)
# Out: (1.4142135623730951, 0.7853981633974483)
Tenemos la parte real y la parte imag (imaginaria), así como el complejo conjugate :
Lasfuncionesintegradasabs ycomplex tambiénsonpartedellenguajeensí ynorequieren 
ninguna importación:
La función complex puede tomar una cadena, pero no puede tener espacios:
Pero para la mayoría de las funciones necesitamos el módulo, por ejemplo, sqrt :
Naturalmente,el comportamiento de sqrt es diferente para números complejos y números reales. 
En math no complejas math la raíz cuadrada de un número negativo genera una excepción:
Se proporcionan funciones para convertir hacia y desde coordenadas polares:
# Out: (0.20787957635076193+0j) # "i to the i" == math.e ** -(math.pi/2)
    748/1068
    684
cmath.phase(complex(-1.0, 0.0))
# Out: 3.141592653589793
cmath.phase(complex(-1.0, -0.0))
# Out: -3.141592653589793
cmath.log(1+1j)
# Out: (0.34657359027997264+0.7853981633974483j)
cmath.exp(1j * cmath.pi)
#Out:(-1+1.2246467991473532e-16j) # e to the i pi == -1, within rounding error
type(cmath.pi)
# Out: <class 'float'>
cmath.isinf(complex(float('inf'), 0.0)) 
# Out: True
cmath.isnan(0.0, float('nan'))
El campo matemático del análisis complejo está más allá del alcance de este ejemplo, pero 
muchas funciones en el plano complejo tienen un "corte de rama", generalmente a lo largo del eje 
real o el eje imaginario. La mayoría de las plataformas modernas admiten el "cero firmado" como 
se especifica en IEEE 754, que proporciona continuidad de esas funciones en ambos lados del 
corte de rama. El siguiente ejemplo es de la documentación de Python:
El módulo cmath también proporciona muchas funciones con contrapartes directas del módulo math
.
Además de sqrt , existen versiones complejas de exp , log , log10 , las funciones trigonométricas y 
sus inverses ( sin , cos , tan , asin , acos , atan ), y las funciones hiperbólicas y sus inverses ( sinh , 
cosh , tanh , asinh , acosh , atanh ). Sin embargo, tenga en cuenta que no hay una contraparte 
compleja de math.atan2 , la forma de arctangente de dos argumentos.
Se proporcionan las constantes pi y e . Tenga en cuenta que estos son float y no complex .
El módulo cmath también proporciona versiones complejas de isinf , y (para Python 3.2+) es 
isfinite . Ver " Infinito y NaN ". Un número complejo se considera infinito si su parte real o su 
parte imaginaria es infinita.
Asimismo, el módulo cmath proporciona una versión compleja de isnan . Ver " Infinito y NaN ". Un 
número complejo se considera "no un número" si su parte real o su parte imaginaria no es "un 
número".
cmath.rect(math.sqrt(2), math.atan(1))
# Out: (1.0000000000000002+1.0000000000000002j)
# same as previous calculation
abs(1 + 1j), cmath.phase(1 + 1j)
# Out: (1.4142135623730951, 0.7853981633974483)
    749/1068
    685
z = cmath.rect(*cmath.polar(1+1j))
z
# Out: (1.0000000000000002+1.0000000000000002j)
cmath.isclose(z, 1+1j) 
# True
cmath.isinf(complex(0.0, math.inf)) 
# Out: True
cmath.isnan(complex(math.nan, 0.0)) 
# Out: True
cmath.inf
# Exception: AttributeError: module 'cmath' has no attribute 'inf'
Tenga en cuenta que no hay cmath contraparte de math.nan constantes math.inf y math.nan (de 
Python 3.5 y superior)
Python 3.x 3.5
EnPython 3.5 y superior, hay una isclose método en ambos cmath y math módulos. 
Python 3.x 3.5
# Out: True
    750/1068
    686
Capítulo 134: Módulo de navegador web
Introducción
De acuerdo con la documentación estándar de Python, el módulo del navegador web proporciona 
una interfaz de alto nivel para permitir la visualización de documentos basados en la Web a los 
usuarios. Este tema explica y demuestra el uso adecuado del módulo de navegador web.
Sintaxis
• webbrowser.open(url, new=0, autoraise=False)
• webbrowser.open_new(url)
• webbrowser.open_new_tab(url)
• webbrowser.get(usage=None)
• webbrowser.register(name, constructor, instance=None)
Parámetros
Parámetro Detalles
webbrowser.open()
url La URL para abrir en el navegador web.
nuevo
0 abre la URL en la pestaña existente, 1 abre en una nueva 
ventana, 2 abre en nueva pestaña
autoraise si se establece en Verdadero, la ventana se moverá sobre las 
otras ventanas
webbrowser.open_new()
url La URL para abrir en el navegador web.
webbrowser.open_new_tab()
url La URL para abrir en el navegador web.
webbrowser.get()
utilizando el navegador para usar
webbrowser.register()
url nombre del navegador
constructor ruta al navegador ejecutable ( ayuda )
ejemplo Una instancia de un navegador web devuelto por el método
    751/1068
    687
Parámetro Detalles
webbrowser.get()
Observaciones
Lasiguientetablaenumeralos tiposdenavegadorpredefinidos.Lacolumnadelaizquierda son 
nombres que se pueden pasar al método webbrowser.get() y la columna de la derecha enumera 
los nombres de clase para cada tipo de navegador.
Escribe un nombre Nombre de la clase
'mozilla' Mozilla('mozilla')
'firefox' Mozilla('mozilla')
'netscape' Mozilla('netscape')
'galeon' Galeon('galeon')
'epiphany' Galeon('epiphany')
'skipstone' BackgroundBrowser('skipstone')
'kfmclient' Konqueror()
'konqueror' Konqueror()
'kfm' Konqueror()
'mosaic' BackgroundBrowser('mosaic')
'opera' Opera()
'grail' Grail()
'links' GenericBrowser('links')
'elinks' Elinks('elinks')
'lynx' GenericBrowser('lynx')
'w3m' GenericBrowser('w3m')
'windows-default' WindowsDefault
'macosx' MacOSX('default')
'safari' MacOSX('safari')
'google-chrome' Chrome('google-chrome')
'chrome' Chrome('chrome')
'chromium' Chromium('chromium')
'chromium-browser' Chromium('chromium-browser')
    752/1068
    688
import webbrowser 
webbrowser.open("http://stackoverflow.com")
import webbrowser 
webbrowser.open_new("http://stackoverflow.com")
import webbrowser 
webbrowser.open_new_tab("http://stackoverflow.com")
import webbrowser
ff_path = webbrowser.get("C:/Program Files/Mozilla Firefox/firefox.exe") 
ff = webbrowser.get(ff_path)
ff.open("http://stackoverflow.com/")
Examples
Abrir una URL con el navegador predeterminado
Para abrir simplemente una URL, use el método webbrowser.open() :
Si una ventana del navegador está actualmente abierta, el método abrirá una nueva pestaña en la 
URL especificada. Si no hay ninguna ventana abierta, el método abrirá el navegador 
predeterminado del sistema operativo y navegará a la URL en el parámetro. El método abierto 
soporta los siguientes parámetros:
• url : la URL que se abrirá en el navegador web (cadena) [requerido]
• new : 0 se abre en la pestaña existente, 1 abre una nueva ventana, 2 abre una nueva 
pestaña (entero) [predeterminado 0]
• autoraise : si se establece en Verdadero, la ventana se moverá sobre las ventanas de otras 
aplicaciones (Booleano) [predeterminado Falso]
Tengaencuentaquelosargumentosnewyautoraise raravezfuncionan,yaquelamayoríadelos 
navegadores modernos rechazan estos comandos.
El navegador web también puede intentar abrir las URL en nuevas ventanas con el método
open_new :
Estemétodoescomúnmente ignoradoporlosnavegadores modernos y laURLgeneralmentese 
abre en una nueva pestaña.El módulo puede intentar abriruna nueva pestaña usando el método 
open_new_tab :
Abrir una URL con diferentes navegadores
El módulo del navegador web también admite diferentes navegadores que utilizan los métodos 
register() y get() . El método de obtención se usa para crear un controlador de navegador 
utilizando una ruta de archivo ejecutable específica y el método de registro se utiliza para adjuntar 
estos ejecutables a los tipos de navegador predeterminados para su uso futuro, generalmente 
cuando se usan múltiples tipos de navegador.
    753/1068
    689
import webbrowser
ff_path = webbrowser.get("C:/Program Files/Mozilla Firefox/firefox.exe") 
ff = webbrowser.get(ff_path)
webbrowser.register('firefox', None, ff)
# Now to refer to use Firefox in the future you can use this 
webbrowser.get('firefox').open("https://stackoverflow.com/")
Registro de un tipo de navegador:
    754/1068
    690
# p = 1, d = deque([2, 3])
# d = deque([5, 2, 3])
d = deque([1, 2, 3]) 
p = d.popleft()
d.appendleft(5)
from collections import deque
Capítulo 135: Módulo Deque
Sintaxis
• dq = deque () # Crea un deque vacío
• dq = deque (iterable) # Crea un deque con algunos elementos
• dq.append (objeto) # Agrega un objeto a la derecha del deque
• dq.appendleft (objeto) # Agrega un objeto a la izquierda del deque
• dq.pop () -> object # Elimina y devuelve el objeto más a la derecha
• dq.popleft () -> object # Elimina y devuelve el objeto más a la izquierda
• dq.extend (iterable) # Agrega algunos elementos a la derecha del deque
• dq.extendleft (iterable) # Agrega algunos elementos a la izquierda del deque
Parámetros
Parámetro Detalles
iterable Crea el deque con elementos iniciales copiados de otro iterable.
maxlen
Limita qué tan grande puede ser el deque, eliminando elementos antiguos a 
medida que se agregan nuevos.
Observaciones
Esta clase esútilcuando necesita un objeto similaraunalista que permitaoperaciones rápidas 
de agregar y abrir desde cualquier lado (el nombre deque significa " cola de doble extremo ").
Los métodos proporcionados son,de hecho, muy similares, excepto que algunos como el pop , el 
append o la extend pueden incluir con el sufijo left . La estructura de datos de deque debería ser 
preferible a una lista si uno necesita insertar y eliminar elementos con frecuencia en ambos 
extremos porque permite hacerlo en tiempo constante O (1).
Examples
Uso básico deque
Los principales métodos que son útiles con esta clase son popleft y appendleft
    755/1068
    691
from collections import deque
d = deque(maxlen=3) # only holds 3 items 
d.append(1) # deque([1])
d.append(2) # deque([1, 2])
d.append(3) # deque([1, 2, 3])
d.append(4) # deque([2, 3, 4]) (1 is removed because its maxlen is 3)
dl = deque() # deque([]) creating empty deque
dl = deque([1, 2, 3, 4]) # deque([1, 2, 3, 4])
dl.append(5) # deque([1, 2, 3, 4, 5])
dl.appendleft(0) # deque([0, 1, 2, 3, 4, 5])
dl.extend([6, 7]) # deque([0, 1, 2, 3, 4, 5, 6, 7])
dl.extendleft([-2, -1]) # deque([-1, -2, 0, 1, 2, 3, 4, 5, 6, 7])
dl.pop() # 7 => deque([-1, -2, 0, 1, 2, 3, 4, 5, 6])
dl.popleft() # -1 deque([-2, 0, 1, 2, 3, 4, 5, 6])
límite de tamaño de salida
Use el parámetro maxlen mientras crea un deque para limitar el tamaño del deque:
Métodos disponibles en deque.
Creando deque vacío:
Creando deque con algunos elementos:
Añadiendo elemento a deque:
Añadiendo elemento del lado izquierdo del deque:
Añadiendo lista de elementos a deque:
Añadiendo lista de elementos desde el lado izquierdo:
El uso del elemento .pop() eliminará naturalmente un elemento del lado derecho:
Usando el elemento .popleft() para eliminar un elemento del lado izquierdo:
Eliminar elemento por su valor:
    756/1068
    692
dl.reverse() # deque([6, 5, 4, 3, 2, 0, -2])
from collections import deque
def bfs(graph, root): 
distances = {} 
distances[root] = 0 
q = deque([root]) 
while q:
# The oldest seen (but not yet visited) node will be the left most one. 
current = q.popleft()
for neighbor in graph[current]: 
if neighbor not in distances:
distances[neighbor] = distances[current] + 1
# When we see a new node, we add it to the right side of the queue. 
q.append(neighbor)
return distances
graph = {1:[2,3], 2:[4], 3:[4,5], 4:[3,5], 5:[]}
>>> bfs(graph, 1)
{1: 0, 2: 1, 3: 1, 4: 2, 5: 2}
>>> bfs(graph, 3)
{3: 0, 4: 1, 5: 1}
Invertir el orden de los elementos en deque:
Amplia primera búsqueda
Deque es la única estructura de datos de Python con operaciones rápidas de cola . (Tenga en 
cuenta queue.Queue normalmente no es adecuado, ya que está destinado a la comunicación entre 
subprocesos). Un caso de uso básico de una cola es la primera búsqueda de amplitud .
Digamos que tenemos un gráfico dirigido simple:
Ahora podemos encontrar las distancias desde alguna posición inicial:
dl.remove(1) # deque([-2, 0, 2, 3, 4, 5, 6])
    757/1068
    693
lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 5, 6)]
testGroupBy(lst)
lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 2, 6)]
def testGroupBy(lst):
groups = itertools.groupby(lst, key=lambda x: x[1]) 
for key, group in groups:
print(key, list(group)) 
testGroupBy(lst)
# 5 [('a', 5, 6)]
# 2 [('b', 2, 4), ('a', 2, 5), ('c', 2, 6)]
lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 2, 6)]
groups = itertools.groupby(lst, key=lambda x: x[1]) 
for key, group in sorted(groups):
print(key, list(group))
# 2 [('c', 2, 6)]
# 5 []
Capítulo 136: Módulo Itertools
Sintaxis
• import itertools
Examples
Agrupando elementos de un objeto iterable usando una función
Comenzar con un iterable que necesita ser agrupado.
Genere el generador agrupado, agrupando por el segundo elemento en cada tupla:
Sólo se agrupan grupos de elementos consecutivos. Es posible que deba ordenar por la misma 
clave antes de llamar a groupby For Eg, (el último elemento ha cambiado)
# 5 [('a', 5, 6)]
# 2 [('b', 2, 4), ('a', 2, 5)]
# 5 [('c', 5, 6)]
El grupo devuelto por groupby es un iterador que no será válido antes de la próxima iteración. Por 
ejemplo, lo siguiente no funcionará si desea que los grupos se ordenen por clave. El grupo 5 está 
vacío a continuación porque cuando se busca el grupo 2 invalida 5
Para realizar correctamente la clasificación, cree una lista desde el iterador antes de ordenar
    758/1068
    694
results = fetch_paged_results() # returns a generator 
limit = 20 # Only want the first 20 results
for data in itertools.islice(results, limit): 
print(data)
def gen():
n = 0
while n < 20: 
n += 1
yield n
for part in gen()[:3]: 
print(part)
Traceback (most recent call last): 
File "gen.py",line 6, in <module>
for part in gen()[:3]:
TypeError: 'generator' object is not subscriptable
import itertools
def gen():
n = 0
while n < 20: 
n += 1
yield n
for part in itertools.islice(gen(), 3): 
print(part)
itertools.islice(iterable, 1, 30, 3)
Toma una rebanada de un generador
Itertools "islice" le permite cortar un generador:
Normalmente no se puede cortar un generador:
Daré
Sin embargo, esto funciona:
Tenga en cuenta que al igual que una división normal, también puede usar los argumentos de
start , stop y step :
groups = itertools.groupby(lst, key=lambda x: x[1])
for key, group in sorted((key, list(group)) for key, group in groups): 
print(key, list(group))
# 2 [('b', 2, 4), ('a', 2, 5), ('c', 2, 6)]
# 5 [('a', 5, 6)]
    759/1068
    695
for x in xrange(10):
for y in xrange(10): 
print x, y
its = [xrange(10)] * 2
for x,y in itertools.product(*its): 
print x, y
>>> from itertools import product
>>> a=[1,2,3,4]
>>> b=['a','b','c']
>>> product(a,b)
<itertools.product object at 0x0000000002712F78>
>>> for i in product(a,b):
... print i
...
(1, 'a')
(1, 'b')
(1, 'c')
(2, 'a')
(2, 'b')
(2, 'c')
(3, 'a')
(3, 'b')
(3, 'c')
(4, 'a')
(4, 'b')
(4, 'c')
itertools.product
Esta función le permite recorrer el producto cartesiano de una lista de iterables. 
Por ejemplo,
es equivalente a
Como todas las funciones de python que aceptan un número variable de argumentos, podemos 
pasar una lista a itertools.product para desempaquetar, con el operador *.
Así,
produce los mismos resultados que los dos ejemplos anteriores.
itertools.count
Introducción:
Esta simple función genera infinitas series de números. Por ejemplo...
for x, y in itertools.product(xrange(10), xrange(10)): 
print x, y
    760/1068
    696
for number in itertools.count(start=10, step=4): 
print(number)
if number > 20: 
break
10
14
18
22
def is_even(x): 
return x % 2 == 0
lst = [0, 2, 4, 12, 18, 13, 14, 22, 23, 44]
result = list(itertools.takewhile(is_even, lst)) 
print(result)
Tenga en cuenta que hay que romper o se imprime para siempre! 
Salida:
Argumentos:
count() toma dos argumentos, start y step :
Salida:
itertools.takewhile
itertools.takewhile le permite tomar elementos de una secuencia hasta que una condición se 
convierte en False .
Esto produce [0, 2, 4, 12, 18] .
0
1
2
3
4
5
6
7
8
9
10
for number in itertools.count(): 
if number > 20:
break 
print(number)
    761/1068
    697
def takewhile(predicate, iterable): 
for x in iterable:
if predicate(x): 
yield x
else:
break
def is_even(x): 
return x % 2 == 0
lst = [0, 2, 4, 12, 18, 13, 14, 22, 23, 44]
result = list(itertools.dropwhile(is_even, lst)) 
print(result)
def dropwhile(predicate, iterable): 
iterable = iter(iterable)
for x in iterable:
if not predicate(x): 
yield x
break 
for x in iterable:
yield x
Tengaencuentaque, el primer número que violael predicado (es decir,la funciónque devuelve 
un valor booleano) is_even is, 13 . Una vez que takewhile encuentra un valor que produce False 
para el predicado dado, se rompe.
La salida producida por takewhile es similar a la salida generada a partir del código siguiente.
Nota: La concatenación de los resultados producidos por takewhile y dropwhile produce el iterable 
original.
result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst))
itertools.dropwhile
itertools.dropwhile le permite tomar elementos de una secuencia después de que una condición 
se convierte en False .
Esto da como resultado [13, 14, 22, 23, 44] .
( Este ejemplo es el mismo que el de takewhile pero usando dropwhile) .
Tenga en cuenta que, el primer número que viola el predicado (es decir, la función que devuelve 
un valor booleano) is_even is, 13 . Todos los elementos antes de eso, se descartan.
La salida producida por dropwhile es similar a la salida generada a partir del código a 
continuación.
La concatenación de los resultados producidos por takewhile y dropwhile produce el iterable
    762/1068
    698
from itertools import zip_longest
a = [i for i in range(5)] # Length is 5
b = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] # Length is 7 
for i in zip_longest(a, b):
x, y = i # Note that zip longest returns the values as a tuple 
print(x, y)
for i in zip_longest(a, b, fillvalue='Hogwash!'):
x, y = i # Note that zip longest returns the values as a tuple 
print(x, y)
a = [1,2,3,4,5]
b = list(itertools.combinations(a, 2)) 
print b
a = [1,2,3,4,5]
b = list(itertools.combinations(a, 3))
original.
result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst))
Zipping dos iteradores hasta que ambos están agotados
Similar alafunción incorporada zip() , itertools.zip_longest continuará iterando más allá del final 
del más corto de los dos iterables.
Sepuedepasarunargumentodevalordefillvalue opcional(predeterminadoa'' )dela 
siguiente manera:
En Python 2.6 y 2.7, esta función se llama itertools.izip_longest .
Método de combinaciones en el módulo Itertools
itertools.combinations devolverá un generador de la secuencia de combinación k de una lista.
En otras palabras: devolverá un generador de tuplas de todas las combinaciones posibles de k 
de la lista de entrada.
Por ejemplo:
Si tienes una lista:
Salida:
[(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
Lasalidaanterioresun generador convertido auna lista de tuplas de todas las combinaciones 
posibles de pares de la lista de entradaa
También puedes encontrar todas las 3 combinaciones:
    763/1068
    699
from itertools import chain
a = (x for x in ['1', '2', '3', '4'])
b = (x for x in ['x', 'y', 'z']) 
' '.join(chain(a, b))
'1 2 3 4 x y z'
' '.join(chain.from_iterable([a,b])
>>> import itertools
>>> for i in itertools.repeat('over-and-over', 3):
... print(i) 
over-and-over 
over-and-over 
over-and-over
>>> import itertools as it
>>> import operator
Salida:
[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4),
(1, 3, 5), (1, 4, 5), (2, 3, 4), (2, 3, 5),
(2, 4, 5), (3, 4, 5)]
Encadenando múltiples iteradores juntos
Use itertools.chain para crear un solo generador que produzca los valores de varios 
generadores en secuencia.
Resultados en:
Como constructor alternativo, puede usar el método chain.from_iterable que toma como único 
parámetro un iterable de iterables. Para obtener el mismo resultado que arriba:
Mientras que chain puede tomar un número arbitrario de argumentos, chain.from_iterable es la 
única manera de encadenar un número infinito de iterables.
itertools.repeat
Repetir algo n veces:
Obtener una suma acumulada de números en un iterable
Python 3.x 3.2
accumulate rendimientos una suma acumulada (o producto) de números.
print b
    764/1068
    700
>>> import itertools as it
>>> it.cycle('ABCD')
A B C D A B C D A B C D ...
>>> # Iterate over each element in cycle for a fixed range
>>> cycle_iterator = it.cycle('abc123')
>>> [next(cycle_iterator) for i in range(0, 10)] 
['a', 'b', 'c', '1', '2', '3', 'a', 'b', 'c', '1']
a = [1,2,3]
list(itertools.permutations(a))
# [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
list(itertools.permutations(a, 2))
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
a = [1,2,1]
list(itertools.permutations(a))
# [(1, 2, 1), (1, 1, 2), (2, 1, 1), (2, 1, 1), (1, 1, 2), (1, 2, 1)]
set(itertools.permutations(a)) 
# {(1, 1, 2), (1, 2, 1), (2, 1, 1)}
Recorre los elementos en un iterador
cycle es un iterador infinito.
Por lo tanto, tenga cuidado de dar límites al usar esto para evitar un bucle infinito. Ejemplo:
itertools.permutaciones
itertools.permutationsdevuelve ungenerador conpermutaciones sucesivas delongitud rde 
elementos en el iterable.
Silalistaa tieneelementosduplicados,laspermutaciones resultantestendránelementos 
duplicados, puede usar set para obtener permutacionesúnicas:
>>> list(it.accumulate([1,2,3,4,5])) 
[1, 3, 6, 10, 15]
>>> list(it.accumulate([1,2,3,4,5], func=operator.mul)) 
[1, 2, 6, 24, 120]
    765/1068
    701
nulo Ninguna
verdadero Falso Verdadero Falso
numero (real) flotador
número (int) En t
cuerda str
formación lista
objeto dictado
JSON Pitón
Capítulo 137: Módulo JSON
Observaciones
Para obtener la documentación completa, incluida la funcionalidad específica de la versión, 
consulte la documentación oficial .
Los tipos
Valores predeterminados
El módulo json manejará la codificación y decodificación de los siguientes tipos de manera 
predeterminada:
Tipos de serialización:
El módulo json también entiende NaN , Infinity e -Infinity como sus valores flotantes 
correspondientes, que están fuera de la especificación JSON.
Tipos de serialización:
Pitón JSON
dictado objeto
lista, tupla formación
str cuerda
    766/1068
    702
# my_json module
import json
from functools import partial
def serialise_object(obj):
# Do something to produce json-serialisable data 
return dict_obj
dump = partial(json.dump, default=serialise_object) 
dumps = partial(json.dumps, default=serialise_object)
# my_json module
import json
from functools import partial
def deserialise_object(dict_obj): 
# Do something custom
return obj
def deserialise_float(str_obj):
# Do something custom 
return obj
Pitón JSON
Enums, float, (int / float) -derived
Cierto
número
cierto
Falso falso
Ninguna nulo
Para no permitir la codificación de NaN , Infinity e -Infinity , debe codificar con allow_nan=False . 
Esto generará un ValueError si intenta codificar estos valores.
Personalización (des) serialización
Existen varios enlaces que le permiten manejar datos que deben representarse de manera 
diferente. El uso de functools.partial permite aplicar parcialmente los parámetros relevantes a 
estas funciones para su comodidad.
Publicación por entregas:
Puede proporcionar una función que opere en objetos antes de que se serialicen así:
De serialización:
Hay varios enlaces que son manejados por las funciones json, como object_hook y parse_float. 
Para obtener una lista exhaustiva de su versión de python, consulte aquí .
    767/1068
    703
# my_json module
import json
from functools import partial
class MyEncoder(json.JSONEncoder): 
# Do something custom
class MyDecoder(json.JSONDecoder): 
# Do something custom
dump = partial(json.dump, cls=MyEncoder) 
dumps = partial(json.dumps, cls=MyEncoder) 
load = partial(json.load, cls=MyDecoder) 
loads = partial(json.loads, cls=MyDecoder)
import json 
d = {
'foo': 'bar', 
'alice': 1,
'wonderland': [1, 2, 3]
}
json.dumps(d)
'{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
import json
s = '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}' 
json.loads(s)
Mayor (des) serialización personalizada:
Elmódulo json también permite la extensión / sustitución de json.JSONEncoder yjson.JSONDecoder 
para manejar varios tipos.Losganchos documentados anteriormente se pueden agregar como 
valores predeterminados creando un método de nombre equivalente. Para usarlos, simplemente 
pase la clase como el parámetro cls a la función relevante. El uso de functools.partial permite 
aplicar parcialmente el parámetro cls a estas funciones por conveniencia, por ejemplo,
Examples
Creando JSON desde el dictado de Python
El fragmento de código anterior devolverá lo siguiente:
Creando el dictado de Python desde JSON
El fragmento de código anterior devolverá lo siguiente:
load = partial(json.load, object_hook=deserialise_object, parse_float=deserialise_float) 
loads = partial(json.loads, object_hook=deserialise_object, parse_float=deserialise_float)
    768/1068
    704
import json
d = {
'foo': 'bar', 
'alice': 1,
'wonderland': [1, 2, 3]
}
with open(filename, 'w') as f: 
json.dump(d, f)
import json
with open(filename, 'r') as f: 
d = json.load(f)
import json
data = {u"foo": u"bar", u"baz": []} 
json_string = json.dumps(data)
# u'{"foo": "bar", "baz": []}' 
json.loads(json_string)
# {u"foo": u"bar", u"baz": []}
import json
from io import StringIO
Almacenamiento de datos en un archivo
El siguiente fragmento de código codifica los datos almacenados en d en JSON y los almacena en 
un archivo (reemplace el filename con el nombre real del archivo).
Recuperando datos de un archivo
El siguiente fragmento de código abre un archivo codificado JSON (reemplaza el filename con el 
nombre real del archivo) y devuelve el objeto que está almacenado en el archivo.
`load` vs` loads`, `dump` vs` dumps`
El módulo json contiene funciones para leer y escribir en y desde cadenas de Unicode, y para leer 
y escribir en y desde archivos. Estos se diferencian por una s final en el nombre de la función. En 
estos ejemplos, usamos un objeto StringIO, pero las mismas funciones se aplicarían a cualquier 
objeto similar a un archivo.
Aquí usamos las funciones basadas en cadenas:
Y aquí usamos las funciones basadas en archivos:
{u'alice': 1, u'foo': u'bar', u'wonderland': [1, 2, 3]}
    769/1068
    705
import json
json_file_path = './data.json' 
data={u"foo": u"bar",u"baz":[]}
with open(json_file_path, 'w') as json_file: 
json.dump(data, json_file)
with open(json_file_path) as json_file: 
json_file_content = json_file.read() 
# u'{"foo": "bar", "baz": []}'
with open(json_file_path) as json_file: 
json.load(json_file)
# {u"foo": u"bar", u"baz": []}
# loading from a file
data = [json.loads(line) for line in open(file_path).splitlines()]
# dumping to a file
with open(file_path, 'w') as json_file: 
for item in data:
json.dump(item, json_file) 
json_file.write('\n')
{"foo": {"bar": {"baz": 1}}}
Como puede ver, la principal diferencia es que al descargar datos json debe pasar el identificador 
de archivo a la función, en lugar de capturar el valor de retorno. También vale la pena señalar que 
debe buscar el inicio del archivo antes de leer o escribir, para evitar la corrupción de datos. Al 
abrir un archivo, el cursor se coloca en la posición 0 , por lo que lo siguiente también funcionaría:
Tenerlas dos formas de tratar conlos datos jsonlepermite trabajar de manera idiomática y 
eficiente con los formatos que se basan en json, como json-per-line de pyspark :
Llamando a `json.tool` desde la línea de comandos a la salida JSON de 
impresión bonita
Dado un archivo JSON "foo.json" como:
podemos llamar al módulo directamente desde la línea de comando (pasando el nombre del 
archivo como un argumento) para imprimirlo en forma bonita:
json_file = StringIO()
data = {u"foo": u"bar", u"baz": []} 
json.dump(data, json_file)
json_file.seek(0) # Seek back to the start of the file before reading 
json_file_content = json_file.read()
# u'{"foo": "bar", "baz": []}'
json_file.seek(0) # Seek back to the start of the file before reading 
json.load(json_file)
# {u"foo": u"bar", u"baz": []}
    770/1068
    706
$ cat foo.json | python -m json.tool
>>> data = {"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": 
"black"}]}
>>> print(json.dumps(data))
{"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}
>>> print(json.dumps(data, indent=2))
{
"cats": [
{
"name": "Tubbs",
"color": "white"
},
{
"name": "Pepper",
"color": "black"
}
]
}
El módulo también recibirá información de STDOUT, por lo que (en Bash) también podríamos 
hacer:
Formato de salida JSON
Digamos que tenemos los siguientes datos:
Simplemente descartando esto como JSON no hace nada especial aquí:
Configuración de sangría para obtener una 
salida más bonita
Si queremos una impresión bonita, podemos establecer un tamaño de indent :
Ordenando las teclas alfabéticamente para
$ python -m json.tool foo.json
{
"foo": {
"bar": {
"baz": 1
}
}
}
    771/1068
    707
>>> print(json.dumps(data, sort_keys=True))
{"cats": [{"color": "white", "name": "Tubbs"}, {"color": "black", "name": "Pepper"}]}
>>>print(json.dumps(data, separators=(',', ':')))
{"cats":[{"name":"Tubbs","color":"white"},{"name":"Pepper","color":"black"}]}
import json
from datetime import datetime
data = {'datetime': datetime(2016, 9, 26, 4, 44, 0)} 
print(json.dumps(data))
class DatetimeJSONEncoder(json.JSONEncoder): 
def default(self, obj):
try:
return obj.isoformat() 
except AttributeError:
# obj has no isoformat method; let the builtin JSON encoder handle it 
return super(DatetimeJSONEncoder, self).default(obj)
encoder = DatetimeJSONEncoder() 
print(encoder.encode(data))
# prints {"datetime": "2016-09-26T04:44:00"}
obtener un resultado consistente
Por defecto, el orden de las teclas en la salida no está definido. Podemos obtenerlos en orden 
alfabético para asegurarnos de que siempre obtengamos la misma salida:
Deshacerse de los espacios en blanco para 
obtener una salida compacta
Podríamosquererdeshacernosdelosespaciosinnecesarios,loquesehaceconfigurando 
cadenas separadoras diferentes de las predeterminadas ', 'y ': ':
JSON que codifica objetos personalizados
Si solo intentamos lo siguiente:
recibimosunerrorquedicequeTypeError: datetime.datetime(2016, 9,26, 4,44)isnotJSON 
serializable .
Para poder serializar correctamente el objeto de fecha y hora, necesitamos escribir un código 
personalizado sobre cómo convertirlo:
y luego use esta clase de codificador en lugar de json.dumps :
    772/1068
    708
    773/1068
    709
1 + 1
# Output: 2
from operator import add 
add(1, 1)
# Output: 2
from operator import mul 
mul('a', 10)
# Output: 'aaaaaaaaaa' 
mul([3], 3)
# Output: [3, 3, 3]
from operator import methodcaller
list(filter(methodcaller('startswith', 'd'), alist)) # Does the same but is faster. 
# Output: ['duck']
from itertools import groupby 
from operator import itemgetter 
adict = {'a': 1, 'b': 5, 'c': 1}
Capítulo 138: Módulo operador
Examples
Operadores como alternativa a un operador infijo.
Para cada operador de infijo, por ejemplo, + hay una función de operator ( operator.add para + ):
aunque la documentación principal indica que para los operadores aritméticos solo se permite la 
entrada numérica, es posible:
Vea también: asignación de la función de operación a operador en la documentación oficial de
Python .
Methodcaller
En lugar de esta función lambda que llama explícitamente al método:
alist = ['wolf', 'sheep', 'duck'] 
list(filter(lambda x: x.startswith('d'), alist)) 
# Output: ['duck']
# Keep only elements that start with 'd'
uno podría usar una función de operador que hace lo mismo:
Itemgetter
Agrupando los pares clave-valor de un diccionario por el valor con itemgetter :
    774/1068
    710
dict((i, dict(v)) for i, v in groupby(adict.items(), lambda x: x[1]))
alist_of_tuples = [(5,2), (1,3), (2,2)] 
sorted(alist_of_tuples, key=itemgetter(1,0)) 
# Output: [(2, 2), (5, 2), (1, 3)]
que es equivalente (pero más rápido) a una función lambda como esta:
O clasificando una lista de tuplas por el segundo elemento primero el primer elemento como 
secundario:
dict((i, dict(v)) for i, v in groupby(adict.items(), itemgetter(1))) 
# Output: {1: {'a': 1, 'c': 1}, 5: {'b': 5}}
    775/1068
    711
pyautogui.displayMousePosition() #gave you the current mouse position but should be done 
on terminal.
#move the cursor relative to your current position. 
#it will click on the position mention there
#it will drag the mouse relative to position
moveRel() 
click(337,46) 
dragRel()
moveTo(200,0,duration=1.5) #move the cursor to (200,0) position with 1.5 second delay
#gave you the size of the screen 
#return current position of mouse
size() 
position()
typewrite(['a','b','left','left','X','Y'])
pyautogui.KEYBOARD_KEYS #get the list of all the keyboard_keys. 
pyautogui.hotkey('ctrl','o') #for the combination of keys to enter.
typewrite('') #this will type the string on the screen where current window has focused.
.screenshot('c:\\path') #get the screenshot.
.locateOnScreen('c:\\path') #search that image on screen and get the coordinates for you. 
locateCenterOnScreen('c:\\path') #get the coordinate for the image on screen.
Capítulo 139: módulo pyautogui
Introducción
pyautogui es un módulo usado para controlar el mouse y el teclado. Este módulo se usa 
básicamente para automatizar el clic del mouse y las tareas de pulsación del teclado. Para el 
mouse, las coordenadas de la pantalla (0,0) comienzan desde la esquina superior izquierda. Si 
está fuera de control, mueva rápidamente el cursor del mouse hacia la parte superior izquierda, 
tomará el control del mouse y el teclado del Python y se lo devolverá.
Examples
Funciones del mouse
Estas son algunas de las funciones útiles del mouse para controlar el mouse.
Funciones del teclado
Estas son algunas de las funciones útiles del teclado para automatizar la pulsación de teclas.
ScreenShot y reconocimiento de imágenes
Esta función te ayudará a tomar la captura de pantalla y también a relacionar la imagen con la 
parte de la pantalla.
    776/1068
    712
import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
# Create table 
c.execute('''CREATETABLE stocks
(date text, trans text, symbol text, qty real, price real)''')
# Insert a row of data
c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)")
# Save (commit) the changes 
conn.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost. 
conn.close()
print c.fetchone()
Capítulo 140: Módulo Sqlite3
Examples
Sqlite3 - No requiere proceso de servidor separado.
El módulo sqlite3 fue escrito por Gerhard Häring. Para usar el módulo, primero debe crear un 
objeto de conexión que represente la base de datos. Aquí los datos se almacenarán en el archivo 
example.db:
También puede proporcionar el nombre especial: memoria: para crear una base de datos en la 
RAM. Una vez que tenga una conexión, puede crear un objeto Cursor y llamar a su método 
execute () para ejecutar comandos SQL:
Obtención de los valores de la base de datos y manejo de errores.
Obteniendo los valores de la base de datos SQLite3. 
Imprimir valores de fila devueltos por consulta de selección
Para obtener un solo método fetchone () coincidente
import sqlite3
conn = sqlite3.connect('example.db') 
c = conn.cursor()
c.execute("SELECT * from table_name where id=cust_id") 
for row in c:
print row # will be a list
    777/1068
    713
a=c.fetchall() #which is similar to list(cursor) method used previously 
for row in a:
print row
try:
#SQL Code
except sqlite3.Error as e:
print "An error occurred:", e.args[0]
Para filas múltiples use el método fetchall ()
El manejo de errores se puede hacer usando la función incorporada sqlite3.Error
    778/1068
    714
import threading
def foo():
print "Hello threading!"
my_thread = threading.Thread(target=foo)
my_thread.start() # prints 'Hello threading!'
import requests
from threading import Thread 
from queue import Queue
Capítulo 141: Multihilo
Introducción
Los subprocesos permiten que los programas de Python manejen múltiples funciones a la vez en 
lugar de ejecutar una secuencia de comandos individualmente. Este tema explica los principios 
detrás de los hilos y demuestra su uso.
Examples
Conceptos básicos de multihilo
Usando el módulo de threading , se puede iniciar un nuevo subproceso de ejecución creando un 
nuevo threading.Thread y asigne una función para ejecutar:
El parámetro de target referencia a la función (u objeto llamable) que se ejecutará.El subproceso 
no comenzará la ejecución hasta que se llame al start en el objeto Thread .
Comenzando un hilo
Ahora que my_thread ha ejecutado y finalizado, al start nuevo, se producirá un RuntimeError . Si 
deseaejecutar suhilo comoundemonio,pasar el daemon=True kwarg,oconfigurar my_thread.daemon 
en True antes de llamar a start(), hace que su Thread ejecute silenciosamente en segundo plano 
como un demonio.
Unirse a un hilo
En los casos en que divide un trabajo grande en varios pequeños y desea ejecutarlos 
simultáneamente, pero debe esperar a que todos terminen antes de continuar, Thread.join() es el 
método que está buscando.
Por ejemplo, supongamos que desea descargar varias páginas de un sitio web y compilarlas en 
una sola página. Tu harias esto
    779/1068
    715
# print 'The main program continuesto run in foreground.' 
t.join()
print("The main program continues to run in the foreground.")
t.start() # start method automatic call Thread class run method.
from threading import Thread 
import time
class Sleepy(Thread): 
def run(self):
time.sleep(5)
print("Hello form Thread")
if name == " main ": t
= Sleepy()
Una mirada más cercana a cómo funciona join() se puede encontrar aquí .
Crear una clase de hilo personalizado
Usando la clase threading.Thread podemos subclasificar la nueva clase Thread personalizada. 
debemos anular el método de run en una subclase.
Comunicando entre hilos
Haymúltipleshilosen sucódigo ynecesita comunicarse de forma seguraentre ellos. 
Puede utilizar una Queue de la biblioteca de queue .
from queue import Queue
q = Queue(maxsize=20)
def put_page_to_q(page_num):
q.put(requests.get('http://some-website.com/page_%s.html' % page_num)
def compile(q):
# magic function that needs all pages before being able to be executed 
if not q.full():
raise ValueError 
else:
print("Done compiling!")
threads = []
for page_num in range(20):
t = Thread(target=requests.get, args=(page_num,)) 
t.start()
threads.append(t)
# Next, join all threads to make sure all threads are done running before 
# we continue. join() is a blocking call (unless specified otherwise using 
# the kwarg blocking=False when callingjoin)
for t in threads: 
t.join()
# Call compile() now, since all threads have completed 
compile(q)
    780/1068
    716
q = Queue()
t1 = Thread(target=consumer, args=(q,)) 
t2 = Thread(target=producer, args=(q,)) 
t1.start()
t2.start()
from socket import socket, AF_INET, SOCK_STREAM 
from threading import Thread
from queue import Queue
def echo_server(addr, nworkers): 
print('Echo server running at', addr) 
# Launch the client workers
q = Queue()
for n in range(nworkers):
t = Thread(target=echo_client, args=(q,)) 
t.daemon = True
t.start()
# Run the server
sock = socket(AF_INET, SOCK_STREAM) 
sock.bind(addr)
sock.listen(5) 
while True:
client_sock, client_addr = sock.accept() 
q.put((client_sock, client_addr))
echo_server(('',15000), 128)
Creación de subprocesos de productor y consumidor con una cola compartida
Creando un grupo de trabajadores
Usando threading y queue :
Utilizando concurrent.futures.Threadpoolexecutor :
from threading import Thread
# create a data producer 
def producer(output_queue):
while True:
data = data_computation() 
output_queue.put(data)
# create a consumer
def consumer(input_queue): 
while True:
# retrieve data (blocking) 
data = input_queue.get()
# do something with the data
# indicate data has been consumed 
input_queue.task_done()
    781/1068
    717
def split_line(line, cols): 
if len(line) > cols:
new_line = ''
# The actual way to send
#!/usr/bin/env python2
import threading 
import Queue 
import time 
import sys
import subprocess
from backports.shutil_get_terminal_size import get_terminal_size
printq = Queue.Queue() 
interrupt = False 
lines = []
def main():
ptt = threading.Thread(target=printer) # Turn the printer on 
ptt.daemon = True
ptt.start()
#Stupid example ofstuffto print 
for i in xrange(1,100):
printq.put(' '.join([str(x) for x in range(1,i)])) 
stuff to the printer
time.sleep(.5)
Python Cookbook, 3ra edición, por David Beazley y Brian K. Jones (O'Reilly). Derechos de autor 
2013 David Beazley y Brian Jones, 978-1-449-34037-7.
Uso avanzado de multihilos
Esta sección contendrá algunos de los ejemplos más avanzados realizados utilizando 
Multithreading.
Impresora avanzada (logger)
Un hilo que imprime todo se recibe y modifica la salida de acuerdo con el ancho del terminal. Lo 
bueno es que también la salida "ya escrita" se modifica cuando cambia el ancho del terminal.
from socket import AF_INET, SOCK_STREAM, socket 
from concurrent.futures import ThreadPoolExecutor
def echo_server(addr):
print('Echo server running at', addr) 
pool = ThreadPoolExecutor(128)
sock = socket(AF_INET, SOCK_STREAM) 
sock.bind(addr)
sock.listen(5) 
while True:
client_sock, client_addr = sock.accept() 
pool.submit(echo_client, client_sock, client_addr)
echo_server(('',15000))
    782/1068
    718
import threading 
import time
class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check 
regularly for the stopped() condition."""
def init (self):
super(StoppableThread, self). init () 
self._stop_event = threading.Event()
def stop(self):
ww = line.split() 
i = 0
whilelen(new_line)<=(cols-len(ww[i])-1): 
new_line += ww[i] + ''
i += 1
print len(new_line) 
if new_line == '':
return (line, '')
return (new_line, ''.join(ww[i:])) 
else:
return (line, '')
def printer():
while True:
cols, rows = get_terminal_size() # Get the terminal dimensions 
msg = '#' + '-' * (cols - 2) + '#\n' # Create the
try:
new_line = str(printq.get_nowait())
if new_line != '!@#EXIT#@!': # A nice way to turn the printer
# thread out gracefully
lines.append(new_line) 
printq.task_done()
else:
printq.task_done() 
sys.exit()
except Queue.Empty: 
pass
#Build the new message to show and split too long lines 
for line in lines:
res = line # The following is to split lines which are
# longer than cols.
while len(res) !=0:
toprint, res = split_line(res, cols) 
msg += '\n' + toprint
# Clear the shell and print the new output 
subprocess.check_call('clear') # Keep the shell clean 
sys.stdout.write(msg)
sys.stdout.flush() 
time.sleep(.5)
Hilo que se puede detener con un bucle de tiempo
    783/1068
    719
Basado en esta pregunta .
self._stop_event.set()
def join(self, *args, **kwargs): 
self.stop()
super(StoppableThread,self).join(*args, **kwargs)
def run()
while not self._stop_event.is_set(): 
print("Still running!") 
time.sleep(2)
print("stopped!"
    784/1068
    720
import multiprocessing 
import time
from random import randint
def countUp(): 
i = 0
while i <= 3:
print('Up:\t{}'.format(i)) 
time.sleep(randint(1, 3)) # sleep 1, 2 or 3 seconds
i += 1
def countDown(): 
i = 3
while i >= 0:
print('Down:\t{}'.format(i)) 
time.sleep(randint(1, 3)) # sleep 1, 2 or 3 seconds
i -= 1
if name == ' main ': # 
Initiate the workers.
workerUp = multiprocessing.Process(target=countUp) 
workerDown = multiprocessing.Process(target=countDown)
# Start the workers. 
workerUp.start() 
workerDown.start()
# Join the workers. This will block in the main (parent) process 
# until the workers are complete.
workerUp.join() 
workerDown.join()
Capítulo 142: Multiprocesamiento
Examples
Ejecutando dos procesos simples
Un ejemplo simple de usar múltiples procesos serían dos procesos (trabajadores) que se ejecutan 
por separado. En el siguiente ejemplo, se inician dos procesos:
• countUp() cuenta 1 arriba, cada segundo.
• countDown() cuenta 1 abajo, cadasegundo.
La salida es la siguiente:
Up: 0
Down: 3
Up: 1
Up: 2
Down: 2
Up: 3
Down: 1
Down: 0
    785/1068
    721
from multiprocessing import Pool
def cube(x):
return x ** 3
if name == " main ": 
pool = Pool(5)
result = pool.map(cube, [0, 1, 2, 3])
Uso de la piscina y el mapa
Poolesunaclasequeadministravarios Workers(procesos)detrásdeescenaylepermite al 
programador usar.
Pool(5) crea un nuevo pool con 5 procesos, y pool.map funciona igual que el mapa, pero usa varios 
procesos (la cantidad definida al crear el pool).
Se pueden obtener resultados similares utilizando map_async , apply y apply_async que se pueden 
encontrar en la documentación .
    786/1068
    722
>>> a = 1
>>> id(a) 
140128142243264
>>> a += 2
>>> a 
3
>>> id(a) 
140128142243328
>>> stack = "Overflow"
>>> stack 
'Overflow'
>>> id(stack) 
140128123955504
>>> stack += " rocks!"
>>> stack 
'Overflow rocks!'
>>> id(stack) 
140128123911472
Capítulo 143: Mutable vs Inmutable (y 
Hashable) en Python
Examples
Mutable vs inmutable
Hay dos tipos de tipos en Python. Tipos inmutables y tipos mutables.
Inmutables
Un objeto de un tipo inmutable no puede ser cambiado. Cualquier intento de modificar el objeto 
dará lugar a que se cree una copia.
Esta categoría incluye: enteros, flotadores, complejos, cadenas, bytes, tuplas, rangos y conjuntos 
de imágenes.
Para resaltar esta propiedad, vamos a jugar con el id incorporado. Esta función devuelve el 
identificador único del objeto pasado como parámetro. Si el id es el mismo, este es el mismo 
objeto. Si cambia, entonces este es otro objeto. (Algunos dicen que esta es realmente la dirección 
de memoria del objeto, pero ten cuidado con ellos, son del lado oscuro de la fuerza ...)
Está bien, 1 no es 3 ... Noticias de última hora ... Tal vez no. Sin embargo, este comportamiento a 
menudo se olvida cuando se trata de tipos más complejos, especialmente de cadenas.
Jajaja ¿Ver? ¡Podemos modificarlo!
    787/1068
    723
>>> stack = "Stack"
>>> stackoverflow = stack + "Overflow"
>>> id(stack) 
140128069348184
>>> id(stackoverflow) 
140128123911480
s = ""
for i in range(1,1000): 
s += str(i)
s += ","
No. Si bien parece que podemos cambiar la cadena nombrada por la stack variables, lo que 
realmente hacemos es crear un nuevo objeto para contener el resultado de la concatenación. Nos 
engañan porque en el proceso, el objeto antiguo no va a ninguna parte, por lo que se destruye.
En otra situación, eso habría sido más obvio:
En este caso, está claro que si queremos conservar la primera cadena, necesitamos una copia.
¿Pero es eso tan obvio para otros tipos?
Ejercicio
Ahora, sabiendo cómo funcionan los tipos inmutables, ¿qué diría usted con el siguiente código?
¿Es sabio?
Mutables
Un objeto de un tipo mutable se puede cambiar y se cambia in situ . No se realizan copias 
implícitas.
Estacategoríaincluye:listas,diccionarios,bytearraysysets. 
Sigamos jugando con nuestra pequeña función de id .
(Como nota al margen, uso bytes que contienen datos ASCII para aclarar mi punto, pero recuerde 
que los bytes no están diseñados para contener datos textuales. Que la fuerza me perdone).
¿Que tenemos? Creamos un bytearray, lo modificamos y usando el id , podemos asegurarnos de
>>> b = bytearray(b'Stack')
>>> b
bytearray(b'Stack')
>>> b = bytearray(b'Stack')
>>> id(b) 
140128030688288
>>> b += b'Overflow'
>>> b
bytearray(b'StackOverflow')
>>> id(b) 
140128030688288
    788/1068
    724
>>> c = b
>>> c += b' rocks!'
>>> c
bytearray(b'StackOverflow rocks!')
>>> b
bytearray(b'StackOverflow rocks!')
>>> id(c) == id(b) 
True
>>> ll = [ [] ]*4 # Create a list of 4 lists to contain our results
>>> ll
[[], [], [], []]
>>> ll[0].append(23) # Add result 23 to first list
>>> ll
[[23], [23], [23], [23]]
>>> # Oops...
>>> def list_add3(lin): 
lin += [3]
return lin
>>> a = [1, 2, 3]
>>> b = list_add3(a)
que este es el mismo objeto, modificado. No es una copia de eso.
Por supuesto, si un objeto se va a modificar con frecuencia, un tipo mutable hace un trabajo 
mucho mejor que un tipo inmutable. Desafortunadamente, la realidad de esta propiedad a 
menudo se olvida cuando más duele.
Bueno...
Waiiit un segundo ...
En efecto. c no es una copia de b . c es b .
Ejercicio
Ahora que entiendes mejor qué efecto secundario implica un tipo mutable, ¿puedes explicar qué 
está mal en este ejemplo?
Mutables e inmutables como argumentos
Uno de los principales casos de uso cuando un desarrollador necesita tener en cuenta la 
mutabilidad es cuando pasa argumentos a una función. Esto es muy importante, ya que esto 
determinará la capacidad de la función para modificar objetos que no pertenecen a su alcance, o 
en otras palabras, si la función tiene efectos secundarios. Esto también es importante para 
comprender dónde debe estar disponible el resultado de una función.
    789/1068
    725
>>> def tuple_add3(tin): 
tin += (3,)
return tin
>>> a = (1, 2, 3)
>>> b = tuple_add3(a)
>>> b
(1, 2, 3, 3)
>>> a 
(1, 2, 3)
>>> def yoda(prologue, sentence): 
sentence.reverse()
prologue += " ".join(sentence) 
return prologue
>>> focused = ["You must", "stay focused"]
>>> saying = "Yoda said: "
>>> yoda_sentence = yoda(saying, focused)
Aquí,elerrorespensarquelin ,comoparámetrodelafunción,puedemodificarselocalmente. 
Ensulugar,linya referenciadelmismoobjeto.Comoesteobjetoesmutable,lamodificaciónse 
realizainsitu,loquesignificaqueelobjetoal quehacenreferenciatantolin comoasemodifica. 
Noesnecesariodevolverlin ,porqueya tenemosunareferenciaaesteobjetoen formadea . ay 
b terminan haciendo referencia al mismoobjeto.
Esto no es lo mismo para las tuplas.
Al comienzo de la función, tin y a referencia del mismo objeto.Pero este es un objeto inmutable. 
Así que cuando la función intenta modificarla, tin recibir un nuevo objeto con la modificación, 
mientras que a mantiene una referencia al objeto original. En este caso, devolver tin es 
obligatorio, o el nuevo objeto se perdería.
Ejercicio
Nota: el reverse opera en el lugar.
¿Qué opinas de esta función? ¿Tiene efectos secundarios? ¿Es necesaria la devolución? 
Después de la llamada, ¿cuál es el valor de saying ? De focused ? ¿Qué sucede si se vuelve a 
llamar a la función con los mismos parámetros?
>>> b
[1, 2, 3, 3]
>>> a
[1, 2, 3, 3]
    790/1068
    726
from py2neo import authenticate, Graph, Node, Relationship 
authenticate("localhost:7474", "neo4j", "<pass>")
graph = Graph()
results = News.objects.todays_news() 
for r in results:
article = graph.merge_one("NewsArticle", "news_id", r) 
article.properties["title"] = results[r]['news_title'] 
article.properties["timestamp"] = results[r]['news_timestamp'] 
article.push()
[...]
results = News.objects.todays_news() 
for r in results:
article = graph.merge_one("NewsArticle", "news_id", r) 
if 'LOCATION' in results[r].keys():
for loc in results[r]['LOCATION']:
loc = graph.merge_one("Location", "name", loc) 
try:
rel = graph.create_unique(Relationship(article, "about_place", loc)) 
except Exception, e:
print e
Capítulo 144: Neo4j y Cypher usando Py2Neo
Examples
Importación y Autenticación
Debe asegurarse de que su base de datos Neo4j existe en localhost: 7474 con las credenciales 
apropiadas.
El objeto graph es su interfaz con la instancia de neo4j en el resto de su código de Python. Más 
bien, gracias a hacer de esto una variable global, debes mantenerla en el método init una 
clase.
Añadiendo nodos a Neo4j Graph
Agregar nodos a la gráfica es bastante simple, graph.merge_one es importante ya que evita 
elementos duplicados.(Si ejecuta el script dosveces,la segunda vez se actualizará el títuloy no 
se crearán nuevos nodos para los mismosartículos)
timestamp debe ser un número entero ynouna cadena defecha, ya queneo4jrealmente notiene 
untipode datos de fecha.Esto causaproblemas de clasificación cuando almacena la fechacomo 
'05 -06-1989 '
article.push() es una llamada que realmente realiza la operación en neo4j. No olvides este paso.
Agregando relaciones a Neo4j Graph
    791/1068
    727
def get_autocomplete(text): 
query = """
start n = node(*) where n.name =~ '(?i)%s.*' return n.name,labels(n) limit 10; 
"""
query = query % (text) 
obj = []
for res in graph.cypher.execute(query): 
# print res[0],res[1]
obj.append({'name':res[0],'entity_type':res[1]}) 
return res
def search_news_by_entity(location,timestamp): 
query = """
MATCH (n)-[]->(l)
where l.name='%s' and n.timestamp='%s'
RETURN n.news_id limit 10 
"""
query = query % (location,timestamp) 
news_ids = []
for res in graph.cypher.execute(query):
news_ids.append(str(res[0]))
return news_ids
MATCH (n)-[]->(l)
where l.name='Donald Trump'
RETURN n.date,count(*) order by n.date
MATCH (n:NewsArticle)-[]->(l)
create_unique es importante para evitar duplicados. Pero por lo demás es una operación bastante 
sencilla.El nombre de larelación también es importante, ya quelousaríaen casosavanzados.
Consulta 1: Autocompletar en títulos de noticias
Esta es una consulta de ejemplo para obtenertodos los nodos con el name la propiedad que 
comienza con el text argumento.
Consulta 2: obtener artículos de noticias por ubicación en una fecha en
particular
Puede usar esta consulta para encontrar todos los artículos de noticias (n) conectados a una 
ubicación (l) por unarelación.
Cypher Query Samples
Contar artículos conectados a una persona en particular a lo largo del tiempo.
Busque otras personas / ubicaciones conectadas a los mismos artículos de noticias que Trump 
con al menos 5 nodos de relaciones totales.
    792/1068
    728
where l.name='Donald Trump' 
MATCH (n:NewsArticle)-[]->(m) 
with m,count(n) as num where num>5
return labels(m)[0],(m.name), num order by num desc limit 10
    793/1068
    729
#! /usr/bin/env python
class Node:
definit (self, cargo=None, next=None): 
self.car = cargo
self.cdr = next 
def str (self):
return str(self.car)
def display(lst): 
if lst:
w("%s " % lst) 
display(lst.cdr)
else:
w("nil\n")
Capítulo 145: Nodo de lista enlazada
Examples
Escribe un nodo de lista enlazada simple en python
Una lista enlazada es:
• la lista vacía, representada por Ninguna, o
• un nodo que contiene un objeto de carga y una referencia a una lista enlazada.
    794/1068
    730
class Foo(object): 
def init (self):
self. bar = None
@property
def bar(self):
if self. bar is None:
self. bar = some_expensive_lookup_operation() 
return self. bar
>>> from foobar import Foo
>>> foo = Foo()
>>> print(foo.bar) # This will take some time since bar is None after initialization 
42
>>> print(foo.bar) # This is much faster since bar has a value now 
42
class Cash(object):
def init (self, value): 
self.value = value
@property
def formatted(self):
return '${:.2f}'.format(self.value) 
@formatted.setter
Capítulo 146: Objetos de propiedad
Observaciones
Nota : en Python 2, asegúrese de que su clase herede del objeto (lo que lo convierte en una clase 
de nuevo estilo) para que todas las características de las propiedades estén disponibles.
Examples
Usando el decorador @property
El decorador de @property se puede utilizar para definir métodos en una clase que actúan como 
atributos. Un ejemplo en el que esto puede ser útil es cuando se expone información que puede 
requerir una búsqueda inicial (costosa) y una recuperación sencilla a partir de entonces.
Dado algún módulo de foobar.py :
Entonces
Usando el decorador de propiedad para las propiedades de lectura-escritura
Si desea usar @property para implementar un comportamiento personalizado para configurar y 
obtener, use este patrón:
    795/1068
    731
>>> wallet = Cash(2.50)
>>> print(wallet.formatted)
$2.50
>>> print(wallet.value) 
2.5
>>> wallet.formatted = '$123.45'
>>> print(wallet.formatted)
$123.45
>>> print(wallet.value) 
123.45
class BaseClass(object): 
@property
def foo(self):
return some_calculated_value()
@foo.setter
def foo(self, value): 
do_something_with_value(value)
class DerivedClass(BaseClass): 
@BaseClass.foo.setter
def foo(self, value): 
do_something_different_with_value(value)
class A:
p = 1234
def getX (self): 
return self._x
def setX (self, value): 
self._x = value
Para usar esto:
Anulando solo un captador, configurador o un eliminador de un objeto de 
propiedad
Cuando se hereda de una clase con una propiedad, puede proporcionar una nueva aplicación 
para una o más de las propiedades getter , setter o deleter funciones, haciendo referencia a la 
propiedad objeto de la clase padre:
También puede agregar un definidor o un eliminador donde antes no había uno en la clase base.
Usando propiedades sin decoradores
Si bien el uso de la sintaxis decorativa (con la @) es conveniente, también es un poco oculto. 
Puede utilizar propiedades directamente, sin decoradores. El siguiente ejemplo de Python 3.x 
muestra esto:
def formatted(self, new): 
self.value = float(new[1:])
    796/1068
    732
def getY (self): 
return self._y
def setY (self, value):
self._y = 1000 + value # Weird but possible
def getY2 (self): 
return self._y
def setY2 (self, value): 
self._y = value
defgetT (self): 
return self._t
def setT (self, value): 
self._t = value
def getU (self):
return self._u + 10000
def setU (self, value): 
self._u = value -5000
x, y, y2 = property (getX, setX), property (getY, setY), property (getY2, setY2) 
t = property (getT, setT)
u = property (getU, setU)
A.q = 5678 
class B:
def getZ (self): 
return self.z_
def setZ (self, value): 
self.z_ = value
z = property (getZ, setZ) 
class C:
def init (self):
self.offset = 1234
def getW (self):
return self.w_ + self.offset
def setW (self, value):
self.w_ = value - self.offset 
w = property (getW, setW)
a1 = A ()
a2 = A ()
a1.y2 = 1000
a2.y2 = 2000
a1.x = 5
a1.y = 6
    797/1068
    733
a2.x = 7
a2.y = 8
a1.t = 77
a1.u = 88
print (a1.x, a1.y, a1.y2)
print (a2.x, a2.y, a2.y2)
print (a1.p, a2.p, a1.q, a2.q) 
print (a1.t, a1.u)
b = B ()
c = C ()
b.z = 100100
c.z = 200200
c.w = 300300
print (a1.x, b.z, c.z, c.w)
print (a1.x, b.z, c.z, c.w)
c.w = 400400
c.z = 500500
b.z = 600600
    798/1068
    734
x = True 
y = True
z = x and y # z = True
x = True 
y = False
z = x and y # z = False
x = False 
y = True
z = x and y # z = False
x = False 
y = False
z = x and y # z = False
x = 1
y = 1
z = x and y # z = y, so z = 1, see `and` and `or` are not guaranteed to be a boolean
x = 0
y = 1
z = x and y # z = x, so z = 0 (see above)
x = 1
y = 0
z = x and y # z = y, so z = 0 (see above)
x = 0
y = 0
z = x and y # z = x, so z = 0 (see above)
x = True 
y = True
z = x or y # z = True
Capítulo 147: Operadores booleanos
Examples
y
Evalúa el segundo argumento si y solo si ambos argumentos son veraces. De lo contrario se 
evalúa al primer argumento falsey.
Los 1 en el ejemplo anterior se pueden cambiar a cualquier valor verdadero, y los 0 se pueden 
cambiar a cualquier valor falso.
o
Evalúa el primer argumento de verdad si alguno de los argumentos es verdadero. Si ambos 
argumentos son falsey, evalúa el segundo argumento.
    799/1068
    735
x = True
y = not x # y = False
x = False
y = not x # y = True
>>> def true_func():
... print("true_func()")
... return True
...
>>> def false_func():
... print("false_func()")
... return False
...
>>> true_func() or false_func() 
true_func()
True
Los 1 en el ejemplo anterior se pueden cambiar a cualquier valor verdadero, y los 0 se pueden 
cambiar a cualquier valor falso.
no
Devuelve lo contrario de la siguiente declaración:
Evaluación de cortocircuito
Python evalúa mínimamente las expresiones booleanas.
x = True 
y = False
z = x or y # z = True
x = False 
y = True
z = x or y # z = True
x = False 
y = False
z = x or y # z = False
x = 1
y = 1
z = x or y # z = x, so z = 1, see `and` and `or` are not guaranteed to be a boolean
x = 1
y = 0
z = x or y # z = x, so z = 1 (see above)
x = 0
y = 1
z = x or y # z = y, so z = 1 (see above)
x = 0
y = 0
z = x or y # z = y, so z = 0 (see above)
    800/1068
    736
def or_(a, b): 
if a:
return a 
else:
return b
def and_(a, b): 
if not a:
return a 
else:
return b
if 3.14 < x < 3.142:
print("x is near pi")
`and` y` or` no están garantizados para devolver un valor booleano
Cuando usa or , devolverá el primer valor en laexpresión si es verdadero, de lo contrario, 
devolverá ciegamente el segundo valor. Es decir or es equivalente a:
Para and , devolverá su primer valor si es falso, de lo contrario, devolverá el último valor:
Un simple ejemplo
En Python puedes comparar un solo elemento utilizando dos operadores binarios, uno en cada 
lado:
Enmuchos (¿la mayoría?)Lenguajes de programación, estose evaluaría de formacontrariaalas 
matemáticas regulares: (3.14 < x) < 3.142 , pero en Python se trata como 3.14 < x and x < 3.142 , 
como la mayoría de los no programadores Esperaría.
>>> false_func() or true_func() 
false_func()
true_func() 
True
>>> true_func() and false_func() 
true_func()
false_func() 
False
>>> false_func() and false_func() 
false_func()
False
    801/1068
    737
# 60 = 0b111100 
# 30 = 0b011110 
60 & 30
# Out: 28
# 28 = 0b11100
bin(60 & 30)
# Out: 0b11100
Capítulo 148: Operadores de Bitwise
Introducción
Las operaciones bitwise alteran cadenas binarias en el nivel de bit. Estas operaciones son 
increíblemente básicas y están directamente soportadas por el procesador. Estas pocas 
operaciones son necesarias para trabajar con controladores de dispositivo, gráficos de bajo nivel, 
criptografía y comunicaciones de red. Esta sección proporciona conocimientos útiles y ejemplos 
de operadores bitwise de Python.
Sintaxis
• x << y # Bitwise Left Shift
• x >> y # Bitwise Right Shift
• x & y # Bitwise Y
• x | y # Bitwise OR
• ~ x # Bitwise NO
• x ^ y # Bitwise XOR
Examples
Y a nivel de bit
El operador & realizará un AND binario, donde se copia un bit si existe en ambos operandos. Eso 
significa:
# 0 & 0 = 0
# 0 & 1 = 0
# 1 & 0 = 0
# 1 & 1 = 1
Bitwise o
El |eloperadorrealizará un binario "o", donde se copia un bit si existe en cualquiera delos
    802/1068
    738
#60=0b111100 
#30=0b011110 
60 | 30
# Out: 62
# 62 = 0b111110
bin(60 | 30) 
# Out: 0b111110
# 60 = 0b111100 
# 30 = 0b011110 
60 ^ 30
# Out: 34
# 34 = 0b100010
bin(60 ^ 30)
# Out: 0b100010
# 2 = 0b10 
2 << 2
# Out: 8
# 8 = 0b1000
bin(2 << 2)
# Out: 0b1000
7 << 1
# Out: 14
operandos. Eso significa:
# 0 | 0 = 0
# 0 | 1 = 1
# 1 | 0 = 1
# 1 | 1 = 1
XOR de bitwise (OR exclusivo)
El operador ^ realizará un XOR binario en el que se copia un binario 1 si y solo si es el valor de 
exactamente un operando. Otra forma de afirmar esto es que el resultado es 1 solo si los 
operandos son diferentes. Ejemplos incluyen:
# 0 ^ 0 = 0
# 0 ^ 1 = 1
# 1 ^ 0 = 1
# 1 ^ 1 = 0
Desplazamiento a la izquierda en modo de bits
El operador << realizará un "desplazamiento a la izquierda" a nivel de bits, donde el valor del 
operando izquierdo se mueve a la izquierda por el número de bits dado por el operando derecho.
Realizar un cambio de bit a la izquierda de 1 es equivalente a la multiplicación por 2 :
    803/1068
    739
3 << 4
# Out: 48
# 8 = 0b1000 
8 >> 2
# Out: 2
# 2 = 0b10
bin(8 >> 2) 
# Out: 0b10
36 >> 1
# Out: 18
15 >> 1
# Out: 7
48 >> 4
# Out: 3
59 >> 3
# Out: 7
Realizar un cambio de bit a la izquierda de n es equivalente a la multiplicación por 2**n :
Cambio a la derecha en el modo de bits
El operador >> realizará un "desplazamiento a la derecha" a nivel de bits, donde el valor del 
operando izquierdo se mueve a la derecha por el número de bits dado por el operando derecho.
Realizar un cambio de bit a la derecha de 1 es equivalente a la división entera por 2 :
Realizar un cambio de bit a la derecha de n es equivalente a la división entera por 2**n :
Bitwise NO
El operador ~ volteará todos los bits en el número. Dado que las computadoras usan 
representaciones de números firmados , especialmente la notación de complemento de los dos
para codificar números binarios negativos donde los números negativos se escriben con un (1) 
inicial en lugar de un cero (0).
Esto significa que si estuviera usando 8 bits para representar los números del complemento a 
dos, trataría los patrones de 0000 0000 a 0111 1111 para representar números de 0 a 127 y 
reservaría 1xxx xxxx para representar números negativos.
Números de ocho bits de complemento a dos
Bits Valor sin firmar Valor del complemento a dos
0000 0000 0 0
    804/1068
    740
# 0 = 0b0000 0000
~0
# Out: -1
# -1 = 0b1111 1111
# 1 = 0b0000 0001
~1
# Out: -2
# -2 = 1111 1110
# 2 = 0b0000 0010
~2
# Out: -3
# -3 = 0b1111 1101
# 123 = 0b0111 1011
~123
# Out: -124
# -124 = 0b1000 0100
Bits Valor sin firmar Valor del complemento a dos
0000 0001 1 1
0000 0010 2 2
0111 1110 126 126
0111 1111 127 127
1000 0000 128 -128
1000 0001 129 -127
1000 0010 130 -126
1111 1110 254 -2
1111 1111 255 -1
Enesencia,estosignificaquemientras1010 0110tieneunvalor sinsignode166(seobtieneal 
agregar (128 * 1) + (64 * 0) + (32 * 1) + (16 * 0) + (8 * 0) + (4 * 1) + (2 * 1) + (1 * 0) ),
tiene un valor de complemento a dos de -90 (se obtiene al agregar (128 * 1)- (64 * 0)- (32 * 
1) - (16 * 0) - (8 * 0) - (4 * 1) - (2 * 1) - (1 * 0) , y complementando el valor).
De esta manera, los números negativos varían hasta -128 ( 1000 0000 ). Cero (0) se representa 
como 0000 0000 , y menos uno (-1) como 1111 1111 .
En general, sin embargo, esto significa ~n = -n - 1 .
Tenga en cuenta que el efecto general de esta operación cuando se aplica a números positivos 
se puede resumir:
~n -> -|n+1|
    805/1068
    741
# -0 = 0b0000 0000
~-0
# Out: -1
# -1 = 0b1111 1111
# 0 is the obvious exception to this rule, as -0 == 0 always
# -1 = 0b1000 0001
~-1
# Out: 0
# 0 = 0b0000 0000
# -2 = 0b1111 1110
~-2
# Out: 1
# 1 = 0b0000 0001
# -123 = 0b1111 1011
~-123
# Out: 122
# 122 = 0b0111 1010
a = 0b001
a &= 0b010 
# a = 0b000
a = 0b001
a |= 0b010 
# a = 0b011
a = 0b001 
a <<= 2
# a = 0b100
a = 0b100 
a >>= 2
# a = 0b001
a = 0b101
a ^= 0b011 
# a = 0b110
Y luego, cuando se aplica a números negativos, el efecto correspondiente es:
~-n -> |n-1|
Los siguientes ejemplos ilustran esta última regla ...
Operaciones in situ
Todos los operadores de Bitwise (excepto ~ ) tienen sus propias versiones in situ
    806/1068
    742
import operator # contains 2 argument arithmetic functions for the examples
a, b = 1, 2
# Using the "+" operator:
a + b # = 3
# Using the "in-place" "+=" operator to add and assign: 
a += b # a = 3 (equivalent to a = a + b)
Capítulo 149: Operadores matemáticos 
simples
Introducción
Python hace operadores matemáticos comunes por sí mismo, incluyendo división de números 
enteros y flotantes, multiplicación, exponenciación, suma y resta. El módulo matemático (incluido 
en todas las versiones estándar de Python) ofrece funciones ampliadas como funciones 
trigonométricas, operaciones de raíz, logaritmos y muchos más.
Observaciones
Tipos numéricos y sus metaclases.
El módulo de numbers contiene las metaclases abstractas para los tipos numéricos:
subclases números.número Números.Integral números.Racional numeros.Real
bool ✓ ✓ ✓ ✓
En t ✓ ✓ ✓ ✓
fracciones.Fracción ✓ - ✓ ✓
flotador ✓ - - ✓
complejo ✓ - - -
decimal.decimal ✓ - - - -
Examples
Adición
    807/1068
    743
[1, 2, 3] + [4, 5,6] # = [1, 2, 3, 4, 5, 6]
"first string " + "second string" # = 'first string second string'
# contains 2 argument arithmetic functions 
# = 1
import operator 
operator.sub(b, a)
a, b = 1, 2
# Using the "-" operator:
b - a # = 1
# = 6
import operator 
operator.mul(a, b)
# = 6
a, b = 2, 3
a * b
Posibles combinaciones (tipos incorporados):
• int e int (da un int)
• int y float (da un float)
• int y complex (da un complex).
• float y float (da un float)
• float y complex (da un complex ).
• complex y complex (da un complex ).
Nota: el operador + también se utiliza para concatenar cadenas, listas y tuplas:
Sustracción
Posibles combinaciones (tipos incorporados):
• int e int (da un int)
• int y float (da un float)
• int y complex (da un complex).
• float y float (da un float)
• float y complex (da un complex ).
• complex y complex (da un complex ).
Multiplicación
a = operator.iadd(a, b) # a = 5 since a is set to 3 right before this line
# The "+=" operator is equivalent to:
operator.add(a, b) # = 5 since a is set to 3 right before this line
    808/1068
    744
3 * 'ab' # = 'ababab'
3 * ('a', 'b') # = ('a', 'b', 'a', 'b', 'a', 'b')
a, b, c, d, e = 3, 2, 2.0, -3, 10
d / e # = -1
b / a # = 0
d / b # = -2
a / c # = 1.5
a / b # = 1
Posibles combinaciones (tipos incorporados):
• int e int (da un int)
• int y float (da un float)
• int y complex (da un complex).
• float y float (da un float)
• float y complex (da un complex ).
• complex y complex (da un complex ).
Nota: el operador * también se utiliza para la concatenación repetida de cadenas, listas y tuplas:
División
Python hace división de enteros cuando ambos operandos son enteros. El comportamiento de los 
operadores de división de Python ha cambiado de Python 2.xy 3.x (ver también División de
enteros ).
Python 2.x 2.7
En Python 2, el resultado del operador '/' depende del tipo de numerador y denominador.
Tenga en cuenta que debido a que a y b son int s, el resultado es un int . 
El resultado siempre se redondea hacia abajo (floored).
Debidoaquecesunflotador,elresultadodea / cesunfloat. 
También puede utilizar el módulo operador:
Python 2.x 2.2
import operator # the operator module provides 2-argument arithmetic functions 
operator.div(a, b) # = 1
operator. div (a, b) # = 1
    809/1068
    745
from operator import truediv 
truediv(a, b) # = 1.5
# = 1.5
# = 1.5
float(a) / b 
a / float(b)
# = 1
# = 1.0
a // b 
a // c
¿Qué tal si quieres división flotante? 
Recomendado:
De acuerdo (si no desea aplicar a todo el módulo):
a / (b * 1.0) # = 1.5
1.0 * a / b # = 1.5
a / b * 1.0 # = 1.0 (careful with order of operations)
No recomendado (puede generar TypeError, por ejemplo, si el argumento es complejo):
Python 2.x 2.2
El operador '//' en Python 2 fuerza la división de pisos independientemente del tipo.
Python 3.x 3.0
EnPython 3, el operador/realizauna división "verdadera"independientemente delos tipos.El 
operador // realiza la división del piso y mantiene el tipo.
a / b 
e / b 
a // b 
a // c
# = 1.5
# = 5.0
# = 1
# = 1.0
import operator 
operator.truediv(a, b) 
operator.floordiv(a, b) 
operator.floordiv(a, c)
# the operator module provides 2-argument arithmetic functions 
# = 1.5
# = 1
# = 1.0
Posibles combinaciones (tipos incorporados):
• int e int (da un int en Python 2 y un float en Python 3)
• int y float (da un float)
• int y complex (da un complex).
• float y float (da un float)
• float y complex (da un complex ).
from future import division # applies Python 3 style division to the entire module a
/ b # = 1.5
a // b # = 1
    810/1068
    746
# does so more efficiently
# 0, calculates (2 ** 3) % 2, but as per Python docs,
a, b, c = 2, 3, 2
pow(2, 3, 2)
import math 
x = 8
math.pow(x, 1/3) # evaluates to 2.0 
x**(1/3) # evaluates to 2.0
math.exp(0) # 1.0
math.exp(1) # 2.718281828459045 (e)
• complex y complex (da un complex ).
Ver PEP 238 para más información.
Exponer
a, b = 2, 3
(a ** b) # = 8
pow(a, b) # = 8
import math 
math.pow(a, b) # = 8.0 (always float; does not allow complex results)
import operator 
operator.pow(a, b) # = 8
Otra diferencia entre el pow math.pow y math.pow es que el pow incorporado puede aceptar tres 
argumentos:
Funciones especiales
La función math.sqrt(x) calcula la raíz cuadrada de x .
import math 
import cmath 
c = 4 
math.sqrt(c) 
cmath.sqrt(c)
# = 2.0 (always float; does not allow complex results) 
# = (2+0j) (always complex)
Para calcular otras raíces, como una raíz cúbica, aumente el número al recíproco del grado de la 
raíz. Esto se podría hacer con cualquiera de las funciones exponenciales u operador.
La función math.exp(x) calcula e ** x .
Lafunciónmath.expm1(x)calculae ** x - 1.Cuandoxespequeño,estoproporcionauna 
precisión significativamente mejor que math.exp(x) - 1 .
    811/1068
    747
# optional base argument. Default is math.e 
math.log(5, math.e) # = 1.6094379124341003 
cmath.log(5) # = (1.6094379124341003+0j)
math.log(1000, 10) # 3.0 (always returns float) 
cmath.log(1000, 10) # (3+0j)
# = 1.6094379124341003
import math 
import cmath
math.log(5)
# Logarithm base 10 
math.log10(100) # = 2.0
cmath.log10(100) # = (2+0j)
# = 3.0
# Logarithm base 2
math.log2(8)
# Logarithm base e - 1 (higher precision for low values) 
math.log1p(5) # = 1.791759469228055
a = a + 1
a = a * 2
a += 1
# and
a *= 2
Logaritmos
De forma predeterminada, la función math.log calcula el logaritmo de un número, base e. 
Opcionalmente puede especificar una base como segundo argumento.
Existen variaciones especiales de la función math.log para diferentes bases.
Operaciones in situ
Es común que dentro de las aplicaciones se necesite tener un código como este:
o
Existe un atajo efectivo para estas operaciones in situ:
Se puede usar cualquier operador matemático antes del carácter '=' para realizar una operación in 
situ:
math.exp(1e-6) - 1 # 1.0000004999621837e-06 
math.expm1(1e-6) # 1.0000005000001665e-06
# exact result # 1.000000500000166666708333341666...
math.expm1(0) # 0.0
    812/1068
    748
a, b = 1, 2
import math
math.sin(a) # returns the sine of 'a' in radians 
# Out: 0.8414709848078965
math.cosh(b) # returns the inverse hyperbolic cosine of 'b' in radians 
# Out: 3.7621956910836314
math.atan(math.pi) # returns the arc tangent of 'pi' in radians 
# Out: 1.2626272556789115
math.hypot(a, b) # returns the Euclidean norm, same as math.sqrt(a*a + b*b) 
# Out: 2.23606797749979
math.hypot(x2-x1, y2-y1)
math.degrees(a)
# Out: 57.29577951308232
math.radians(57.29577951308232) 
# Out: 1.0
• -= disminuir la variable en su lugar
• += incrementar la variable en su lugar
• *= multiplica la variable en su lugar
• /= dividir la variable en su lugar
• //= piso divide la variable en su lugar # Python 3
• %= devolver el módulo de la variable en su lugar
• **= elevar a una potencia en su lugar
Existen otros operadores in situ para los operadores bitwise ( ^ , |etc)
Funciones trigonométricas
Tengaencuentaquemath.hypot(x, y) tambiéneslalongituddelvector(odistancia 
euclidiana) desde el origen (0, 0) hasta el punto (x, y) .
Para calcular la distancia euclidiana entre dos puntos (x1, y1) y (x2, y2) puede usar
math.hypot siguiente manera
Para convertir de radianes -> grados y grados -> radianes respectivamente use math.degrees y
math.radians
Módulo
Como en muchos otros idiomas, Python usa el operador % para calcular el módulo.
3 % 4 # 3
10 % 2 # 0
6 % 4 # 2
    813/1068
    749
quotient, remainder = divmod(9, 4)
# quotient = 2, remainder = 1 as 4 * 2 + 1 == 9
O utilizando el módulo operator :
import operator
operator.mod(3 , 4) # 3
operator.mod(10 , 2) # 0
operator.mod(6 , 4) # 2
También puedes usar números negativos.
-9 % 7 # 5
9 % -7 # -5
-9 % -7 # -2
Si necesita encontrar el resultado de la división y el módulo de enteros, puede usar la función
divmod como acceso directo:
    814/1068
    750
import cProfile 
def f(x):
return "42!" 
cProfile.run('f(12)')
import cProfile, pstats, StringIO
Capítulo 150: Optimización del rendimiento
Observaciones
Cuando intente mejorar el rendimiento de un script de Python, en primer lugar debería poder 
encontrar el cuello de botella de su script y tener en cuenta que ninguna optimización puede 
compensar una mala elección en las estructuras de datos o una falla en el diseño de su algoritmo. 
La identificación de los cuellos de botella de rendimiento se puede hacer mediante la creación de 
perfiles de su script. En segundo lugar, no intente optimizar demasiado pronto su proceso de 
codificación a expensas de la legibilidad / diseño / calidad. Donald Knuth hizo la siguiente 
declaración sobre la optimización:
"Debemos olvidarnos de las pequeñas eficiencias, digamos que aproximadamente el 
97% de las veces: la optimización prematura es la raíz de todo mal. Sin embargo, no 
debemos dejar pasar nuestras oportunidades en ese 3% crítico ".
Examples
Código de perfil
En primer lugar, debe poder encontrar el cuello de botella de su script y tener en cuenta que 
ninguna optimización puede compensar una mala elección en la estructura de datos o una falla en 
el diseño de su algoritmo. En segundo lugar, no intente optimizar demasiado pronto su proceso 
de codificación a expensas de la legibilidad / diseño / calidad. Donald Knuth hizo la siguiente 
declaración sobre la optimización:
"Debemos olvidarnos de las pequeñas eficiencias, digamos que aproximadamente el 
97% de las veces: la optimización prematura es la raíz de todo mal. Sin embargo, no 
debemos dejar pasar nuestras oportunidades en ese 3% crítico".
Paraperfilarsucódigotienevariasherramientas:cProfile (oelprofilemáslento)delabiblioteca 
estándar, line_profiler y timeit . Cada uno de ellos tiene un propósito diferente.
cProfile es un generador de perfiles determinístico: se controlan los eventos de llamada de 
función, retorno de función y excepción, y se realizan intervalos precisos para los intervalos entre 
estos eventos (hasta 0.001s). La documentación de la biblioteca ([ 
https://docs.python.org/2/library/profile.html◆◆1]) nos proporciona un caso de uso simple
O si prefiere envolver partes de su código existente:
    815/1068
    751
3 function calls in 0.000 seconds 
Ordered by: standard name
$ kernprof -l script_to_profile.py
@profile
def slow_function(a, b, c):
...
$ python -m line_profiler script_to_profile.py.lprof
Esto creará resultados que se parecen a la tabla a continuación, donde puede ver rápidamente 
dónde pasa su programa la mayor parte de su tiempo e identificar las funciones para optimizar.
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <stdin>:1(f)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
El módulo line_profiler ([ https://github.com/rkern/line_profilerI [ ]] es útil para tener un análisis 
línea por línea de su código. Obviamente, esto no es manejable para scripts largos, pero está 
dirigido a fragmentos. Consulte la documentación para más detalles. La forma más fácil de 
comenzar es usar el script kernprof tal como se explica en la página del paquete, tenga en cuenta 
que deberá especificar manualmente la función (es) que desea perfilar.
kernprof creará una instancia de LineProfiler y la insertará en el espacio de nombres builtins
con el perfil de nombre. Se ha escrito para ser utilizado como decorador, por lo que en su script, 
decora las funciones que desea perfilar con @profile .
El comportamiento predeterminado de kernprof es colocar los resultados en un archivo binario 
script_to_profile.py.lprof . Puede decirle a kernprof que vea inmediatamente los resultados 
formateados en el terminal con la opción [-v / - ver]. De lo contrario, puede ver los resultados más 
tarde así:
Finalmente,timeitproporcionaunaformasencilladeprobarunforroounapequeñaexpresión 
tanto desde la línea de comandos como desde el shell de python. Este módulo responderá 
preguntas como,¿es másrápidohaceruna listadecomprensiónousarlalist()integradalist() 
al transformar un conjunto en una lista? Busque la palabra clave de setup o la opción -s para 
agregar el código deconfiguración.
pr = cProfile.Profile() 
pr.enable()
# ... do something ...
# ... long ... 
pr.disable()
sortby = 'cumulative'
ps = pstats.Stats(pr, stream=s).sort_stats(sortby) 
ps.print_stats()
print s.getvalue()
    816/1068
    752
$ python -m timeit '"-".join(str(n) for n in range(100))' 
10000 loops, best of 3: 40.3 usec per loop
desde una terminal
>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000) 
0.8187260627746582
    817/1068
    753
import os 
os.path.join('a', 'b', 'c')
>>> os.path.join('a', 'b', 'c') 
'a\b\c'
>>> os.path.join('a', 'b', 'c') 
'a/b/c'
Capítulo 151: os.path
Introducción
Este módulo implementa algunas funciones útiles en las rutas de acceso. Los parámetros de ruta 
se pueden pasar como cadenas o bytes. Se recomienda que las aplicaciones representen los 
nombres de archivo como cadenas de caracteres (Unicode).
Sintaxis
• os.path.join (a, * p)
• os.path.basename (p)
• os.path.dirname (p)
• os.path.split (p)
• os.path.splitext (p)
Examples
Unir caminos
Para unir dos o más componentes de ruta, primero importe el módulo OS de Python y luego use 
lo siguiente:
La ventaja de usar os.path es que permite que el código permanezca compatible en todos los 
sistemas operativos, ya que utiliza el separador apropiado para la plataforma en la que se está 
ejecutando.
Por ejemplo, el resultado de este comando en Windows será:
En un sistema operativo Unix:
Camino Absoluto desde el Camino Relativo
Utilice os.path.abspath :
    818/1068
    754
>>> p = os.path.join(os.getcwd(), 'foo.txt')
>>> p
'/Users/csaftoiu/tmp/foo.txt'
>>> os.path.dirname(p) 
'/Users/csaftoiu/tmp'
>>> os.path.basename(p) 
'foo.txt'
>>> os.path.split(os.getcwd()) 
('/Users/csaftoiu/tmp', 'foo.txt')
>>> os.path.splitext(os.path.basename(p)) 
('foo', '.txt')
os.path.abspath(os.path.join(PATH_TO_GET_THE_PARENT, os.pardir))
path = '/home/john/temp' 
os.path.exists(path)
#this returns false if path doesn't exist or if the path is a broken symbolic link
dirname = '/home/john/python' 
os.path.isdir(dirname)
filename = dirname + 'main.py' 
os.path.isfile(filename)
Manipulación de componentes del camino
Para separar un componente de la ruta:
Obtener el directorio padre
Si el camino dado existe.
para comprobar si existe el camino dado
compruebe si la ruta dada es un directorio, archivo, enlace simbólico, punto 
de montaje, etc.
para comprobar si la ruta dada es un directorio
para comprobar si la ruta dada es un archivo
>>> os.getcwd() 
'/Users/csaftoiu/tmp'
>>> os.path.abspath('foo') 
'/Users/csaftoiu/tmp/foo'
>>> os.path.abspath('../foo') 
'/Users/csaftoiu/foo'
>>> os.path.abspath('/foo') 
'/foo'
    819/1068
    755
symlink = dirname + 'some_sym_link' 
os.path.islink(symlink)
mount_path = '/home' 
os.path.ismount(mount_path)
para comprobar si el camino dado es enlace simbólico
para comprobar si la ruta dada es un punto de montaje
    820/1068
    756
orders_df = pd.DataFrame()
orders_df['customer_id'] = [1,1,1,1,1,2,2,3,3,3,3,3]
orders_df['order_id'] = [1,1,1,2,2,3,3,4,5,6,6,6]
orders_df['item'] = ['apples', 'chocolate', 'chocolate', 'coffee', 'coffee', 'apples', 
'bananas', 'coffee', 'milkshake', 'chocolate', 'strawberry',
'strawberry']
# And this is how the dataframe looks like: 
print(orders_df)
# First, we define the function that will be applied per customer_id 
count_number_of_orders = lambda x: len(x.unique())
# And now, we can tranform each group using the logic defined above 
orders_df['number_of_orders_per_cient'] = ( # Put the results into a new column
Capítulo 152: Pandas Transform: Preforma 
operaciones en grupos y concatena los 
resultados.
Examples
Transformada simple
Primero, vamos a crear un marco de datos ficticio
Suponemos que un cliente puede tener n pedidos, un pedido puede tener m artículos y los 
artículos se pueden pedir más veces
# customer_id order_id item
# 0 1 1 apples
# 1 1 1 chocolate
# 2 1 1 chocolate
# 3 1 2 coffee
# 4 1 2 coffee
# 5 2 3 apples
# 6 2 3 bananas
# 7 3 4 coffee
# 8 3 5 milkshake
# 9 3 6 chocolate
# 10 3 6 strawberry
# 11 3 6 strawberry
.
.
Ahora, usaremos la función de transform pandas para contar el 
número de pedidos por cliente
    821/1068
    757
that is called 'number_of_orders_per_cient'
orders_df # Take the original dataframe
.groupby(['customer_id'])['order_id'] # Create a seperate group for each 
customer_id & select the order_id
.transform(count_number_of_orders)) # Apply the function to each group
seperatly
#Inspecting the results... 
print(orders_df)
.transform(multiple_items_per_order)) # Apply the defined function to
# Put the results into a new
# Take the orders dataframe 
# Create a seperate group for
# Then, we transform each group according to the defined function 
orders_df['item_duplicated_per_order'] = (
column
orders_df
.groupby(['order_id'])['item'] 
each order_id & select the item
# Let's try to see if the items were ordered more than once in each orders
# First, we define a fuction that will be applied per group 
def multiple_items_per_order(_items):
# Apply .duplicated, which will return True is the item occurs more than once. 
multiple_item_bool = _items.duplicated(keep=False)
return(multiple_item_bool)
# Create a dummy dataframe 
orders_df = pd.DataFrame()
orders_df['customer_id'] = [1,1,1,1,1,2,2,3,3,3,3,3]
orders_df['order_id'] = [1,1,1,2,2,3,3,4,5,6,6,6]
orders_df['item'] = ['apples', 'chocolate', 'chocolate', 'coffee', 'coffee', 'apples', 
'bananas', 'coffee', 'milkshake', 'chocolate', 'strawberry',
'strawberry']
# customer_id order_id item number_of_orders_per_cient
# 0 1 1 apples 2
# 1 1 1 chocolate 2
# 2 1 1 chocolate 2
# 3 1 2 coffee 2
# 4 1 2 coffee 2
# 5 2 3 apples 1
# 6 2 3 bananas 1
# 7 3 4 coffee 3
# 8 3 5 milkshake 3
# 9 3 6 chocolate 3
# 10 3 6 strawberry 3
# 11 3 6 strawberry 3
Múltiples resultados por grupo
Usando funciones de transform que devuelven 
sub-cálculos por grupo.
En el ejemplo anterior, tuvimos un resultado por cliente. Sin embargo, también se pueden aplicar 
funciones que devuelven valores diferentes para el grupo.
    822/1068
    758
each group separately
#Inspecting the results... 
print(orders_df)
# customer_id order_id item item_duplicated_per_order
# 0 1 1 apples False
# 1 1 1 chocolate True
# 2 1 1 chocolate True
# 3 1 2 coffee True
# 4 1 2 coffee True
# 5 2 3 apples False
# 6 2 3 bananas False
# 7 3 4 coffee False
# 8 3 5 milkshake False
# 9 3 6 chocolate False
# 10 3 6 strawberry True
# 11 3 6 strawberry True
    823/1068
    759
from types import MethodType
class Animal(object):
def init (self, *args, **kwargs):
self.name = kwargs.pop('name', None) or 'Animal' 
if kwargs.get('walk', None):
self.walk = MethodType(kwargs.pop('walk'), self)
def walk(self): 
"""
Cause animal instance to walk
Walking funcionallity is a strategy, and is intended to 
be implemented separately by different types of animals. 
"""
message = '{} shouldimplement a walkmethod'.format( 
self. class . name )
raise NotImplementedError(message)
# Here are some different walking algorithms that can be used with Animal 
def snake_walk(self):
print('I am slithering side to side because I am a {}.'.format(self.name))
def four_legged_animal_walk(self):
print('I am using all four of my legs to walk because I am a(n) {}.'.format( 
self.name))
def two_legged_animal_walk(self):
print('I am standing up on my two legs to walk because I am a {}.'.format( 
self.name))
Capítulo 153: Patrones de diseño
Introducción
Un patrón de diseño es una solución general a un problema común en el desarrollo de software. 
Este tema de documentación está dirigido específicamente a proporcionar ejemplos de patrones 
de diseño comunes en Python.
Examples
Patrón de estrategia
Este patrón de diseño se llama patrón de estrategia. Se utiliza para definir una familia de 
algoritmos, encapsula cada uno de ellos y los hace intercambiables. El patrón de diseño de 
estrategia permite que un algoritmo varíe independientemente de los clientes que lo utilizan.
Por ejemplo, los animales pueden "caminar" de muchas maneras diferentes. Caminar podría 
considerarse una estrategia que es implementada por diferentes tipos de animales:
    824/1068
    760
generic_animal = Animal()
king_cobra = Animal(name='King Cobra', walk=snake_walk)
elephant = Animal(name='Elephant', walk=four_legged_animal_walk) 
kangaroo = Animal(name='Kangaroo', walk=two_legged_animal_walk)
kangaroo.walk() 
elephant.walk() 
king_cobra.walk()
# This one will Raise a NotImplementedError to let the programmer 
# know that the walk method is intended to be used as a strategy. 
generic_animal.walk()
# OUTPUT:
#
# I am standing up on my two legs to walk because I am a Kangaroo.
# I am using all four of my legs to walk because I am a(n) Elephant. 
# I am slithering side to side because I am a King Cobra.
# Traceback (most recent call last):
# File "./strategy.py", line 56, in <module> 
# generic_animal.walk()
# File "./strategy.py", line 30, in walk 
# raise NotImplementedError(message)
# NotImplementedError: Animal should implement a walk method
Ejecutar este ejemplo produciría el siguiente resultado:
Tenga en cuenta que en lenguajes como C ++ o Java, este patrón se implementa utilizando una 
clase abstracta o una interfaz para definir una estrategia. En Python tiene más sentido 
simplemente definir algunas funciones externamente que pueden agregarse dinámicamente a una 
clase usando types.MethodType .
Introducción a los patrones de diseño y patrón Singleton.
Los patrones de diseño proporcionan soluciones a los commonly occurring problems en el diseño de 
software. Los patrones de diseño fueron introducidos por primera vez por GoF(Gang of Four) donde 
describían los patrones comunes como problemas queocurren una y otra vez y soluciones aesos 
problemas.
Los patrones de diseño tienen cuatro elementos esenciales:
1. The pattern name es un identificador que podemos usar para describir un problema de 
diseño, sus soluciones y consecuencias en una o dos palabras.
2. The problem describe cuándo aplicar el patrón.
3. The solution describe los elementos que conforman el diseño, sus relaciones, 
responsabilidades y colaboraciones.
4. The consequences son los resultados y las compensaciones de aplicar el patrón.
Ventajas de los patrones de diseño:
1. Son reutilizables en múltiples proyectos.
2. El nivel arquitectónico de problemas puede ser resuelto.
3. Han sido probados y probados con el tiempo, lo cual es la experiencia de desarrolladores y 
arquitectos.
    825/1068
    761
class Singleton(object): 
def new (cls):
# hasattr methodchecksif the class object an instanceproperty or not. 
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls). new(cls) 
return cls.instance
s = Singleton()
print ("Object created", s)
s1 = Singleton()
print ("Object2 created", s1)
('Object created', < main .Singleton object at 0x10a7cc310>) 
('Object2 created', < main .Singleton object at 0x10a7cc310>)
4. Tienen confiabilidad y dependencia.
Los patrones de diseño se pueden clasificar en tres categorías:
1. Patrón creacional
2. Patrón estructural
3. Patrón de comportamiento
Creational Pattern : se ocupan de cómo se puede crear el objeto y aíslan los detalles de la 
creación del objeto.
Structural Pattern :diseñanlaestructuradeclasesyobjetosparaquepuedancomponersepara 
lograr resultados más grandes.
Behavioral Pattern : se ocupan de la interacción entre los objetos y la responsabilidad de los 
objetos.
Patrón Singleton :
Esuntipodecreational patternqueproporcionaunmecanismoparatenersolounoyunobjeto 
de un tipo dado y proporciona un punto de acceso global.
Por ejemplo, Singleton se puede usar en operaciones de base de datos, donde queremos que el 
objeto de la base de datos mantenga la consistencia de los datos.
Implementación
Podemos implementar Singleton Pattern en Python creando solo una instancia de la clase 
Singleton y sirviendo nuevamente el mismo objeto.
Salida:
Tenga en cuenta que en lenguajes como C ++ o Java, este patrón se implementa haciendo que el 
constructor sea privado y creando un método estático que realice la inicialización del objeto. De 
esta manera, un objeto se crea en la primera llamada y la clase devuelve el mismo objeto a partir 
de entonces. Pero en Python, no tenemos forma de crear constructores privados.
    826/1068
    762
from abc import ABCMeta, abstractmethod
class Music():
 metaclass = ABCMeta 
@abstractmethod
def do_play(self): 
pass
class Mp3(Music):
def do_play(self):
print ("Playing .mp3 music!")
class Ogg(Music):
def do_play(self):
print ("Playing .ogg music!")
class MusicFactory(object):
def play_sound(self, object_type): 
return eval(object_type)().do_play()
if name == " main ":mf
= MusicFactory()
music = input("Which music you want to play Mp3 or Ogg") 
mf.play_sound(music)
Which music you want to play Mp3 or Ogg"Ogg" 
Playing .ogg music!
from datetime import date
from operator import attrgetter
Patrón de fábrica
El patrón de fábrica es también un Creational pattern . El término factory significa que una clase 
es responsable de crear objetos de otros tipos.Hay una claseque actúa como una fábrica que
tiene objetos y métodos asociados con ella. El cliente crea un objeto llamando a los métodos con 
ciertos parámetros y la fábrica crea el objeto del tipo deseado y lo devuelve al cliente.
Salida:
MusicFactory es la clase de fábrica aquí que crea un objeto de tipo Mp3 o Ogg según la elección que 
proporciona el usuario.
Apoderado
El objeto proxy se usa a menudo para garantizar el acceso protegido a otro objeto, cuya lógica 
empresarial interna no queremos contaminar con los requisitos de seguridad.
Supongamos que queremos garantizar que solo los usuarios con permisos específicos puedan 
acceder a los recursos.
Definición de proxy: (garantiza que solo los usuarios que realmente puedan ver las reservas 
puedan reservar el servicio al consumidor)
    827/1068
    763
class Proxy:
def init (self, current_user, reservation_service): 
self.current_user = current_user 
self.reservation_service = reservation_service
def highest_total_price_reservations(self, date_from, date_to, reservations_count): 
if self.current_user.can_see_reservations:
return self.reservation_service.highest_total_price_reservations( 
date_from,
date_to, 
reservations_count
)
else:
return [] 
#Models and ReservationService:
class Reservation:
def init (self, date, total_price): 
self.date = date 
self.total_price = total_price
class ReservationService:
def highest_total_price_reservations(self, date_from, date_to, reservations_count): 
# normally it would be read from database/external service
reservations = [
Reservation(date(2014, 5, 15), 100),
Reservation(date(2017, 5, 15), 10),
Reservation(date(2017, 1, 15), 50)
]
filtered_reservations = [r for r in reservations if (date_from <= r.date <= date_to)] 
sorted_reservations = sorted(filtered_reservations, key=attrgetter('total_price'),
reverse=True)
return sorted_reservations[0:reservations_count]
class User:
def init (self, can_see_reservations, name): 
self.can_see_reservations = can_see_reservations 
self.name = name
#Consumer service:
class StatsService:
def init (self, reservation_service): 
self.reservation_service = reservation_service
def year_top_100_reservations_average_total_price(self, year):
reservations = self.reservation_service.highest_total_price_reservations( 
date(year, 1, 1),
date(year, 12, 31),
1
)
if len(reservations) > 0:
total = sum(r.total_price for r in reservations)
    828/1068
    764
BENEFICIOS
• estamos evitando cualquier cambio en ReservationService cuando se cambianlas 
restricciones de acceso.
• no estamos mezclando datos relacionados con la empresa ( date_from , date_to , 
reservations_count ) con conceptos de dominio no relacionados (permisos de usuario) 
en servicio.
• El consumidor ( StatsService ) también está libre de la lógica relacionada con los 
permisos
CUEVAS
• La interfaz de proxy es siempre exactamente la misma que el objeto que oculta, por lo que 
el usuario que consume el servicio envuelto por el proxy ni siquiera estaba al tanto de la 
presencia del proxy.
return total / len(reservations) 
else:
return 0
#Test:
def test(user, year):
reservations_service = Proxy(user, ReservationService()) 
stats_service = StatsService(reservations_service)
average_price = stats_service.year_top_100_reservations_average_total_price(year) 
print("{0} will see: {1}".format(user.name, average_price))
test(User(True, "John the Admin"), 2017) 
test(User(False, "Guest"), 2017)
    829/1068
    765
In [1]: import string
In [2]: %%timeit s=""; long_list=list(string.ascii_letters)*50
....: for substring in long_list:
....: s+=substring
....:
1000 loops, best of 3: 570 us per loop
In [3]: %%timeit long_list=list(string.ascii_letters)*50
....: s="".join(long_list)
....:
100000 loops, best of 3: 16.1 us per loop
In [4]: %timeit for i in range(100000):pass 
100 loops, best of 3: 2.82 ms per loop
In [5]: %timeit for i in list(range(100000)):pass 
100 loops, best of 3: 3.95 ms per loop
>>> import timeit
>>> timeit.timeit('list(itertools.repeat("a", 100))', 'import itertools', number = 10000000) 
10.997665435877963
>>> timeit.timeit('["a"]*100', number = 10000000) 
7.118789926862576
python -m timeit "'-'.join(str(n) for n in range(100))" 
10000 loops, best of 3: 29.2 usec per loop
python -m timeit "'-'.join(map(str,range(100)))" 
100000 loops, best of 3: 19.4 usec per loop
Capítulo 154: Perfilado
Examples
%% timeit y% timeit en IPython
Concatanación de cadenas de perfiles:
Perfilado de bucles sobre iterables y listas:
función timeit ()
Repetición de perfiles de elementos en una matriz.
línea de comandos de timeit
Perfil de concatanación de números.
    830/1068
    766
$ kernprof -lv so6.py
Wrote profile results to so6.py.lprof 
Timer unit: 4.27654e-07 s
Total time: 22.6427 s 
File: so6.py
Function: slow_func at line 4
Line # Hits Time Per Hit % Time Line Contents
==============================================================
html=s.get("https://en.wikipedia.org/").text
8
list(html)])
50 5306958 106139.2 10.0 sum([pow(ord(x),3.1) for x in
import requests
@profile
def slow_func():
s = requests.session() 
html=s.get("https://en.wikipedia.org/").text 
sum([pow(ord(x),3.1) for x in list(html)])
for i in range(50): 
slow_func()
line_profiler en linea de comando
El código fuente con la directiva @profile antes de la función que queremos perfilar:
Usando el comando kernprof para calcular el perfil línea por línea
4 @profile
5 def slow_func():
6 50 20729 414.6 0.0 s = requests.session()
7 50 47618627 952372.5 89.9
La solicitud de página es casi siempre más lenta que cualquier cálculo basado en la información 
de la página.
Usando cProfile (Perfilador preferido)
Python incluye un generador de perfiles llamado cProfile. Esto es generalmente preferido sobre el 
uso de timeit.
Desglosa su script completo y para cada método en su script le dice:
• ncalls:elnúmerodevecesquesellamóaunmétodo
• tottime : tiempo total empleado en la función dada (excluyendo el tiempo realizado en 
llamadas a subfunciones)
• percall : Tiempo empleado porllamada. O el cociente de tottime dividido por ncalls
• cumtime : el tiempo acumulado empleado en esta y todas las subfunciones (desde la 
invocación hasta la salida). Esta cifra es precisa incluso para funciones recursivas.
• percall : es el cociente de cumtime dividido por llamadas primitivas
    831/1068
    767
$ python -m cProfile -s time main.py
• filename:lineno(function) : proporciona los datos respectivos de cada función 
El cProfiler se puede llamarfácilmente en la línea de comandos usando:
Para ordenar la lista devuelta de métodos perfilados por el tiempo empleado en el método:
$ python -m cProfile main.py
    832/1068
    768
data={'a':'some_value',
'b':[9,4,7],
'c':['some_str','another_str','spam','ham'], 
'd':{'key':'nested_dictionary'},
}
import pickle
file=open('filename','wb') #file object in binary write mode 
pickle.dump(data,file) #dump the data in the file object 
file.close() #close the file to write into the file
Capítulo 155: Persistencia Python
Sintaxis
• pickle.dump (obj, file, protocol = None, *, fix_imports = True)
• pickle.load (archivo, *, fix_imports = True, encoding = "ASCII", errores = "strict")
Parámetros
Parámetro Detalles
obj Representación encurtida de obj al archivo de objeto de archivo abierto
protocolo un entero, le dice al pickler que use el protocolo dado, 0 -ASCII, 1 - formato 
binario antiguo
expediente El argumento del archivo debe tener un método write () wb para el método dump
y para cargar el método rb read ()
Examples
Persistencia Python
Los objetos como números, listas, diccionarios, estructuras anidadas y objetos de instancia de 
clase viven en la memoria de su computadora y se pierden tan pronto como termina el script.
pickle almacena los datos de forma persistente en un archivo separado.
La representación de un objeto encurtido es siempre un objeto de bytes en todos los casos, por lo 
que uno debe abrir archivos en wb para almacenar datos y rb para cargar datos desde pickle.
Los datos pueden estar fuera de cualquier tipo, por ejemplo,
Almacenamiento de datos
    833/1068
    769
import pickle
file=open('filename','rb') #file object in binary read mode 
data=pickle.load(file) #load the data back 
file.close()
>>>data
{'b': [9, 4, 7], 'a': 'some_value', 'd': {'key': 'nested_dictionary'}, 
'c': ['some_str', 'another_str', 'spam', 'ham']}
import pickle
def save(filename,object): 
file=open(filename,'wb') 
pickle.dump(object,file) 
file.close()
def load(filename): 
file=open(filename,'rb') 
object=pickle.load(file) 
file.close()
return object
>>>list_object=[1,1,2,3,5,8,'a','e','i','o','u']
>>>save(list_file,list_object)
>>>new_list=load(list_file)
>>>new_list
[1, 1, 2, 3, 5, 8, 'a', 'e', 'i', 'o', 'u'
Cargar datos
Los siguientes tipos pueden ser decapados
1. Ninguno, verdadero y falso
2. enteros, números de punto flotante, números complejos
3. cuerdas, bytes, bytearrays
4. Tuplas, listas, conjuntos y diccionarios que contienen solo objetos extraíbles
5. Funciones definidas en el nivel superior de un módulo (usando def, no lambda)
6. Funciones incorporadas definidas en el nivel superior de un módulo
7. Clases que se definen en el nivel superior de un módulo.
8. instancias de dichas clases cuyo dict o el resultado de llamar a getstate ()
Función de utilidad para guardar y cargar.
Guardar datos en y desde archivo
    834/1068
    770
Capítulo 156: pip: PyPI Package Manager
Introducción
pip es el gestor de paquetes más utilizado para el Índice de paquetes de Python, instalado de 
forma predeterminada con las versiones recientes de Python.
Sintaxis
• pip <comando> [opciones] donde <comando> es uno de los siguientes:
○ instalar
○ Instalar paquetes
○ desinstalar
○ Desinstalar paquetes
○ congelar
○
○ lista
○
Salida de paquetes instalados en formato de requerimientos.
Listar paquetes instalados
○ espectáculo
○ Mostrar información sobre los paquetes instalados
○ buscar
○ Buscar PyPI para paquetes
○ rueda
○ Construye ruedas a partir de tus requerimientos.
○ cremallera
○ Zip paquetes individuales (obsoletos)
○ abrir la cremallera
○
○ haz
○
Descomprimir paquetes individuales (obsoletos)
Crear pybundles (en desuso)
○ ayuda
○ Mostrar ayuda para comandos
Observaciones
A veces, pip realizará una compilación manual de código nativo. En Linux, Python elegirá 
automáticamente un compilador de C disponible en su sistema. Consulte la tabla a continuación 
para obtener la versión requerida de Visual Studio / Visual C ++ en Windows (las versiones más 
recientes no funcionarán).
Versión Python Versión de Visual Studio Versión Visual C ++
2.6 - 3.2 Visual Studio 2008 Visual C ++ 9.0
    835/1068
    771
$ pip install SomePackage
$ pip install SomePackage==1.0.4
$ pip install SomePackage>=1.0.4
$ pip install -r requirements.txt
$ pip freeze
$ pip uninstall SomePackage
Versión Python Versión de Visual Studio Versión Visual C ++
3.3 - 3.4 Visual Studio 2010 Visual C ++ 10.0
3.5 Visual Studio 2015 Visual C ++ 14.0
Fuente: wiki.python.org
Examples
Instalar paquetes
Para instalar la última versión de un paquete llamado SomePackage :
Para instalar una versión específica de un paquete:
Para especificar una versión mínima para instalar para un paquete:
Si los comandos muestran un error de denegación de permiso en Linux / Unix, use sudo con los 
comandos
Instalar desde archivos de requisitos
Cada línea del archivo de requisitos indica algo para instalar, y al igual que los argumentos para 
instalar, los detalles sobre el formato de los archivos están aquí: Formato del archivo de requisitos
.
Después de instalar el paquete, puede verificarlo usando el comando de freeze :
Desinstalar paquetes
Para desinstalar un paquete:
    836/1068
    772
$ pip list
# example output 
docutils (0.9.1)
Jinja2 (2.6)
Pygments (1.5)
Sphinx (1.1.2)
$ pip list --outdated 
# example output
docutils (Current: 0.9.1 Latest: 0.10)
Sphinx (Current: 1.1.2 Latest: 1.1.3)
$ pip install --upgrade SomePackage
$ pip install --upgrade pip
$ python -m pip install --upgrade pip
pip list --outdated --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
Para listar todos los paquetes instalados usando `pip`
Para listar los paquetes instalados:
Para listar paquetes obsoletos y mostrar la última versión disponible:
Paquetes de actualización
Corriendo
actualizará el paquete SomePackage y todas sus dependencias. Además, pip elimina 
automáticamente la versión anterior del paquete antes de la actualización.
Para actualizar pip en sí, haz
en Unix o
en las máquinas de Windows.
Actualizando todos los paquetes desactualizados en Linux
pip no contiene actualmente una bandera que permita a un usuario actualizar todos los paquetes 
desactualizados de una sola vez. Sin embargo, esto puede lograrse uniendo los comandos en un 
entorno Linux:
Este comando toma todos los paquetes en el virtualenv local y comprueba si están 
desactualizados. De esa lista, obtiene el nombre del paquete y luego lo canaliza a un comando 
pip install -U . Al final de este proceso, todos los paquetes locales deben actualizarse.
    837/1068
    773
for /F "delims= " %i in ('pip list --outdated --local') do pip install -U %i
pip freeze > requirements.txt
pip freeze --local > requirements.txt
pip install [package]
pip2 install [package]
Actualizando todos los paquetes desactualizados en Windows
pip no contiene actualmente una bandera que permita a un usuario actualizar todos los paquetes 
desactualizados de una sola vez. Sin embargo, esto puede lograrse uniendo los comandos en un 
entorno Windows:
Este comando toma todos los paquetes en el virtualenv local y comprueba si están 
desactualizados. De esa lista, obtiene el nombre del paquete y luego lo canaliza a un comando 
pip install -U . Al final de este proceso, todos los paquetes locales deben actualizarse.
Cree un archivo Requirements.txt de todos los paquetes en el sistema
pip ayuda en la creación de los requirements.txt archivos .txt al proporcionar la opción de freeze .
Esto guardará una lista de todos los paquetes y su versióninstalada en el sistema en un archivo 
llamado requirements.txt en la carpeta actual.
Cree un archivo Requirements.txt de paquetes solo en el virtualenv actual
pip ayuda en la creación de los requirements.txt archivos .txt al proporcionar la opción de freeze .
El parámetro --local solo generará una lista de paquetes y versiones que se instalan localmente 
en un virtualenv. Los paquetes globales no serán listados.
Usando una determinada versión de Python con pip
Si tiene tanto Python 3 como Python 2 instalados, puede especificar qué versión de Python le 
gustaría que usara pip. Esto es útil cuando los paquetes solo admiten Python 2 o 3 o cuando 
desea probar con ambos.
Si desea instalar paquetes para Python 2, ejecute:
o:
Si desea instalar paquetes para Python 3, haga:
    838/1068
    774
\path\to\that\python.exe -m pip install some_package # on Windows OR
/usr/bin/python25 -m pip install some_package # on OS-X/Linux
py -3 -m pip install -U some_package # Install/Upgrade some_package to the latest python 3 
py -3.3 -m pip install -U some_package # Install/Upgrade some_package to python 3.3 if present
py -2 -m pip install -U some_package # Install/Upgrade some_package to the latest python 2 -
64 bit if present
py -2.7-32 -m pip install -U some_package # Install/Upgrade some_package to python 2.7 - 32 
bit if present
También puede invocar la instalación de un paquete a una instalación específica de Python con:
En las plataformas OS-X / Linux / Unix, es importante tener en cuenta la distinción entre la versión 
del sistema de python (la actualización hace que el sistema deje de funcionar) y las versiones de 
usuario de python. Usted puede , dependiendo de lo que está intentando actualizar , necesita 
prefijar estos comandos con sudo e ingresar una contraseña.
Delmismomodo,enWindows,algunasinstalacionesdePython,especialmenteaquellasqueson 
partedeotropaquete,puedenterminarinstaladasenlosdirectoriosdelsistema(aquellasque 
tendrá que actualizar desde una ventana de comandos que se ejecuta en el modo de 
administración) si le parece que necesita Para ello, es una muy buena idea comprobar qué 
instalación de Python está intentando actualizar con un comando como python -c"import 
sys;print(sys.path);" o py -3.5 -c"import sys;print(sys.path);" También puede comprobar qué 
pip está intentando ejecutar con pip --version
En Windows, si tienes ambos python 2 y python 3 instalados, y en tu ruta y tu python 3 es mayor 
que 3.4, entonces probablemente también tengas python launcher py en la ruta de tu sistema. A 
continuación, puede hacer trucos como:
Siestáejecutandoymanteniendo variasversionesdepython,lerecomendaríaencarecidamente 
leer sobre los entornos virtualenv python virtualenv o venv que le permiten aislar tanto la versión
de python como los paquetes que estánpresentes.
Instalación de paquetes aún no en pip como ruedas
Muchos paquetes de python puro aún no están disponibles en el Índice de Paquetes de Python 
como ruedas, pero aún así se instalan bien. Sin embargo, algunos paquetes en Windows le dan el 
error vcvarsall.bat no encontrado.
El problema es que el paquete que está intentando instalar contiene una extensión C o C ++ y no 
está disponible actualmente como una rueda precompilada del índice del paquete python, pypi , y 
en las ventanas no tiene la cadena de herramientas necesaria para compilar tales artículos
La respuesta más simple es ir al excelente sitio de Christoph Gohlke y localizar la versión 
adecuada de las bibliotecas que necesita. Por apropiado en el paquete nombrar -cp NN - tiene 
que coincidir con la versión de Python, es decir, si está utilizando Windows 32 bits pitón incluso 
en Win64 el nombre debe incluir -win32- y si el uso de la pitón de 64 bits que debe incluir -
pip3 install [package]
    839/1068
    775
win_amd64 - y luego la versión de Python debe coincidir, es decir, para Python 34, el nombre del 
archivo debe incluir -cp 34- , etc. Esta es básicamente la magia que el pip hace por ti en el sitio 
pypi.
Alternativamente, necesita obtener el kit de desarrollo de Windows apropiado para la versión de 
python que está utilizando, los encabezados de cualquier biblioteca en la que el paquete está 
intentando crear interfaces, posiblemente los encabezados de python para la versión de python, 
etc.
Python 2.7 usó Visual Studio 2008, Python 3.3 y 3.4 usó Visual Studio 2010, y Python 3.5+ usa
Visual Studio 2015.
• Instale " Visual C ++ Compiler Package for Python 2.7 ", que está disponible en el sitio web 
de Microsoft o
• Instale " Windows SDK para Windows 7 y .NET Framework 4 " (v7.1), que está disponible 
en el sitio web de Microsoft o
• Instale Visual Studio 2015 Community Edition , (o cualquier versión posterior, cuando se 
publiquen) , asegurándose de que selecciona las opciones para instalar el soporte de 
C & C ++ que ya no tiene el valor predeterminado . Me han dicho que la descarga y la 
instalación pueden demorar hasta 8 horas. así que asegúrese de que esas opciones estén 
configuradas en el primer intento.
Entonces es posible que deba ubicar los archivos de encabezado, en la revisión correspondiente 
de las bibliotecas a las que se vincula su paquete deseado y descargarlos en las ubicaciones 
correspondientes.
Finalmente , puede dejar que pip haga su compilación; por supuesto, si el paquete tiene 
dependencias que aún no tiene, es posible que también necesite encontrar los archivos de 
encabezado para ellos.
Alternativas: también vale la pena mirar hacia fuera, tanto en pypi como en el sitio de Christop , 
para cualquier versión ligeramente anterior del paquete que está buscando, ya sea python puro o 
pre-construido para su plataforma y versión de python y posiblemente usarlos, si encontrado, 
hasta que su paquete esté disponible. Del mismo modo, si está utilizando la última versión de 
python, es posible que los mantenedores de paquetes necesiten un poco de tiempo para ponerse 
al día, por lo que, para los proyectos que realmente necesitan un paquete específico, es posible 
que deba usar una python un poco más antigua por el momento. También puede consultar el sitio 
de origen de los paquetes para ver si hay una versión bifurcada que esté disponible preconstruida 
o como puro python y buscar paquetes alternativos que proporcionen la funcionalidad que 
necesita pero está disponible. Un ejemplo que viene a la mente es el siguiente. Almohada , 
mantenida activamente , reemplazo de PIL actualmente no actualizado en 6 años y no disponible 
para python 3 .
Después , recomendaría a cualquier persona que tenga este problema que vaya al rastreador de 
errores del paquete y añada o aumente, si no hay uno ya, un boleto que solicite educadamente 
que los mantenedores del paquete proporcionen una rueda en pypi para su específico 
combinación de plataforma y python, si esto se hace, normalmente las cosas mejorarán con el 
tiempo, algunos mantenedores de paquetes no se dan cuenta de que se han perdido una
    840/1068
    776
> py -3.5-32 -m venv demo-pip
> demo-pip\Scripts\activate.bat
> python -m pip install -U pip 
Collecting pip
Using cached pip-9.0.1-py2.py3-none-any.whl 
Installing collected packages: pip
Found existing installation: pip 8.1.1 
Uninstalling pip-8.1.1:
Successfully uninstalled pip-8.1.1 
Successfully installed pip-9.0.1
> pip install git+https://github.com/sphinx-doc/sphinx/ 
Collecting git+https://github.com/sphinx-doc/sphinx/
Cloning https://github.com/sphinx-doc/sphinx/ to c:\users\steve-
~1\appdata\local\temp\pip-04yn9hpp-build
Collecting six>=1.5 (from Sphinx==1.7.dev20170506) 
Using cached six-1.10.0-py2.py3-none-any.whl
Collecting Jinja2>=2.3 (from Sphinx==1.7.dev20170506)
combinación determinada que las personas pueden estar usando.
Nota sobre la instalación de versiones preliminares
Pipsiguelas reglas del control de versiones semántico y, de forma predeterminada, prefierelos 
paquetespublicados antes que los lanzamientos previos.Porlo tanto, si un paquete dado seha 
liberado como V0.98 y también hay una versión candidata V1.0-rc1 el comportamiento 
predeterminado depip install seráinstalar V0.98 : si deseainstalarlaversióncandidata, le 
recomendamosparaprobarprimeroenunentornovirtual,puedehabilitarlocon--pip install--
pre package-name o --pip install --pre --upgrade package-name . En muchos casos, los prelanzamientosolanzamientosdecandidatospuedennotenerruedas creadas para todas las 
combinaciones de plataformas y versiones, porlo que es más probable que encuentre los 
problemas anteriores.
Nota sobre la instalación de versiones de desarrollo
También puede usar pip para instalar versiones de desarrollo de paquetes desde github y otras 
ubicaciones, ya que dicho código está en flujo, es muy poco probable que se le construyan 
ruedas, por lo que cualquier paquete impuro requerirá la presencia de las herramientas de 
construcción, y es posible que se puede romper en cualquier momento, por lo que se recomienda 
encarecidamente al usuario que solo instale dichos paquetes en un entorno virtual.
Existen tres opciones para tales instalaciones:
1. Descargue una instantánea comprimida, la mayoría de los sistemas de control deversiones 
en línea tienen la opción de descargar una instantánea comprimida del código. Esto puede 
descargarse manualmente y luego instalarse con la ruta de pip install / to / download / file. 
Tenga en cuenta que, para la mayoría de los formatos de compresión, pip manejará el 
desempaquetado en un área de caché, etc.
2. Permita que pip maneje la descarga e instale por usted con: pip installURL /of/ package / 
repository - también puede necesitar usar las --trusted-host , --client-cert y / o --proxy 
paraqueestofuncionecorrectamente,especialmenteenunentornocorporativo.p.ej:
    841/1068
    777
Using cached Jinja2-2.9.6-py2.py3-none-any.whl 
Collecting Pygments>=2.0 (from Sphinx==1.7.dev20170506)
Using cached Pygments-2.2.0-py2.py3-none-any.whl 
Collecting docutils>=0.11 (from Sphinx==1.7.dev20170506)
Using cached docutils-0.13.1-py3-none-any.whl
Collecting snowballstemmer>=1.1 (from Sphinx==1.7.dev20170506) 
Using cached snowballstemmer-1.2.1-py2.py3-none-any.whl
Collecting babel!=2.0,>=1.3 (from Sphinx==1.7.dev20170506) 
Using cached Babel-2.4.0-py2.py3-none-any.whl
Collecting alabaster<0.8,>=0.7 (fromSphinx==1.7.dev20170506) 
Using cached alabaster-0.7.10-py2.py3-none-any.whl
Collecting imagesize (from Sphinx==1.7.dev20170506) 
Using cached imagesize-0.7.1-py2.py3-none-any.whl
Collecting requests>=2.0.0 (from Sphinx==1.7.dev20170506) 
Using cached requests-2.13.0-py2.py3-none-any.whl
Collecting typing (from Sphinx==1.7.dev20170506) 
Using cached typing-3.6.1.tar.gz
Requirement already satisfied: setuptools in f:\toolbuild\temp\demo-pip\lib\site-packages 
(from Sphinx==1.7.dev20170506)
Collecting sphinxcontrib-websupport (from Sphinx==1.7.dev20170506) 
Downloading sphinxcontrib_websupport-1.0.0-py2.py3-none-any.whl
Collecting colorama>=0.3.5 (from Sphinx==1.7.dev20170506) 
Using cached colorama-0.3.9-py2.py3-none-any.whl
Collecting MarkupSafe>=0.23 (from Jinja2>=2.3->Sphinx==1.7.dev20170506) 
Using cached MarkupSafe-1.0.tar.gz
Collecting pytz>=0a (frombabel!=2.0,>=1.3->Sphinx==1.7.dev20170506) 
Using cached pytz-2017.2-py2.py3-none-any.whl
Collecting sqlalchemy>=0.9 (from sphinxcontrib-websupport->Sphinx==1.7.dev20170506) 
Downloading SQLAlchemy-1.1.9.tar.gz (5.2MB)
100% |################################| 5.2MB 220kB/s
Collecting whoosh>=2.0 (from sphinxcontrib-websupport->Sphinx==1.7.dev20170506) 
Downloading Whoosh-2.7.4-py2.py3-none-any.whl (468kB)
100% |################################| 471kB 1.1MB/s
Installing collected packages: six, MarkupSafe, Jinja2, Pygments, docutils, 
snowballstemmer, pytz, babel, alabaster, imagesize, requests, typing, sqlalchemy, whoosh, 
sphinxcontrib-websupport, colorama, Sphinx
Running setup.py install for MarkupSafe ... done 
Running setup.py install for typing ... done 
Running setup.py install for sqlalchemy ... done 
Running setup.py install for Sphinx ... done
Successfully installed Jinja2-2.9.6 MarkupSafe-1.0 Pygments-2.2.0 Sphinx-1.7.dev20170506 
alabaster-0.7.10 babel-2.4.0 colorama-0.3.9 docutils-0.13.1 imagesize-0.7.1 pytz-2017.2 requests2.13.0 six-1.10.0 snowballstemmer-1.2.1 sphinxcontrib-websupport-1.0.0 sqlalchemy1.1.9 typing-3.6.1 whoosh-2.7.4
Tenga en cuenta el prefijo git+ a la URL.
3. Clonarelrepositoriousandogit,mercurialherramientaaceptableuotro,preferentemente 
una herramienta DVCS, y el uso pip installruta / a / clonada /repo - esto tanto el proceso 
como cualquier archivo requires.text y llevar a cabo los pasos de generación y 
configuración,sepuedecambiarmanualmentedirectorioa surepositorioclonadoyejecute 
pip install -r requires.txt python setup.py install yluegopython setup.py install para 
obtener el mismo efecto.Lasgrandes ventajasde este enfoque esque, si bienlaoperación 
de clonación inicial puede llevar más tiempo que la descarga de instantáneas, puede 
actualizar a la última versión con, en el caso de git: git pull origin master y si la versión 
actual contiene errores, puede usar la pip uninstall nombre-paquete, luego use los 
comandos de git checkout para retroceder a través del historial del repositorio a las
    842/1068
    778
versiones anteriores y volver a intentarlo.
    843/1068
    779
from string import Template
data = dict(item = "candy", price = 8, qty = 2) 
# define the template
t = Template("Simon bought $qty $item for $price dollar")
print(t.substitute(data))
Simon bought 2 candy for 8 dollar
from string import Template
class MyOtherTemplate(Template): 
delimiter = "#"
data = dict(id = 1, name = "Ricardo")
t=MyOtherTemplate("My name is #name andI havetheid: #id") 
print(t.substitute(data))
Capítulo 157: Plantillas en python
Examples
Programa de salida de datos simple usando plantilla
Salida:
Las plantillas admiten sustituciones basadas en $ en lugar de sustituciones basadas en%. 
Substitute (mapeo, palabras clave) realiza la sustitución de plantillas, devolviendo una nueva 
cadena.
La asignación es cualquier objeto similar a un diccionario con claves que coinciden con los 
marcadores de posición de la plantilla. En este ejemplo, el precio y la cantidad son marcadores de 
posición. Los argumentos de palabras clave también se pueden utilizar como marcadores de 
posición. Los marcadores de posición de las palabras clave tienen prioridad si ambos están 
presentes.
Cambiando delimitador
Puede cambiar el delimitador "$" a cualquier otro. El siguiente ejemplo:
Puedes leer los documentos aquí.
    844/1068
    780
class Shape: 
"""
This is a parent class that is intended to be inherited by other classes 
"""
def calculate_area(self): 
"""
This method is intended to be overridden in subclasses.
If a subclass doesn't implement it but it is called, NotImplemented will be raised.
"""
raise NotImplemented
class Square(Shape): 
"""
This is a subclass of the Shape class, and represents a square 
"""
side_length = 2 # in this example, the sides are 2 units long
def calculate_area(self): 
"""
This method overrides Shape.calculate_area(). When an object of type 
Square has its calculate_area() method called, this is the method that 
will be called, rather than the parent class' version.
It performsthe calculation necessary for this shape, a square, and 
returns the result.
"""
return self.side_length * 2
class Triangle(Shape): 
"""
Thisis also a subclass ofthe Shape class, and it represents a triangle 
"""
base_length = 4
height = 3
def calculate_area(self): 
"""
This method also overrides Shape.calculate_area() and performs the area
Capítulo 158: Polimorfismo
Examples
Polimorfismo basico
El polimorfismo es la capacidad de realizar una acción en un objeto independientemente de su 
tipo. Esto generalmente se implementa creando una clase base y teniendo dos o más subclases 
que implementan todos los métodos con la misma firma. Cualquier otra función o método que 
manipule estos objetos puede llamar a los mismos métodos independientemente del tipo de 
objeto en el que esté operando, sin necesidad de realizar una verificación de tipo primero. En la 
terminología orientada a objetos, cuando la clase X extiende la clase Y, entonces Y se llama 
súper clase o clase base y X se llama subclase o clase derivada.
    845/1068
    781
class Square:
side_length = 2
def calculate_square_area(self): 
return self.side_length ** 2
class Triangle:
base_length = 4
height = 3
def calculate_triangle_area(self):
return (0.5 * self.base_length) * self.height 
def get_area(input_obj):
# Notice the type checks that are now necessary here. These type checks
# could get very complicated for a more complex example, resulting in
# duplicate and difficult to maintain code.
Deberíamos ver esta salida:
Ninguna 
4
6.0
¿Qué pasa sin el polimorfismo?
Sin polimorfismo, puede requerirse una verificación de tipo antes de realizar una acción en un 
objetoparadeterminarel métodocorrectoparallamar.Elsiguienteejemplodecontadorrealiza 
lamismatareaqueel códigoanterior,perosinelusodepolimorfismo,lafunciónget_area()tiene 
que hacer más trabajo.
calculation for a triangle, returning the result. 
"""
return 0.5 * self.base_length * self.height 
def get_area(input_obj):
"""
This function accepts an input object, and will call that object's 
calculate_area() method. Note that the object type is not specified. It 
could be a Square, Triangle, or Shape object.
"""
print(input_obj.calculate_area())
# Create one object of each class 
shape_obj = Shape()
square_obj = Square() 
triangle_obj = Triangle()
# Now pass each object, one at a time, to the get_area() function and see the 
# result.
get_area(shape_obj) 
get_area(square_obj) 
get_area(triangle_obj)
    846/1068
    782
class Duck:
def quack(self): 
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray feathers.")
class Person:
def quack(self):
print("The person imitates a duck.") 
def feathers(self):
print("The person takes a feather from the ground and shows it.") 
def name(self):
print("John Smith")
def in_the_forest(obj): 
obj.quack() 
obj.feathers()
Deberíamos ver esta salida:
4
6.0
Nota IMPORTANTE
Tenga en cuenta que las clases utilizadas en el ejemplo de contador son clases de "nuevo estilo" 
y se heredan implícitamente de la clase de objeto si se está utilizando Python 3. El polimorfismo 
funcionará tanto en Python 2.xy 3.x, pero el código de contraejemplo del polimorfismo generará 
una excepción si se ejecuta en un intérprete de Python 2.x porque escribe (input_obj). el nombre 
devolverá "instancia" en lugar del nombre de la clase si no se heredan explícitamente del objeto, 
lo que da como resultado que nunca se asigne un área.
Escribiendo pato
Polimorfismo sin herencia en forma de escritura de pato disponible en Python debido a su sistema 
de escritura dinámico. Esto significa que siempre que las clases contengan los mismos métodos, 
el intérprete de Python no distingue entre ellos, ya que la única comprobación de las llamadas se 
realiza en tiempo de ejecución.
if type(input_obj). name == "Square": area
= input_obj.calculate_square_area()
elif type(input_obj). name == "Triangle": 
area = input_obj.calculate_triangle_area()
print(area)
# Create one object of each class 
square_obj = Square() 
triangle_obj = Triangle()
# Now pass each object, one at a time, to the get_area() function and see the 
# result.
get_area(square_obj) 
get_area(triangle_obj)
    847/1068
    783
La salida es:
Quaaaaaack!
El pato tiene plumas blancas y grises. 
La persona imita a un pato.
La persona toma una pluma del suelo y la muestra.
donald = Duck() 
john = Person()
in_the_forest(donald) 
in_the_forest(john)
    848/1068
    784
import psycopg2
# Establish a connection to the existing database 'my_database' using 
# the user 'my_user' with password 'my_password'
con = psycopg2.connect("host=localhost dbname=my_database user=my_user password=my_password")
# Create a cursor 
cur = con.cursor()
# Insert a record into 'my_table'
cur.execute("INSERT INTO my_table(id, first_name, last_name) VALUES (2, 'Jane', 'Doe');")
# Commit the current transaction 
con.commit()
# Retrieve all records from 'my_table' 
cur.execute("SELECT * FROM my_table;") 
results = cur.fetchall()
# Close the database connection 
con.close()
# Print the results 
print(results)
Capítulo 159: PostgreSQL
Examples
Empezando
PostgreSQLesunabasededatosdecódigoabiertodesarrolladaactivamenteymadura.Usando 
el módulo psycopg2 , podemos ejecutar consultas en la base dedatos.
Instalación utilizando pip
pip install psycopg2
Uso básico
Supongamos quetenemos una tabla my_tableen la base dedatos my_database definida de la 
siguiente manera.
carné de identidad nombre de pila apellido
1 Juan Gama
Podemos usar el módulo psycopg2 para ejecutar consultas en la base de datos de la siguiente 
manera.
    849/1068
    785
# OUTPUT: [(1, 'John', 'Doe'), (2, 'Jane', 'Doe')]
    850/1068
    786
Capítulo 160: Precedencia del operador
Introducción
Los operadores de Python tienen un orden de prioridad establecido , que determina qué 
operadores se evalúan primero en una expresión potencialmente ambigua. Por ejemplo, en la 
expresión 3 * 2 + 7, primero se multiplica 3 por 2, y luego el resultado se agrega a 7, obteniendo
13. La expresión no se evalúa al revés, porque * tiene una precedencia más alta que +.
A continuación hay una lista de operadores por precedencia y una breve descripción de lo que 
hacen (generalmente).
Observaciones
De la documentación de Python:
La siguiente tabla resume las precedencias del operador en Python, desde la 
precedencia más baja (menos vinculante) hasta la precedencia más alta (más 
vinculante). Los operadores en la misma caja tienen la misma prioridad. A menos que 
la sintaxis esté explícitamente dada, los operadores son binarios. Los operadores en el 
mismo grupo agrupan de izquierda a derecha (excepto las comparaciones, incluidas 
las pruebas, que tienen la misma prioridad y cadena de izquierda a derecha y 
exponenciación, que agrupa de derecha a izquierda).
Operador Descripción
lambda Expresión lambda
si Expresión condicional
o Booleano o
y Booleano y
no x Booleano no
en, no en, es, no es, <, <=,>,> =,
<>,! =, ==
Comparaciones, incluyendo pruebas de membresía y 
pruebas de identidad
| Bitwise o
^ Bitwise XOR
Y Y a nivel de bit
<<, >> Turnos
    851/1068
    787
>>> a, b, c, d = 2, 3, 5, 7
>>> a ** (b + c) # parentheses 
256
>>> a * b ** c # exponent: same as `a * (b ** c)` 
7776
>>> a + b * c / d # multiplication / division: same as `a + (b * c / d)` 
4.142857142857142
>>> 300 / 300 * 200
200.0
>>> 300 * 200 / 300
200.0
>>> 1e300 / 1e300 * 1e200 
1e+200
>>> 1e300 * 1e200 / 1e300
inf
Operador Descripción
+, - Adición y sustracción
*, /, //,% Multiplicación, división, resto [8]
+ x, -x, ~ x Positivo, negativo, a nivel de bit NO
** Exposiciónción [9]
x [índice], x [índice: índice], x 
(argumentos ...), x.attribute Suscripción, corte, llamada, atributo de referencia.
(expresiones ...), [expresiones ...],
{clave: valor ...}, expresiones ...
Encuadernación o visualización de tupla, visualización 
de lista, visualización de diccionario, conversión de 
cadena
Examples
Ejemplos simples de precedencia de operadores en python.
Python sigue la regla de PEMDAS. PEMDAS significa paréntesis, exponentes, multiplicación y 
división, y suma y resta.
Ejemplo:
Extras: las reglas matemáticas se mantienen, pero no siempre :
    852/1068
    788
import threading 
import time
def process(): 
time.sleep(2)
start = time.time() 
process()
print("One run took %.2fs" % (time.time() - start))
start = time.time()
threads = [threading.Thread(target=process) for _ in range(4)] 
for t in threads:
t.start()
for t in threads: 
t.join()
print("Four runs took %.2fs" % (time.time() - start))
# Out: One run took 2.00s
# Out: Four runs took 2.00s
Capítulo 161: Procesos e hilos
Introducción
La mayoría de los programas se ejecutan línea por línea, ejecutando solo un proceso a la vez. 
Los hilos permiten que múltiples procesos fluyan independientemente unos de otros. El 
subprocesamiento con múltiples procesadores permite que los programas ejecuten múltiples 
procesos simultáneamente. Este tema documenta la implementación y el uso de subprocesos en 
Python.
Examples
Bloqueo de intérprete global
El rendimiento de subprocesos múltiples de Python a menudo puede verse afectado por el 
bloqueo global de intérprete . En resumen, aunque puede tener varios subprocesos en un 
programa de Python, solo una instrucción de bytecode puede ejecutarse en paralelo al mismo 
tiempo, independientemente del número de CPU.
Como tal, el multihilo en casos en los que las operaciones están bloqueadas por eventos 
externos, como el acceso a la red, puede ser bastante efectivo:
Tenga en cuenta que aunque cada process tardó 2 segundos en ejecutarse, los cuatro procesos 
juntos pudieron ejecutarse de manera efectiva en paralelo, tomando un total de 2 segundos.
Sin embargo, los subprocesos múltiples en los casos en los que se realizan cálculos intensivos en
    853/1068
    789
import threading 
import time
def somefunc(i): 
return i * i
def otherfunc(m, i): 
return m + i
def process():
for j inrange(100): 
result = 0
for i in range(100000):
result = otherfunc(result, somefunc(i))
start = time.time() 
process()
print("One run took %.2fs" % (time.time() - start))
start = time.time()
threads = [threading.Thread(target=process) for _ in range(4)] 
for t in threads:
t.start()
for t in threads: 
t.join()
print("Four runs took %.2fs" % (time.time() - start))
# Out: One run took 2.05s
# Out: Four runs took 14.42s
import multiprocessing 
import time
def somefunc(i): 
return i * i
def otherfunc(m, i): 
return m + i
def process():
for j inrange(100): 
result = 0
for i in range(100000):
result = otherfunc(result, somefunc(i))
start = time.time() 
process()
print("One run took %.2fs" % (time.time() - start))
el código de Python, como muchos cálculos, no producen una gran mejora e incluso pueden ser 
más lentos que ejecutarse en paralelo:
En este último caso, el multiprocesamiento puede ser efectivo, ya que los procesos múltiples 
pueden, por supuesto, ejecutar múltiples instrucciones simultáneamente:
    854/1068
    790
import threading 
import os
def process():
print("Pid is %s, thread id is %s" % (os.getpid(), threading.current_thread().name))
threads = [threading.Thread(target=process) for _ in range(4)] 
for t in threads:
t.start()
for t in threads: 
t.join()
# Out: Pid is 11240, thread id is Thread-1 
# Out: Pid is 11240, thread id is Thread-2 
# Out: Pid is 11240, thread id is Thread-3 
# Out: Pid is 11240, thread id is Thread-4
import multiprocessing 
import os
def process():
print("Pid is %s" % (os.getpid(),))
processes = [multiprocessing.Process(target=process) for _ in range(4)] 
for p in processes:
p.start()
for p in processes: 
p.join()
# Out: Pid is 11206 
# Out: Pid is 11207 
# Out: Pid is 11208 
# Out: Pid is 11209
Corriendo en múltiples hilos
Use threading.Thread para ejecutar una función en otrohilo.
Ejecutando en múltiples procesos
Use multiprocessing.Process para ejecutar una función en otro proceso. La interfaz es similar a
threading.Thread :
start = time.time()
processes = [multiprocessing.Process(target=process) for _ in range(4)] 
for p in processes:
p.start()
for p in processes: 
p.join()
print("Four runs took %.2fs" % (time.time() - start))
# Out: One run took 2.07s
# Out: Four runs took 2.30s
    855/1068
    791
import threading
obj = {}
obj_lock = threading.Lock()
def objify(key, val):
print("Obj has %d values" % len(obj))
with obj_lock:
obj[key] = val
print("Obj now has %d values" % len(obj))
ts =[threading.Thread(target=objify, args=(str(n),n))fornin range(4)] 
for t in ts:
t.start() 
for t in ts:
t.join()
print("Obj final result:") 
import pprint; pprint.pprint(obj)
# Out: Obj has 0 values 
# Out: Obj has 0 values
# Out: Obj now has 1 values
# Out: Obj now has 2 valuesObj has 2 values 
# Out: Obj now has 3 values
# Out:
# Out: Obj has 3 values 
# Out: Obj now has 4values 
# Out: Obj final result:
# Out: {'0': 0, '1': 1, '2': 2, '3': 3}
import multiprocessing
plain_num = 0
shared_num = multiprocessing.Value('d', 0) 
lock = multiprocessing.Lock()
def increment(): 
global plain_num 
with lock:
# ordinary variable modifications are not visible across processes 
plain_num += 1
# multiprocessing.Value modifications are
Compartir el estado entre hilos
Como todos los subprocesos se ejecutan en el mismo proceso, todos los subprocesos tienen 
acceso a los mismos datos.
Sin embargo, el acceso simultáneo a los datos compartidos debe protegerse con un bloqueo para 
evitar problemas de sincronización.
Estado de intercambio entre procesos
El códigoqueseejecutaendiferentesprocesosnocomparte, de formapredeterminada,los 
mismos datos. Sin embargo, el módulo de multiprocessing contiene primitivas para ayudar a 
compartir valores a través de múltiplesprocesos.
    856/1068
    792
shared_num.value += 1
ps = [multiprocessing.Process(target=increment) for n in range(4)] 
for p in ps:
p.start() 
for p in ps:
p.join()
print("plain_num is %d, shared_num is %d" % (plain_num, shared_num.value)) 
# Out: plain_num is 0, shared_num is 4
    857/1068
    793
s=lambda x:x*x 
s(2) =>4
name_lengths = map(len, ["Mary", "Isla", "Sam"]) 
print(name_lengths) =>[4, 4, 3]
total = reduce(lambda a, x: a + x, [0, 1, 2, 3, 4])
print(total) =>10
Capítulo 162: Programación Funcional en 
Python
Introducción
La programación funcional descompone un problema en un conjunto de funciones. Lo ideal es 
que las funciones solo tomen entradas y produzcan salidas, y no tengan ningún estado interno 
que afecte la salida producida para una entrada dada. A continuación, se encuentran las técnicas 
funcionales comunes a muchos idiomas: como lambda, map, reduce.
Examples
Función lambda
Una función anónima, en línea definida con lambda. Los parámetros de la lambda se definen a la 
izquierda de los dos puntos. El cuerpo de la función se define a la derecha de los dos puntos. El 
resultado de ejecutar el cuerpo de la función se devuelve (implícitamente).
Función de mapa
Mapa toma una función y una colección de elementos. Hace una nueva colección vacía, ejecuta 
la función en cada elemento de la colección original e inserta cada valor de retorno en la nueva 
colección. Devuelve la nueva colección.
Este es un mapa simple que toma una lista de nombres y devuelve una lista de las longitudes de 
esos nombres:
Función de reducción
Reducir toma una función y una colección de elementos. Devuelve un valor que se crea 
combinando los elementos.
Este es un simple reducir. Devuelve la suma de todos los elementos de la colección.
Función de filtro
    858/1068
    794
# outputs[5,6]
arr=[1,2,3,4,5,6]
[ifori infilter(lambda x:x>4,arr)]
Filtro toma una función y una colección. Devuelve una colección de cada elemento para el que la 
función devolvió True.
    859/1068
    795
Capítulo 163: Programación IoT con Python y 
Raspberry PI
Examples
Ejemplo - sensor de temperatura 
Interfaz de DS18B20 con Raspberry pi 
Conexión de DS18B20 con Raspberry pi
Se puede ver que hay tres terminales.
1. Vcc
2. Gnd
3. Datos (protocolo de un cable)
    860/1068
    796
R1 es una resistencia de 4.7k ohmios para elevar el nivel de voltaje
1. Vcc debe conectarse a cualquiera de los pines 5v o 3.3v de la Raspberry pi (PIN: 01, 02, 04, 
17).
2. Gnd debe estar conectado a cualquiera de los pines Gnd de Raspberry pi (PIN: 06, 09, 14, 
20, 25).
3. Los datos deben estar conectados a (PIN: 07)
Habilitando la interfaz de un cable desde el lado RPi
4. Inicie sesión en Raspberry pi utilizando putty o cualquier otro terminal linux / unix.
5. Después de iniciar sesión, abra el archivo /boot/config.txt en su navegador favorito. 
nano /boot/config.txt
6. Ahora agregue esta línea dtoverlay=w1–gpio al final delarchivo.
7. Ahora reinicie el Raspberry pi sudo reboot .
8. Inicia sesión en Raspberry pi y ejecuta sudo modprobe g1-gpio
9. Luego ejecute sudo modprobe w1-therm
10. Ahora vaya al directorio / sys / bus / w1 / devices cd /sys/bus/w1/devices
11. Ahora descubrirá un directorio virtual creado con su sensor de temperatura a partir de 28 -
    861/1068
    797
import glob 
import time
RATE = 30
sensor_dirs = glob.glob("/sys/bus/w1/devices/28*")
if len(sensor_dirs) != 0: 
while True:
time.sleep(RATE)
for directories in sensor_dirs:
temperature_file = open(directories + "/w1_slave") 
# Reading the files
text = temperature_file.read() 
temperature_file.close()
# Split the text with new lines (\n) and select the second line. 
second_line = text.split("\n")[1]
# Split the line into words, and select the 10th word 
temperature_data = second_line.split(" ")[9]
# We will read after ignoring first two character. 
temperature = float(temperature_data[2:])
#Nownormalisethetemperaturebydividing1000. 
temperature = temperature / 1000
print'Address:'+str(directories.split('/')[-1])+',Temperature: 
'+str(temperature)
********.
12. Ir a este directorio cd 28-********
13. Ahora hay un nombre de archivow1-slave ,este archivocontiene la temperatura yotra 
información como CRC. cat w1-slave .
Ahora escribe un módulo en python para leer la temperatura
Sobre el módulo de python se imprimirá la temperatura frente a la dirección durante un tiempo 
infinito. El parámetro RATE se define para cambiar o ajustar la frecuencia de la consulta de 
temperatura del sensor.
Diagrama de pin GPIO
1. [ https://www.element14.com/community/servlet/JiveServlet/previewBody/73950-102-11-
339300/pi3_gpio.png◆[3]
    862/1068
    798
pip install pytest
# projectroot/module/code.py 
def add(a, b):
return a + b
# projectroot/tests/test_code.py 
from module import code
def test_add():
assert code.add(1, 2) == 3
# ensure we have the modules
$ touch tests/ init .py
$ touch module/ init .py
$ py.test
================================================== test session starts
===================================================
platform darwin -- Python 2.7.10, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 
rootdir: /projectroot, inifile:
collected 1 items 
tests/test_code.py .
Capítulo 164: py.test
Examples
Configurando py.test
py.test esunadevariasbibliotecasdepruebasdetercerosqueestándisponiblesparaPython. 
Se puede instalar utilizando pip con
El código a probar
Digamos que estamos probando una función de adición en projectroot/module/code.py :
El código de prueba
Creamos un archivo de prueba en projectroot/tests/test_code.py . El archivo debe comenzar 
con test_ para que se reconozca como un archivo de prueba.
Corriendo la prueba
Desde projectroot simplemente ejecutamos py.test :
    863/1068
    799
# projectroot/tests/test_code.py 
from module import code
def test_add failing():
assert code.add(10, 11) == 33
tests/test_code.py:5: AssertionError
================================================ 1 failed in 0.01 seconds
================================================
+ where <function add at 0x105d4d6e0> = code.add
def test_add failing():
assert code.add(10, 11) == 33
assert 21 == 33
+ where 21 = <function add at 0x105d4d6e0>(10, 11)
> 
E
E
E
$ py.test
================================================== test session starts
===================================================
platform darwin -- Python 2.7.10, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 
rootdir: /projectroot, inifile:
collected 1 items 
tests/test_code.py F
======================================================== FAILURES
========================================================
test_add failing
# projectroot/module/stuff.py 
class Stuff(object):
def prep(self): 
self.foo = 1
Pruebas de falla
Una prueba fallida proporcionará resultados útiles en cuanto a lo que salió mal:
Resultados:
Introducción a los accesorios de prueba
Las pruebas más complicadas a veces necesitan tener las cosas configuradas antes de ejecutar 
el código que desea probar. Es posible hacer esto en la función de prueba en sí, pero luego
terminas con funciones de prueba grandes que hacen tanto que es difícil decir dónde se detiene 
la configuración y comienza la prueba. También puede obtener una gran cantidad de códigos de 
configuración duplicados entre sus diversas funciones de prueba.
Nuestro archivo de código:
================================================ 1 passed in 0.01 seconds
================================================
    864/1068
    800
# projectroot/tests/test_stuff.py 
import pytest
from module import stuff
def test_foo_updates(): 
my_stuff = stuff.Stuff() 
my_stuff.prep()
assert 1 == my_stuff.foo 
my_stuff.foo = 30000
assert my_stuff.foo == 30000
def test_bar_updates(): 
my_stuff = stuff.Stuff() 
my_stuff.prep()
assert 2 == my_stuff.bar 
my_stuff.bar = 42
assert 42 == my_stuff.bar
# projectroot/tests/test_stuff.py 
import pytest
from module import stuff
def get_prepped_stuff(): 
my_stuff = stuff.Stuff() 
my_stuff.prep()
return my_stuff
def test_foo_updates():
my_stuff = get_prepped_stuff() 
assert 1 == my_stuff.foo 
my_stuff.foo = 30000
assert my_stuff.foo == 30000
def test_bar_updates():
my_stuff = get_prepped_stuff() 
assert 2 == my_stuff.bar 
my_stuff.bar = 42
assert 42 == my_stuff.bar
Nuestro archivo de prueba:
Estos son ejemplos bastante simples, pero si nuestro objeto Stuff necesitara mucha más 
configuración, se volvería difícil de manejar. Vemos que hay un código duplicado entre nuestros 
casos de prueba, así que vamos a reformular eso en una función separada primero.
Esto se ve mejor, pero todavía tenemos la my_stuff = get_prepped_stuff() nuestras funciones de 
prueba.
Py.test accesorios para el rescate!
self.bar = 2
    865/1068
    801
@pytest.fixture
def prepped_stuff(): 
my_stuff = stuff.Stuff() 
my_stuff.prep()
return my_stuff
def test_foo_updates(prepped_stuff): 
my_stuff = prepped_stuff
assert 1 == my_stuff.foo 
my_stuff.foo = 30000
assert my_stuff.foo == 30000
def test_bar_updates(prepped_stuff): 
my_stuff = prepped_stuff
assert 2 == my_stuff.bar 
my_stuff.bar = 42
assert 42 == my_stuff.bar
def test_foo_updates(prepped_stuff): 
assert 1 == prepped_stuff.foo 
prepped_stuff.foo = 30000
assert prepped_stuff.foo == 30000
def test_bar_updates(prepped_stuff): 
assert 2 == prepped_stuff.bar 
prepped_stuff.bar = 42
assert 42 == prepped_stuff.bar
Los accesorios son versiones mucho más potentes y flexibles de las funciones de configuración 
de prueba. Pueden hacer mucho más de lo que estamos aprovechando aquí, pero lo haremos 
paso a paso.
Primero cambiamos get_prepped_stuff a un dispositivo llamado prepped_stuff . Desea nombrar sus 
aparatos con sustantivos en lugar de verbos debido ala forma en que los aparatos se utilizarán 
en las funciones de prueba más adelante. El @pytest.fixture indica que esta función específica 
debe manejarse como un accesorio en lugar de una función regular.
Ahora debemos actualizar las funciones de prueba para que usen el aparato. Esto se hace 
agregando un parámetro a su definición que coincida exactamente con el nombre del dispositivo. 
Cuando se ejecuta py.test, ejecutará el dispositivo antes de ejecutar la prueba, luego pasará el 
valor de retorno del dispositivo a la función de prueba a través de ese parámetro. (Tenga en 
cuenta que los dispositivos no necesitan devolver un valor; en su lugar, pueden hacer otras 
tareas de configuración, como llamar a un recurso externo, organizar las cosas en el sistema de 
archivos, poner valores en una base de datos, independientemente de las pruebas necesarias 
para la configuración)
Ahora puedes ver por qué lo nombramos con un sustantivo. pero la línea my_stuff = prepped_stuff
es bastante inútil, así que simplemente utilicemos prepped_stuff directamente.
Ahora estamos usando accesorios! Podemos ir más lejos cambiando el alcance del dispositivo
    866/1068
    802
# projectroot/module/stuff.py 
class Stuff(object):
def prep(self): 
self.foo = 1
self.bar = 2
def finish(self):
self.foo = 0
self.bar = 0
@pytest.fixture
def prepped_stuff(request): # we need to pass in the request to use finalizers 
my_stuff = stuff.Stuff()
my_stuff.prep()
def fin(): # finalizer function 
# do all the cleanup here 
my_stuff.finish()
request.addfinalizer(fin) # register fin() as a finalizer 
# you can do more setup here if you really want to 
return my_stuff
@pytest.yield_fixture
(de modo que solo se ejecute una vez por módulo de prueba o sesión de ejecución del conjunto 
de pruebas en lugar de una vez por función de prueba), construyendo dispositivos que utilicen 
otros dispositivos, parametrizando el dispositivo (para que el dispositivo y todo las pruebas que 
usan ese dispositivo se ejecutan varias veces, una vez para cada parámetro dado al dispositivo), 
dispositivos que leen los valores del módulo que los llama ... como se mencionó anteriormente, 
los dispositivos tienen mucha más potencia y flexibilidad que una función de configuración normal.
Limpieza después de las pruebas.
Digamos que nuestro código ha crecido y nuestro objeto Stuff ahora necesita una limpieza 
especial.
Podríamos agregar algún código para llamar a la limpieza al final de cada función de prueba, pero 
los dispositivos proporcionan una mejor manera de hacerlo. Si agrega una función al dispositivo y 
lo registra como finalizador , se llamará al código en la función de finalizador después de que se 
realice la prueba con el dispositivo. Si el alcance del dispositivo es mayor que una sola función 
(como módulo o sesión), el finalizador se ejecutará una vez que se hayan completado todas las 
pruebas en el alcance, por lo que una vez que el módulo haya terminado de ejecutarse o al final 
de toda la sesión de ejecución de prueba .
Usar la función de finalizador dentro de una función puede ser un poco difícil de entender a 
primera vista, especialmente cuando tienes dispositivos más complicados.En su lugar, puede 
utilizarundispositivo de rendimiento para hacerlo mismoconun flujode ejecuciónlegiblemás 
humano. La única diferencia real es que, en lugar de utilizar la return , usamos un yield en la
parte del dispositivo donde se realiza la configuración y el control debeir a una función de prueba, 
luego se agrega todo el código de limpieza después del yield . También lo decoramos como un 
yield_fixture para que py.test sepa cómo manejarlo.
    867/1068
    803
¡Y eso concluye la Introducción a los Aparatos de Prueba!
Para obtener más información, consulte la documentación oficial de la prueba py.test y la 
documentación oficial de la unidad de rendimiento.
def prepped_stuff(): # it doesn't need request now! 
# do setup
my_stuff = stuff.Stuff() 
my_stuff.prep()
# setup is done, pass control to the test functions 
yield my_stuff
# do cleanup 
my_stuff.finish()
    868/1068
    804
"""PyAudio Example: Play a wave file (callback version)."""
import pyaudio 
import wave 
import time 
import sys
if len(sys.argv) < 2:
print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0]) 
sys.exit(-1)
wf = wave.open(sys.argv[1], 'rb') 
# instantiate PyAudio (1)
p = pyaudio.PyAudio()
# define callback (2)
def callback(in_data, frame_count, time_info, status): 
data = wf.readframes(frame_count)
return (data, pyaudio.paContinue)
Capítulo 165: pyaudio
Introducción
PyAudio proporciona enlaces de Python para PortAudio, la biblioteca de E / S de audio 
multiplataforma. Con PyAudio, puede usar Python fácilmente para reproducir y grabar audio en 
una variedad de plataformas. PyAudio está inspirado en:
1.pyPortAudio / fastaudio: enlaces de Python para la API de PortAudio v18. 
2.tkSnack: kit de herramientas de sonido multiplataforma para Tcl / Tk y Python.
Observaciones
Nota: se llama a stream_callback en un hilo separado (del hilo principal). Las excepciones que se 
producen en el stream_callback:
1. Imprima un rastreo de error estándar para ayudar a la depuración,
2 .queue la excepción que se lanzará (en algún momento) en el hilo principal, y
3. Devuelva paAbort a PortAudio para detener la transmisión.
Nota: No llame a Stream.read () ni a Stream.write () si usa una operación sin bloqueo. 
Ver: firma de devolución de llamada de PortAudio para detalles adicionales: 
http://portaudio.com/docs/v19-
doxydocs/portaudio_8h.html#a8a60fb2a5ec9cbade3f54a9c978e2710
Examples
Modo de devolución de llamada de audio I / O
    869/1068
    805
import pyaudio 
import wave 
import sys
CHUNK = 1024
if len(sys.argv) < 2:
print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0]) 
sys.exit(-1)
wf = wave.open(sys.argv[1], 'rb') 
# instantiate PyAudio (1)
p = pyaudio.PyAudio()
Enel modo de devolución de llamada,PyAudio llamará a una función de devolución dellamada 
especificada(2) siempreque necesitenuevosdatos deaudio(para reproducir) y /ocuandohaya 
nuevos datos de audio (grabados)disponibles.Tenga en cuenta quePyAudiollama a la función 
de devolución de llamada en un hilo separado. La función tiene la siguiente callback(<input_data>,
<frame_count>, <time_info>, <status_flag>) firma callback(<input_data>, <frame_count>,
<time_info>, <status_flag>) y debe devolver una tupla que contiene fotogramas frame_count de 
datos de audio y una bandera que indica si hay más frames para reproducir / grabar.
Comience a procesar la transmisión de audio utilizando pyaudio.Stream.start_stream () (4), que 
llamará repetidamente a la función de devolución de llamada hasta que esa función devuelva 
pyaudio.paComplete .
Para mantener el flujo activo, el hilo principal no debe terminar, por ejemplo, durmiendo (5).
Modo de bloqueo de E / S de audio
"" "Ejemplo de PyAudio: reproducir un archivo wave." ""
# open stream using callback (3)
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), 
channels=wf.getnchannels(),
rate=wf.getframerate(), 
output=True, 
stream_callback=callback)
# start the stream (4)
stream.start_stream()
# wait for stream to finish (5) 
while stream.is_active():
time.sleep(0.1)
# stop stream (6) 
stream.stop_stream() 
stream.close() 
wf.close()
# close PyAudio (7) 
p.terminate()
    870/1068
    806
Para usar PyAudio, primero cree una instancia de PyAudio usando pyaudio.PyAudio () (1), que 
configura el sistema portaudio.
Para grabar o reproducir audio, abra una transmisión en el dispositivo deseado con los 
parámetros de audio deseados utilizando pyaudio.PyAudio.open () (2). Esto configura un 
pyaudio.Stream para reproducir o grabar audio.
Reproduce el audio escribiendo datos de audio en la transmisión usando pyaudio.Stream.write 
() , o lee los datos de audio de la transmisión usando pyaudio.Stream.read () . (3)
Tenga en cuenta que en el " modo de bloqueo ", cada pyaudio.Stream.write () o 
pyaudio.Stream.read () se bloquea hasta que todos los cuadros dados / solicitados se hayan 
reproducido / grabado. Alternativamente, para generar datos de audio sobre la marcha o procesar 
inmediatamente los datos de audio grabados, use el "modo de devolución de llamada" ( consulte 
el ejemplo en el modo de devolución de llamada )
Use pyaudio.Stream.stop_stream () para pausar la reproducción / grabación, y
pyaudio.Stream.close () para terminar la transmisión. (4)
Finalmente, finalice la sesión de portaudio utilizando pyaudio.PyAudio.terminate () (5) 
# open stream (2)
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), 
channels=wf.getnchannels(),
rate=wf.getframerate(), 
output=True)
# read data
data = wf.readframes(CHUNK)
# play stream (3) 
while len(data) > 0:
stream.write(data)
data = wf.readframes(CHUNK)
# stop stream (4) 
stream.stop_stream() 
stream.close()
# close PyAudio (5) 
p.terminate()
    871/1068
    807
pip install pygame
Capítulo 166: pygame
Introducción
Pygame es la biblioteca de acceso para hacer aplicaciones multimedia, especialmente juegos, en 
Python. El sitio web oficial es http://www.pygame.org/ .
Sintaxis
• pygame.mixer.init (frecuencia = 22050, tamaño = -16, canales = 2, búfer = 4096)
• pygame.mixer.pre_init (frecuencia, tamaño, canales, búfer)
• pygame.mixer.quit ()
• pygame.mixer.get_init ()
• pygame.mixer.stop ()
• pygame.mixer.pause ()
• pygame.mixer.unpause ()
• pygame.mixer.fadeout (tiempo)
• pygame.mixer.set_num_channels (count)
• pygame.mixer.get_num_channels ()
• pygame.mixer.set_reserved (cuenta)
• pygame.mixer.find_channel (force)
• pygame.mixer.get_busy ()
Parámetros
Parámetro Detalles
contar
Un entero positivo que representa algo así como la cantidad de canales 
necesarios para ser reservados.
fuerza
Un valor booleano ( False o True ) que determina si find_channel() tiene que 
devolver un canal (inactivo o no) con True o no (si no hay canales inactivos) con
False
Examples
Instalando pygame
Con pip
Con conda :
    872/1068
    808
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=4096)
Descarga directa desde el sitio web: http://www.pygame.org/download.shtml
Puede encontrar los instaladores adecuados para Windows y otros sistemas operativos. 
Los proyectos también se pueden encontrar en http://www.pygame.org/
Modulo mezclador de pygame
El módulo pygame.mixer ayuda a controlar la música utilizada en los programas de pygame . A partir 
de ahora, hay 15 funciones diferentes para el módulo mixer.
Inicializando
De manera similar a cómo tienes que inicializar pygame con pygame.init() , también debes 
inicializar pygame.mixer .
Al usar la primera opción, inicializamos el módulo usando los valores predeterminados. Puede, sin 
embargo, anular estas opciones predeterminadas. Al usar la segunda opción, podemos inicializar 
el módulo usando los valores que manualmente ingresamos en nosotros mismos. Valores 
estándar:
Para verificar si lo hemos inicializado o no, podemos usar pygame.mixer.get_init() , que devuelve 
True si es y False si no lo es. Para salir / deshacer la inicialización, simplemente use 
pygame.mixer.quit() .Si desea continuar reproduciendo sonidos con el módulo, es posible que 
deba reinicializar el módulo.
Posibles acciones
Mientras se reproduce su sonido, puede pausarlo temporalmente con pygame.mixer.pause() . Para 
reanudar la reproducción de sus sonidos, simplemente use pygame.mixer.unpause() . También 
puedes desvanecer el final del sonido utilizando pygame.mixer.fadeout() . Se necesita un 
argumento, que es la cantidad de milisegundos que se tarda en terminar de desvanecerse la 
música.
Los canales
Puede reproducir tantas canciones como sea necesario siempre que haya suficientes canales 
abiertos para admitirlas. Por defecto, hay 8 canales. Para cambiar la cantidad de canales que 
hay, use pygame.mixer.set_num_channels() . El argumento es un entero no negativo. Si la cantidad
de canales disminuye, cualquier sonido que se reproduzca en los canales eliminados se detendrá
conda install -c tlatorre pygame=1.9.2
    873/1068
    809
de inmediato.
Para saber cuántos canales se están utilizando actualmente, llame a
pygame.mixer.get_channels(count) . La salida es el número de canales que no están abiertos 
actualmente. También puede reservar canales para los sonidos que deben reproducirse utilizando 
pygame.mixer.set_reserved(count) . El argumento también es un entero no negativo. Cualquier 
sonido que se reproduzca en los canales recién reservados no se detendrá.
También puede averiguar qué canal no se está utilizando mediante el uso de 
pygame.mixer.find_channel(force) . Su argumento es un bool: verdadero o falso. Si no hay canales 
que estén inactivos y la force sea Falso, devolverá None . Si la force es verdadera, devolverá el 
canal que ha estado tocando durante más tiempo.
    874/1068
    810
import pyglet
window = pyglet.window.Window()
label = pyglet.text.Label('Hello, world',
font_name='Times New Roman', 
font_size=36,
x=window.width//2, y=window.height//2, 
anchor_x='center', anchor_y='center')
@window.event 
def on_draw():
window.clear() 
label.draw()
pyglet.app.run()
pip3 install pyglet
sound = pyglet.media.load(sound.wav) 
sound.play()
import pyglet
from pyglet.gl import *
Capítulo 167: Pyglet
Introducción
Pyglet es un módulo de Python utilizado para efectos visuales y de sonido. No tiene 
dependencias en otros módulos. Ver [pyglet.org] [1] para la información oficial. [1]: 
http://pyglet.org
Examples
Hola Mundo en Pyglet
Instalación de Pyglet
Instala Python, entra en la línea de comandos y escribe: 
Python 2:
Python 3:
Reproducción de sonido en Pyglet
Usando Pyglet para OpenGL
pip install pyglet
    875/1068
    811
import pyglet
from pyglet.gl import *
win = pyglet.window.Window() 
glClear(GL_COLOR_BUFFER_BIT)
@win.event 
def on_draw():
glBegin(GL_POINTS)
glVertex2f(x, y) #x is desired distance from left side of window, y is desired distance 
from bottom of window
#make as many vertexes as you want 
glEnd
Dibujar puntos usando Pyglet y OpenGL
Para conectar los puntos, reemplace GL_POINTS con GL_LINE_LOOP . 
win = pyglet.window.Window() 
@win.event()
def on_draw():
#OpenGL goes here. Use OpenGL as normal.
pyglet.app.run()
    876/1068
    812
pip install pyinstaller
Capítulo 168: PyInstaller - Distribuir código 
de Python
Sintaxis
• pyinstaller [opciones] script [script ...] | archivo de especificaciones
Observaciones
PyInstaller es un módulo utilizado para agrupar aplicaciones de Python en un solo paquete junto 
con todas las dependencias. El usuario puede ejecutar la aplicación del paquete sin un intérprete 
de Python o cualquier módulo. Combina correctamente muchos paquetes importantes como 
numpy, Django, OpenCv y otros.
Algunos puntos importantes para recordar:
• Pyinstaller es compatible con Python 2.7 y Python 3.3+
• Pyinstaller ha sido probado contra Windows, Linux y Mac OS X.
• NO es un compilador cruzado. (Una aplicación de Windows no se puede empaquetar en 
Linux. Debe ejecutar PyInstaller en Windows para agrupar una aplicación para Windows)
Página de inicio documentos oficiales
Examples
Instalación y configuración
Pyinstaller es un paquete normal de Python. Se puede instalar utilizando pip:
Instalación en Windows
Para Windows, pywin32 o pypiwin32 es un requisito previo. Este último se instala 
automáticamente cuando se instala pyinstaller usando pip.
Instalación en Mac OS X
PyInstaller funciona con el Python 2.7 predeterminado que se proporciona con el Mac OS X 
actual. Si se van a usar versiones posteriores de Python o si se deben usar paquetes importantes 
como PyQT, Numpy, Matplotlib y similares, se recomienda instalarlos usando ya sea MacPorts o 
Homebrew .
Instalación desde el archivo
Si pip no está disponible, descargue el archivo comprimido desde PyPI .
Para probar la versión de desarrollo, descargue el archivo comprimido desde la rama de
    877/1068
    813
desarrollo de la página de descargas de PyInstaller .
Expandaelarchivoyencuentreel scriptsetup.py .Ejecutepython setup.py install conprivilegio 
de administrador para instalar o actualizar PyInstaller.
Verificando la instalación
El comando pyinstaller debería existir en la ruta del sistema para todas las plataformas después 
de una instalación exitosa.
pyinstaller --version escribiendo pyinstaller --version en la línea de comando. Esto imprimirá la 
versión actual de pyinstaller.
Usando Pyinstaller
En el caso de uso más simple, simplemente navegue hasta el directorio en el que se encuentra su 
archivo y escriba:
pyinstaller myfile.py
Pyinstaller analiza el archivo y crea:
• Un archivo myfile.spec en el mismo directorio que myfile.py
• Una carpeta de compilación en el mismo directorio que myfile.py
• Una carpeta dist en el mismo directorio que myfile.py
• Archivos de registro en la carpeta de compilación
La aplicación incluida se puede encontrar en la carpeta dist 
Opciones
Hay varias opciones que se pueden usar con pyinstaller. Una lista completa de las opciones se 
puede encontrar aquí .
Una vez que su aplicación se puede empaquetar, abra 'dist \ myfile \ myfile.exe'.
Agrupar en una carpeta
Cuando se usa PyInstaller sin ninguna opción para agrupar myscript.py , la salida predeterminada 
es una única carpeta (denominada myscript ) que contiene un ejecutable llamado myscript ( 
myscript.exe en Windows) junto con todas las dependencias necesarias.
La aplicación se puede distribuir comprimiendo la carpeta en un archivo zip.
El mododeunacarpetasepuedeconfigurar explícitamente con la opción-D o--onedir 
pyinstaller myscript.py -D
Ventajas:
Una de las principales ventajas de agrupar en una sola carpeta es que es más fácil depurar 
problemas. Si alguno de los módulos no se puede importar, puede verificarse inspeccionando la
    878/1068
    814
carpeta.
Otra ventaja se siente durante las actualizaciones. Si hay algunos cambios en el código pero las 
dependencias utilizadas son exactamente las mismas, los distribuidores pueden enviar el archivo 
ejecutable (que generalmente es más pequeño que la carpeta completa).
Desventajas
La única desventaja de este método es que los usuarios tienen que buscar el ejecutable entre una 
gran cantidad de archivos.
Además, los usuarios pueden eliminar / modificar otros archivos, lo que puede hacer que la 
aplicación no funcione correctamente.
Agrupar en un solo archivo
pyinstaller myscript.py -F
Lasopciones paragenerar unsoloarchivo son-F o--onefile .Estomyscript.exe el programaen 
un solo archivo myscript.exe .
Un solo archivo ejecutable es más lento que el paquete de una carpeta. También son más 
difíciles de depurar.
    879/1068
    815
from ply import lex 
import ply.yacc as yacc
tokens = (
'PLUS',
'MINUS',
'TIMES',
'DIV',
'LPAREN',
'RPAREN',
Capítulo 169: Python Lex-Yacc
Introducción
PLY es una implementación pura de Python de las populares herramientas de construcción de 
compiladores lex y yacc.
Observaciones
Enlaces adicionales:
1. Documentos oficiales
2. Github
Examples
Empezando con PLY
Para instalar PLY en su máquina para python2 / 3, siga los pasos descritos a continuación:
1. Descarga el código fuente desde aquí .
2. Descomprima el archivo zip descargado.
3. Navegue en la carpeta ply-3.10 descomprimida
4. Ejecute el siguiente comando en su terminal: python setup.py install
Sicompletó todolo anterior, ahoradeberíapoderusarel móduloPLY.Puedeprobarloabriendo 
un intérprete de python y escribiendo import ply.lex.
Nota: No utilice pip para instalar PLY, se instalará una distribución rota en su máquina.
El "¡Hola mundo!" de PLY - Una calculadora simple
Demostremos el poder de PLY con un ejemplo simple: este programa tomará una expresión 
aritmética como una entrada de cadena e intentará resolverla.
Abre tu editor favorito y copia el siguiente código:
    880/1068
    816
'NUMBER',
)
t_ignore = ' \t'
t_PLUS = r'\+' 
t_MINUS = r'-'
t_TIMES = r'\*' 
t_DIV = r'/' 
t_LPAREN = r'\(' 
t_RPAREN = r'\)'
deft_NUMBER(t): 
r'[0-9]+'
t.value = int( t.value ) 
return t
def t_newline( t): 
r'\n+'
t.lexer.lineno += len( t.value )
def t_error( t ):
print("Invalid Token:",t.value[0]) 
t.lexer.skip( 1 )
lexer = lex.lex() 
precedence = (
( 'left', 'PLUS', 'MINUS' ),
( 'left', 'TIMES', 'DIV' ),
( 'nonassoc', 'UMINUS' )
)
def p_add( p ) :
'expr : expr PLUS expr' 
p[0] = p[1] + p[3]
def p_sub( p ) :
'expr : expr MINUS expr' 
p[0] = p[1] - p[3]
def p_expr2uminus( p ) :
'expr: MINUS expr %prec UMINUS' 
p[0] = - p[2]
def p_mult_div( p ) :
'''expr : expr TIMES expr
| expr DIV expr'''
if p[2] == '*' :
p[0] = p[1] * p[3]
else :
if p[3] == 0 :
print("Can't divide by 0")
raise ZeroDivisionError('integer division by 0') 
p[0] = p[1] / p[3]
defp_expr2NUM(p): 
'expr: NUMBER' 
p[0] = p[1]
    881/1068
    817
import ply.lex as lex
# List of token names. This is always required 
tokens = [
'NUMBER',
'PLUS',
'MINUS',
'TIMES',
'DIVIDE',
'LPAREN',
'RPAREN',
]
# Regular expression rules for simple tokens
# A regular expression rule with some action code 
def t_NUMBER(t):
r'\d+'
t.value = int(t.value)
return t
Guarde este archivo como calc.py y ejecútelo. 
Salida:
¿Cuál es la respuesta correcta para -4 * - (3 - 5) ?
Parte 1: Tokenizing entrada con Lex
Hay dos pasos que llevó a cabo el código del ejemplo 1: uno fue tokenizar la entrada, lo que 
significa que buscó los símbolos que constituyen la expresión aritmética, y el segundo paso fue 
analizar , lo que implica analizar los tokens extraídos y evaluar el resultado.
Esta sección proporciona un ejemplo simple de cómo tokenizar la entrada del usuario, y luego la 
divide línea por línea.
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_LPAREN = r'\('
t_RPAREN = r'\)'
-8
def p_parens( p ) :
'expr : LPAREN expr RPAREN' 
p[0] = p[2]
def p_error( p ):
print("Syntax error in input!") 
parser = yacc.yacc()
res = parser.parse("-4*-(3-5)") # the input 
print(res)
    882/1068
    818
tokens = [
'NUMBER',
'PLUS',
'MINUS',
'TIMES',
'DIVIDE',
'LPAREN',
'RPAREN',
]
Guarde este archivo como calclex.py . Usaremos esto cuando construyamos nuestro analizador 
de Yacc.
Descompostura
1. Importe el módulo usando import ply.lex
2. Todos los lexers deben proporcionar una lista llamada tokens que define todos los posibles 
nombres de token que puede producir el lexer. Esta lista siempre es obligatoria.
tokens también podrían ser una tupla de cadenas (en lugar de una cadena), donde cada cadena 
denota un token como antes.
3. La regla de expresiones regulares para cada cadena puede definirse como una cadena o 
como una función. En cualquier caso, el nombre de la variable debe tener el prefijo t_ para 
denotar que es una regla para hacer coincidir tokens.
# Define a rule so we can track line numbers 
def t_newline(t):
r'\n+'
t.lexer.lineno += len(t.value)
#Astringcontainingignoredcharacters(spacesandtabs) 
t_ignore = ' \t'
# Error handling rule 
def t_error(t):
print("Illegal character '%s'" % t.value[0]) 
t.lexer.skip(1)
# Build the lexer 
lexer = lex.lex()
# Give the lexer some input 
lexer.input(data)
# Tokenize 
while True:
tok = lexer.token() 
if not tok:
break # No more input 
print(tok)
    883/1068
    819
def t_NUMBER(t): 
r'\d+'
t.value = int(t.value) 
return t
def t_newline(t): 
r'\n+'
t.lexer.lineno += len(t.value)
def t_COMMENT(t): 
r'\#.*'
pass
# No return value. Token discarded
• Para tokens simples, la expresión regular se puede especificar como cadenas: t_PLUS
= r'\+'
• Si es necesario realizar algún tipo de acción, se puede especificar una regla de token 
como una función.
Tenga en cuenta que la regla se especifica como una cadena de documentación 
dentro de la función. La función acepta un argumento que es una instancia de LexToken
, realiza alguna acción y luego devuelve el argumento.
Si desea usar una cadena externa como regla de expresión regular para la función en 
lugar de especificar una cadena de documentación, considere el siguiente ejemplo:
@TOKEN(identifier) 
def t_ID(t):
... #actions
# identifier is a string holding the regex
• Unainstanciadeobjeto LexToken(llamemosaesteobjetot)tienelossiguientes 
atributos:
1. t.typeque es el tipo de token (como una cadena) (por ejemplo: 'NUMBER' , 'PLUS' , 
etc.). Por defecto, t.type se establece en el nombre que sigue al prefijo t_ .
2. t.value que es el lexema (el texto real t.value )
3. t.lineno que es el número de línea actual (esto no se actualiza automáticamente, 
ya que el lexer no sabe nada de los números de línea). Actualiza lineno usando 
una función llamada t_newline .
4. t.lexpos que es la posición del token en relación con el comienzo del texto de 
entrada.
• Si no se devuelve nada de una función de regla de expresiones regulares, el token se 
descarta. Si desea descartar un token, alternativamente puede agregar el prefijo 
t_ignore_ a una variable de regla de expresiones regulares en lugar de definir una 
función para la misma regla.
...Es lo mismo que:
    884/1068
    820
t_ignore_COMMENT = r'\#.*'
t_ignore = ' \t' # ignores spaces andtabs
literals = [ '+', '-', '*', '/' ]
literals = "+-*/"
literals = [ '{', '}' ]
def t_lbrace(t): 
r'\{'
t.type = '{' #Set token type to the expected literal (ABSOLUTEMUST if this 
is a literal)
return t
# Error handling rule 
def t_error(t):
print("Illegal character '%s'" % t.value[0]) 
t.lexer.skip(1) # skip the illegal token (don't process it)
Por supuesto, esto no es válido si está realizando alguna acción cuando ve un comentario. En cuyo 
caso, use una función para definir la regla de expresiones regulares.
Si no ha definido un token para algunos caracteres pero aún quiere ignorarlo, use
t_ignore = "<characters to ignore>" (estos prefijos son necesarios):
• Al crear la expresión regular maestra, lex agregará las expresiones regulares 
especificadas en el archivo de la siguiente manera:
1. Las fichas definidas por funciones se agregan en el mismo orden en que 
aparecen en el archivo.
2. Los tokens definidos por cadenas se agregan en orden decreciente de la longitud 
de la cadena que define la expresión regular para ese token.
Si coincide == y = en el mismo archivo, aproveche estas reglas.
• Los literales son tokens que se devuelven como son. Tanto t.type como t.valuese 
establecerán en el propio carácter. Defina una lista de literales como tales:
o,
Es posible escribir funciones de token que realizan acciones adicionales cuando se 
combinan literales. Sin embargo, deberás configurar el tipo de token de forma 
adecuada. Por ejemplo:
• Manejar errores con la función t_error.
t_ignore_COMMENT = r'\#.*'
    885/1068
    821
# Build the lexer 
#
m = MyLexer() 
m.build() 
m.test("3 + 4")
# Build the lexer
def build(self, **kwargs):
self.lexer = lex.lex(module=self, **kwargs)
def test(self, data): 
self.lexer.input(data)
for token in self.lexer.token(): 
print(token)
# Build the lexer and try it out
usual
... # everything relating to token rules and error handling comes here as
import ply.lex as lex 
class MyLexer(object):
for i in lexer: 
print(i)
# Yacc example
import ply.yacc as yacc
# Get the token map from the lexer. This is required. 
from calclex import tokens
def p_expression_plus(p):
'expression : expression PLUS term' 
p[0] = p[1] + p[3]
En general, t.lexer.skip(n) omite n caracteres en la cadena de entrada.
4. Preparativos finales
Construya el lexer usando lexer = lex.lex() .
También puede colocar todo dentro de una clase y llamar a la instancia de uso de la clase 
para definir el lexer. P.ej:
Proporcione entrada utilizando lexer.input(data) donde los datos son una cadena
Para obtener los tokens, use lexer.token() que devuelve tokens coincidentes. Puede iterar 
sobre lexer en un bucle como en:
Parte 2: Análisis de entrada Tokenized con Yacc
Esta sección explica cómo se procesa la entrada tokenizada de la Parte 1: se realiza utilizando 
las gramáticas libres de contexto (CFG). Se debe especificar la gramática y los tokens se 
procesan de acuerdo con la gramática. Bajo el capó, el analizador utiliza un analizador LALR.
    886/1068
    822
def p_expression_plus(p):
'expression : expression PLUS term'
def p_expression_minus(p):
'expression : expression MINUS term' 
p[0] = p[1] - p[3]
def p_expression_term(p): 
'expression : term' 
p[0] = p[1]
def p_term_times(p):
'term:termTIMESfactor' 
p[0] = p[1] *p[3]
def p_term_div(p):
'term:termDIVIDEfactor' 
p[0] = p[1] / p[3]
def p_term_factor(p): 
'term : factor' 
p[0] = p[1]
def p_factor_num(p): 
'factor: NUMBER' 
p[0] = p[1]
def p_factor_expr(p):
'factor : LPAREN expression RPAREN' 
p[0] = p[2]
# Error rule for syntax errors 
def p_error(p):
print("Syntax error in input!")
# Build the parser 
parser = yacc.yacc()
while True: 
try:
s = raw_input('calc > ') 
except EOFError:
break
if not s: continue 
result = parser.parse(s) 
print(result)
Descompostura
• Cada regla gramatical está definida por una función donde la cadena de documentación de 
esa función contiene la especificación gramatical libre de contexto apropiada. Las 
declaraciones que conforman el cuerpo de la función implementan las acciones semánticas 
de la regla. Cada función acepta un solo argumento p que es una secuencia que contiene 
los valores de cada símbolo gramatical en la regla correspondiente. Los valores de p[i] se 
asignan a símbolos gramaticales como se muestra aquí:
    887/1068
    823
p[0] = p[1] + p[3]
def p_binary_operators(p):
'''expression : expression PLUS term
| expression MINUS term
term : term TIMES factor
| termDIVIDEfactor''' 
if p[2] == '+':
p[0] = p[1] + p[3]
elif p[2] == '-':
p[0] = p[1] - p[3]
elif p[2] == '*':
p[0] = p[1] * p[3]
elif p[2] == '/':
p[0] = p[1] / p[3]
def p_binary_operators(p): 
'''expression : expression '+' term
|expression'-'term
term : term '*' factor
| term '/' factor''' 
if p[2] == '+':
p[0] = p[1] + p[3]
elif p[2] == '-':
p[0] = p[1] - p[3]
elif p[2] == '*':
p[0] = p[1] * p[3]
elif p[2] == '/':
p[0] = p[1] / p[3]
# ^ ^ ^ ^
# p[0] p[1] p[2] p[3]
• Para los tokens, el "valor" de la p[i] es el mismo que el atributo p.value asignado en el 
módulo lexer. Por lo tanto, PLUS tendrá el valor + .
• Para no terminales, el valor se determina por lo que se coloque en p[0] . Si no se coloca 
nada, el valor es Ninguno. Además, p[-1] no es lo mismo que p[3] , ya que p no es una lista 
simple ( p[-1] puede especificar acciones incrustadas (no se trata aquí)).
Tenga en cuenta que la función puede tener cualquier nombre, siempre que esté precedida por p_
.
• La p_error(p) se define para detectar errores de sintaxis (igual que yyerror en yacc / bison).
• Se pueden combinar varias reglas gramaticales en una sola función, lo que es una buena 
idea si las producciones tienen una estructura similar.
• Se pueden usar caracteres literales en lugar de fichas.
Por supuesto, los literales deben especificarse en el módulo lexer.
• Lasproduccionesvacíastienenlaforma'''symbol:'''
    888/1068
    824
precedence = (
('nonassoc', 'LESSTHAN', 'GREATERTHAN'), # Nonassociative operators 
('left', 'PLUS', 'MINUS'),
('left', 'TIMES', 'DIVIDE'),
('right', 'UMINUS'), # Unary minus operator
)
• Paraestablecerexplícitamenteelsímbolodeinicio,usestart = 'foo',dondefooesalgo 
que no es terminal.
• La configuración de la precedencia y la asociatividad se puede hacer utilizando la variable 
de precedencia.
Los tokens se ordenan de menor a mayor precedencia. nonassoc significa que esos tokens 
no se asocian. Esto significa que algo como a < b < c es ilegal mientras que a < b todavía 
es legal.
• parser.outesunarchivodedepuraciónquesecreacuandoseejecutaelprogramayaccpor 
primeravez.Cadavezqueseproduceunconflictodedesplazamiento/reducción,el 
analizador siempre cambia.
    889/1068
    825
from requests import post
foo = post('http://httpbin.org/post', data = {'key':'value'})
print(foo.headers)
{'Content-Length':'439','X-Processed-Time':'0.000802993774414','X-Powered-By':'Flask', 
'Server': 'meinheld/0.6.1', 'Connection': 'keep-alive', 'Via': '1.1 vegur', 'Access-ControlAllow-Credentials':'true','Date':'Sun,21May201720:56:05GMT','Access-Control-AllowOrigin': '*', 'Content-Type': 'application/json'}
headers = {'Cache-Control':'max-age=0', 
'Upgrade-Insecure-Requests':'1',
'User-Agent':'Mozilla/5.0 (WindowsNT10.0;Win64; x64) AppleWebKit/537.36 (KHTML, 
like Gecko) Chrome/54.0.2840.99 Safari/537.36',
'Content-Type':'application/x-www-form-urlencoded', 
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 
'Referer':'https://www.groupon.com/signup',
'Accept-Encoding':'gzip, deflate, br', 
'Accept-Language':'es-ES,es;q=0.8'
}
foo = post('http://httpbin.org/post', headers=headers, data = {'key':'value'})
Capítulo 170: Python Requests Post
Introducción
Documentación para el módulo de solicitudes de Python en el contexto del método HTTP POST y 
su función de solicitudes correspondiente
Examples
Post simple
Realizará una simple operación HTTP POST. Los datos publicados pueden ser en la mayoría de 
los formatos, sin embargo, los pares de valores clave son los más frecuentes.
Encabezados
Los encabezados pueden ser vistos:
Un ejemplo de respuesta:
Los encabezados también se pueden preparar antes de la publicación:
Codificación
La codificación se puede configurar y ver de la misma manera:
    890/1068
    826
foo = post('http://httpbin.org/post', data = {'key':'value'}, verify=False)
foo = post('http://httpbin.org/post', data = {'key':'value'}, allow_redirects=False)
print(foo.url)
print(foo.history)
from requests import post
payload = {'key1' : 'value1',
'key2' : 'value2'
}
foo = post('http://httpbin.org/post', data=payload)
from requests import post
payload = {'key1' : 'value1', 'key2' : 'value2'} 
foo = post('http://httpbin.org/post',json=payload)
Verificación SSL
Las solicitudes por defecto valida los certificados SSL de los dominios. Esto puede ser anulado:
Redireccion
Se seguirá cualquier redirección (por ejemplo, http a https), esto también se puede cambiar:
Si la operación posterior se ha redirigido, se puede acceder a este valor:
Se puede ver un historial completo de redirecciones:
Formulario de datos codificados
Para pasar datos codificados de forma con la operación posterior, los datos deben estructurarse 
como diccionario y suministrarse como el parámetro de datos.
Si los datos no desean estar codificados en forma, simplemente pase una cadena o un entero al 
parámetro de datos.
Suministre el diccionario al parámetro json para que Solicitudes formateen los datos 
automáticamente:
print(foo.encoding) 
'utf-8'
foo.encoding = 'ISO-8859-1'
    891/1068
    827
from requests import post
files = {'file' : open('data.txt', 'rb')} 
foo = post('http://http.org/post',files=files)
files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel',
{'Expires': '0'})}
foo = requests.post('http://httpbin.org/post', files=files)
multiple_files = [
('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
foo = post('http://httpbin.org/post', files=multiple_files)
from requests import post
foo = post('http://httpbin.org/post', data={'data' : 'value'}) 
print(foo.status_code)
foo = post('http://httpbin.org/post', data={'data' : 'value'}) 
print(foo.text)
Subir archivo
Conel módulodesolicitudes, solo esnecesarioproporcionarunidentificadordearchivoen lugar 
de los contenidos recuperados con .read() :
Nombre de archivo, tipo de contenido y encabezados también se pueden configurar:
Lascadenas tambiénsepuedenenviarcomo unarchivo, siemprequeseproporcionencomoel 
parámetro de files .
Múltiples archivos
Se pueden suministrar varios archivos de la misma manera que un archivo:
Respuestas
Los códigos de respuesta se pueden ver desde una operación posterior:
Datos devueltos
Accediendo a los datos que se devuelven:
Respuestas crudas
En los casos en que necesite acceder al objeto subyacente urllib3 response.HTTPResponse, esto 
se puede hacer de la siguiente manera:
    892/1068
    828
from requests import post
foo = post('http://natas0.natas.labs.overthewire.org', auth=('natas0', 'natas0'))
from requests import post
from requests.auth import HTTPBasicAuth
foo = post('http://natas0.natas.labs.overthewire.org', auth=HTTPBasicAuth('natas0', 'natas0'))
from requests import post
from requests.auth import HTTPDigestAuth
foo = post('http://natas0.natas.labs.overthewire.org', auth=HTTPDigestAuth('natas0', 
'natas0'))
from requests.auth import AuthBase
from requests.auth import _basic_auth_str
from requests._internal_utils import to_native_string 
class CustomAuth(AuthBase):
def init (self, secret_header, user_agent , username, password): 
# setup any auth-related datahere
Autenticación
Autenticación HTTP simple
La autenticación HTTP simple se puede lograr con lo siguiente:
Esta es una mano técnicamente corta para lo siguiente:
Autentificación HTTP Digest
La autenticación HTTP Digest se realiza de una manera muy similar, las solicitudes proporcionan 
un objeto diferente para esto:
Autenticación personalizada
En algunos casos, los mecanismos de autenticación integrados pueden no ser suficientes, 
imagine este ejemplo:
Un servidor está configurado para aceptar la autenticación si el remitente tiene la cadena de 
usuario-agente correcta, un cierto valor de encabezado y proporciona las credenciales correctas a 
través de la autenticación básica HTTP. Para lograr esto, se debe preparar una clase de 
autenticación personalizada, subclasificando AuthBase, que es la base para las 
implementaciones de autenticación de solicitudes:
foo = post('http://httpbin.org/post', data={'data' : 'value'}) 
res = foo.raw
print(res.read())
    893/1068
    829
foo = get('http://test.com/admin', auth=CustomAuth('SecretHeader', 'CustomUserAgent', 'user', 
'password' ))
from requests import post
proxies = {
'http': 'http://192.168.0.128:3128',
'https': 'http://192.168.0.127:1080',
}
foo = requests.post('http://httpbin.org/post', proxies=proxies)
proxies = {'http': 'http://user:pass@192.168.0.128:312'} 
foo = requests.post('http://httpbin.org/post', proxies=proxies)
proxies = {
'http': 'socks5://user:pass@host:port', 
'https': 'socks5://user:pass@host:port'
}
foo = requests.post('http://httpbin.org/post', proxies=proxies)
Esto puede ser utilizado con el siguiente código:
Proxies
Cada operación POST de solicitud puede configurarse para usar proxies de red
Proxies HTTP / S
La autenticación básica HTTP se puede proporcionar de esta manera:
SOCKS Proxies
El uso de proxies de calcetines requiere requests[socks] dependencias de terceros requests[socks]
; una vez instalados, los proxies de calcetines se utilizan de manera muy similar a 
HTTPBasicAuth:
self.secret_header = secret_header 
self.user_agent = user_agent 
self.username = username 
self.password = password
def call (self, r):
# modify and return the request r.headers['XSecret'] = self.secret_header r.headers['UserAgent'] = self.user_agent
r.headers['Authorization'] = _basic_auth_str(self.username, self.password)
return r
    894/1068
    830
import os, sys
from openpyxl import Workbook 
from datetime import datetime
dt = datetime.now()
list_values = [["01/01/2016", "05:00:00", 3],\
["01/02/2016", "06:00:00",4],\
["01/03/2016", "07:00:00",5],\
["01/04/2016", "08:00:00",6],\
["01/05/2016", "09:00:00", 7]]
# Create a Workbook on Excel:
wb = Workbook() 
sheet = wb.active 
sheet.title = 'data'
# Print the titles into Excel Workbook:
row = 1
sheet['A'+str(row)] = 'Date'
sheet['B'+str(row)] = 'Hour' 
sheet['C'+str(row)] = 'Value'
# Populate with data
for item in list_values: 
row += 1
sheet['A'+str(row)] = item[0] 
sheet['B'+str(row)] = item[1] 
sheet['C'+str(row)] = item[2]
# Save a file by date:
filename = 'data_' + dt.strftime("%Y%m%d_%I%M%S") + '.xlsx' 
wb.save(filename)
# Open the file for the user: 
os.chdir(sys.path[0])
os.system('start excel.exe "%s\\%s"' % (sys.path[0], filename, ))
import openpyxl as opx
#To change an existing wookbook we located it by referencing its path 
workbook = opx.load_workbook(workbook_path)
Capítulo 171: Python y Excel
Examples
Ponga los datos de la lista en un archivo de Excel.
OpenPyXL
OpenPyXL es un módulo para manipular y crear libros de trabajo xlsx/xlsm/xltx/xltm en la 
memoria.
Manipulando y leyendo un libro existente:
    895/1068
    831
workbook = opx.load_workbook(workbook_path, read_only=True)
first_sheet = workbook.worksheets[0]
sheet = workbook.get_sheet_by_name('Sheet Name')
for row in sheet.rows: 
print row[0].value
#Calling the Workbook() function creates a new book in memory 
wb = opx.Workbook()
#We can then create a new sheet in the wb
ws = wb.create_sheet('Sheet Name', 0) #0 refers to the index of the sheet order in the wb
ws.sheet_properties.tabColor = 'FFC0CB'
wb.save('filename.xlsx')
import xlsxwriter
# sample data 
chart_data = [
{'name': 'Lorem', 'value': 23},
{'name': 'Ipsum', 'value': 48},
{'name': 'Dolor', 'value': 15},
load_workbook() contiene el parámetro read_only , estableciendo esto en True cargará el libro como 
read_only, esto es útil cuando se leen archivos xlsx más grandes:
Una vez que haya cargado el libro en la memoria, puede acceder a las hojas individuales 
utilizando workbook.sheets
Si desea especificar el nombre de una hoja disponible, puede usar workbook.get_sheet_names() .
Finalmente, se puede acceder a las filas de la hoja utilizando sheet.rows . Para iterar sobre las 
filas de una hoja, use:
Dado que cada row en rows es una lista de Cell , use Cell.value para obtener el contenido de la 
Celda.
Creando un nuevo libro de ejercicios en la memoria:
Se pueden cambiar varias propiedades de la pestaña a través de openpyxl, por ejemplo el
tabColor :
Para guardar nuestro libro creado terminamos con:
Crear gráficos de Excel con xlsxwriter
    896/1068
    832
{'name': 'Sit', 'value': 8},
{'name': 'Amet', 'value': 32}
]
# excel file path 
xls_file = 'chart.xlsx'
# the workbook
workbook = xlsxwriter.Workbook(xls_file)
# add worksheet to workbook 
worksheet = workbook.add_worksheet()
row_ = 0
col_ = 0
# write headers 
worksheet.write(row_, col_, 'NAME') 
col_ += 1
worksheet.write(row_, col_, 'VALUE') 
row_ += 1
# write sample data 
for item in chart_data:
col_ = 0
worksheet.write(row_, col_, item['name']) 
col_ += 1
worksheet.write(row_, col_, item['value']) 
row_ += 1
# create pie chart
pie_chart = workbook.add_chart({'type': 'pie'})
# add series to pie chart 
pie_chart.add_series({
'name': 'Series Name',
'categories': '=Sheet1!$A$3:$A$%s' % row_, 
'values': '=Sheet1!$B$3:$B$%s' % row_, 
'marker': {'type': 'circle'}
})
# insert pie chart 
worksheet.insert_chart('D2', pie_chart)
# create column chart
column_chart = workbook.add_chart({'type': 'column'})
# add serie to column chart
column_chart.add_series({ 
'name': 'Series Name',
'categories': '=Sheet1!$A$3:$A$%s' % row_, 
'values': '=Sheet1!$B$3:$B$%s' % row_, 
'marker': {'type': 'circle'}
})
# insert column chart 
worksheet.insert_chart('D20', column_chart)
workbook.close()
Resultado:
    897/1068
    833
pip install xlrd
Lee los datos de excel usando el módulo xlrd
La biblioteca xlrd de Python es para extraer datos de los archivos de hoja de cálculo de Microsoft 
Excel (tm).
Instalación:-
O puedes usar el archivo setup.py de pypi 
https://pypi.python.org/pypi/xlrd
    898/1068
    834
import xlrd 
book=xlrd.open_workbook('sample.xlsx')
print book.nsheets
print book.sheet_names()
sheet=book.sheet_by_index(1)
cell =sheet.cell(row,col) #where row=rownumber andcol=column number 
print cell.value #to print the cell contents
num_rows=sheet.nrows 
num_col=sheet.ncols
sheets = book.sheet_names()
cur_sheet = book.sheet_by_name(sheets[0])
import xlsxwriter
# create a new file
workbook = xlsxwriter.Workbook('your_file.xlsx')
# add some new formats to be used by the workbook 
percent_format = workbook.add_format({'num_format': '0%'})
percent_with_decimal = workbook.add_format({'num_format': '0.0%'}) 
bold = workbook.add_format({'bold': True})
red_font = workbook.add_format({'font_color': 'red'}) 
remove_format = workbook.add_format()
# add a new sheet
worksheet = workbook.add_worksheet()
Leyendo una hoja de Excel: - Importe el módulo xlrd y abra el archivo de Excel usando el 
método open_workbook ().
Consultar número de hojas en el excel.
Imprimir los nombres de las hojas
Obtener la hoja basada en el índice
Leer el contenido de una celda.
Obtenga el número de filas y el número de columnas en una hoja de Excel
Obtener hoja de excel por nombre
Formato de archivos de Excel con xlsxwriter
    899/1068
    835
# set the width of column A 
worksheet.set_column('A:A', 30, )
# set column B to 20 and include the percent format we created earlier 
worksheet.set_column('B:B', 20, percent_format)
# remove formatting from the first row (change in height=None) 
worksheet.set_row('0:0', None, remove_format)
workbook.close()
    900/1068
    836
Capítulo 172: Recolección de basura
Observaciones
Ensunúcleo,elrecolectordebasuradePython(apartirde3.5)esunaimplementaciónde 
conteodereferenciasimple.Cadavezquehaceunareferenciaaunobjeto(porejemplo,a = 
myobject)elrecuentodereferenciaeneseobjeto(myobject) seincrementa.Cadavezquese 
eliminaunareferencia,elrecuentodereferenciasdisminuye,yunavezqueelrecuentode 
referencias llega a 0 , sabemos que nada tiene una referencia a ese objeto y podemos 
desasignarlo.
Un malentendido común acerca de cómo funciona la administración de memoria de Python es 
que la palabra clave del delimita la memoria de los objetos. Esto no es verdad. Lo que sucede en 
realidad es que la palabra clave del Delte simplemente reduce los refcount de los objetos, lo que 
significa que si lo llama suficientes veces para que el refcount llegue a cero, el objeto puede ser 
recolectado como basura (incluso si en realidad todavía hay referencias al objeto disponible en
otra parte de su código). ).
Python crea o limpia agresivamente los objetos la primera vez que los necesita. Si realizo la 
asignación a = object (), la memoria para el objeto se asigna en ese momento (cpython a veces 
reutilizará ciertos tipos de objetos, por ejemplo, listas bajo el capó, pero, en su mayoría, no 
mantiene un grupo de objetos libres y realizará la asignación cuando la necesite. De manera 
similar, tan pronto como el número de ref se reduce a 0, GC lo limpia.
Recolección de basura generacional
En la década de 1960, John McCarthy descubrió una falla fatal en el recuento de basura cuando 
implementó el algoritmo de recuento de cuentas utilizado por Lisp: ¿Qué sucede si dos objetos se 
refieren entre sí en una referencia cíclica? ¿Cómo puede alguna vez recolectar esos dos objetos 
de la basura incluso si no hay referencias externas a ellos si siempre se referirán entre ellos? Este 
problema también se extiende a cualquier estructura de datos cíclica, como los buffers de un 
anillo o dos entradas consecutivas en una lista con doble enlace. Python intenta solucionar este 
problema con un giro ligeramente interesante en otro algoritmo de recolección de basura llamado 
Generational Garbage Collection .
En esencia, cada vez que creas un objeto en Python, lo agrega al final de una lista doblemente 
enlazada. En ocasiones, Python recorre esta lista, comprueba a qué objetos se refieren los 
objetos de la lista, y si también están en la lista (veremos por qué podrían no estar en un 
momento), disminuye aún más sus refcounts. En este punto (en realidad, hay algunas heurísticas 
que determinan cuándo se mueven las cosas, pero supongamos que después de una sola 
colección para mantener las cosas simples) cualquier cosa que aún tenga un refcount mayor que 
0 se promociona a otra lista vinculada llamada "Generación 1" (esta es la razón por la que no 
todos los objetos están siempre en la lista de la generación 0) que tiene este bucle aplicado con 
menos frecuencia. Aquí es donde entra en juego la recolección de basura generacional. Hay 3 
generaciones de forma predeterminada en Python (tres listas vinculadas de objetos): La primera
    901/1068
    837
/* Break reference cycles by clearing the containers involved. This is
* tricky business as the lists can be changing and we don't know which
* objects may be freed. It is possible I screwed something up here.
*/
static void
delete_garbage(PyGC_Head *collectable, PyGC_Head *old)
lista (generación 0) contiene todos los objetos nuevos; si ocurre un ciclo GC y los objetos no se 
recolectan, se mueven a la segunda lista (generación 1), y si ocurre un ciclo GC en la segunda 
lista y aún no se recolectan, se mueven a la tercera lista (generación 2 ). La lista de la tercera 
generación (llamada "generación 2", dado que no tenemos ninguna indexación) es recogida de 
basura con mucha menos frecuencia que las dos primeras, y la idea es que si su objeto tiene una 
larga vida útil, no es tan probable que se realice la GCed, y puede que nunca estar en GC durante 
la vida útil de su aplicación, por lo que no tiene sentido perder el tiempo en cada ejecución del 
GC. Además, se observa que la mayoría de los objetos se recolectan basura relativamente 
rápido. De ahora en adelante, llamaremos a estos "buenos objetos" ya que mueren jóvenes. Esto 
se denomina "hipótesis generacional débil" y también se observó por primera vez en los años 60.
Un lado rápido: a diferencia de las dos primeras generaciones, la lista de tercera generación de 
larga duración no es recogida de basura en un horario regular. Se verifica cuando la proporción 
de objetos pendientes de larga duración (aquellos que están en la lista de la tercera generación, 
pero que aún no han tenido un ciclo GC) con el total de objetos de larga duración en la lista es 
superior al 25%. Esto se debe a que la tercera lista no tiene límites (las cosas nunca se mueven 
de ella a otra lista, por lo que solo desaparecen cuando en realidad se recolectan basura), lo que 
significa que para las aplicaciones en las que está creando muchos objetos de larga duración, los 
ciclos de GC en la tercera lista puede llegar a ser bastante largo. Al utilizar una relación, logramos 
"rendimiento lineal amortizado en el número total de objetos"; también conocido, cuanto más larga 
sea la lista, más tiempo lleva GC, pero con menos frecuencia realizamos GC (aquí está la 
propuesta original de 2008 para esta heurística de Martin von Löwis para mayor lectura). El acto 
de realizar una recolección de basura en la tercera generación o lista "madura" se denomina 
"recolección de basura completa".
Así que la recolección de basura generacional acelera las cosas tremendamente al no requerir 
que escaneamos objetos que no es probable que necesiten GC todo el tiempo, pero ¿cómo nos 
ayuda a romper las referencias cíclicas? Probablemente no muy bien, resulta. La función para 
realmente romper estos ciclos de referencia comienza así :
La razón por la que la recolección de basura generacional ayuda con esto es que podemos 
mantener la longitud de la lista como un conteo separado; cada vez que agregamos un nuevo 
objeto a la generación incrementamos este conteo, y cada vez que movemos un objeto a otra 
generación o lo tratamos, decrementamos el conteo. Teóricamente, al final de un ciclo de GC, 
este recuento (para las primeras dos generaciones de todos modos) siempre debe ser 0. Si no lo 
es, cualquier cosa que quede en la lista es alguna forma de referencia circular y podemos dejarla. 
Sin embargo, hay un problema más aquí: ¿Qué pasa si los objetos sobrantes tienen el método 
mágico de Python del en ellos? del se llama cada vez que se destruye un objeto de 
Python. Sin embargo, si dos objetos en una referencia circular tienen métodos del , no 
podemos estar seguros de que destruir uno no romperá el método del los otros. Para un 
ejemplo artificial, imagina que escribimos lo siguiente:
    902/1068
    838
/* list of uncollectable objects */ 
static PyObject *garbage = NULL;
y establecemos una instancia de A y una instancia de B para que apunten entre sí y luego 
terminan en el mismo ciclo de recolección de basura? Digamos que elegimos uno al azar y 
desechamos nuestra instancia de A primero; Se del método del de A, se imprimirá y 
luego A se liberará. Luego llegamos a B, llamamos a su método del , y ¡ del ! Segfault! A 
ya no existe. Podríamos arreglar esto llamando primero a del métodos del que del , 
luego haciendo otra pasada para repartir todo, sin embargo, esto introduce otro problema: ¿Qué 
pasa si uno de los del método del guarda una referencia del otro objeto que está a punto 
de ser GCed y ¿Tiene una referencia a nosotros en otro lugar? Todavía tenemos un ciclo de 
referencia, pero ahora no es posible hacer GC en ninguno de los dos objetos, incluso si ya no 
están en uso. Tenga en cuenta que incluso si un objeto no es parte de una estructura de datos 
circular, podría revivir en su propio método del ; Python tiene una verificación de esto y 
detendrá la GCing si un refcount de objetos ha aumentado después de que se haya llamado a su 
método del .
CPython se ocupa de esto al pegar esos objetos del de GC (cualquier cosa con algún tipo de 
referencia circular y un método del ) en una lista global de basura no recolectable y luego 
dejarla ahí por toda la eternidad:
Examples
Recuento de referencias
La gran mayoría de la administración de memoria de Python se maneja con conteo de 
referencias.
Cada vez que se hace referencia a un objeto (por ejemplo, asignado a una variable), su recuento 
de referencia aumenta automáticamente. Cuando se elimina la referencia (por ejemplo, la variable 
queda fuera del alcance), su recuento de referencia se reduce automáticamente.
Cuando el recuento de referencia llega a cero, el objeto se destruye inmediatamente y la 
memoria se libera inmediatamente. Por lo tanto, para la mayoría de los casos, el recolector de 
basura ni siquiera es necesario.
class A(object):
def init (self, b=None): 
self.b = b
def del (self):
print("We're deleting an instance of A containing:", self.b)
class B(object):
def init (self, a=None): 
self.a = a
def del (self):
print("We're deleting an instance of B containing:", self.a)
    903/1068
    839
>>> def bar():
return Track()
>>> t = bar() 
Initialized
>>> another_t = t # assign another reference
>>> print("...")
...
>>>t =None # not destructed yet - another_t still refers to it
>>> another_t = None # final reference gone, object is destructed 
Destructed
>>> import gc; gc.disable() # disable garbage collector
>>> class Track:
def init (self): 
print("Initialized")
def del (self): 
print("Destructed")
>>> A = Track() 
Initialized
>>>B = Track() 
Initialized
>>> A.other = B
>>> B.other = A
>>> del A;del B # objects are not destructed due to reference cycle
Para demostrar aún más el concepto de referencias:
Recolector de basura para ciclos de referencia
La única vez que se necesita el recolector de basura es si tiene un ciclo de referencia . El ejemplo
simple de un ciclo de referencia es uno en el que A se refiere a B y B se refiere a A, mientras que 
nada más se refiere a A o B. No se puede acceder a A ni a B desde cualquier lugar del programa, 
por lo que se pueden destruir de forma segura. sin embargo, sus recuentos de referencia son 1 y, 
por lo tanto, no se pueden liberar únicamente con el algoritmo de recuento de referencia.
>>> import gc; gc.disable() # disable garbage collector
>>> class Track:
def init (self): 
print("Initialized")
def del (self): 
print("Destructed")
>>> def foo():
Track()
# destructed immediately since no longer has any references 
print("---")
t =Track()
# variable is referenced, so it's not destructed yet 
print("---")
# variable is destructed when function exits
>>> foo() 
Initialized 
Destructed
---
Initialized
---
Destructed
    904/1068
    840
>>> objs = [Track() for _ in range(10)] 
Initialized
Initialized 
Initialized 
Initialized 
Initialized 
Initialized 
Initialized 
Initialized 
Initialized 
Initialized
>>> for i in range(len(objs)-1):
... objs[i].other = objs[i + 1]
...
>>> objs[-1].other = objs[0] # complete the cycle
>>> del objs # no one can refer to objs now - still not destructed
>>> gc.collect() 
Destructed 
Destructed 
Destructed 
Destructed 
Destructed 
Destructed 
Destructed 
Destructed 
Destructed 
Destructed
20
>>> import gc
>>> gc.disable() # disable garbage collector
>>> class Track:
def init (self): 
print("Initialized")
def del (self): 
print("Destructed")
>>> def bar():
return Track()
>>> t = bar() 
Initialized
Un ciclo de referencia puede ser arbitrario largo. Si A apunta a B apunta a C apunta a ... apunta a 
Z que apunta a A, entonces no se recolectarán A a Z, hasta la fase de recolección de basura:
Efectos del comando del
Eliminarunnombredevariabledelámbitousandodel v,oeliminarunobjetodeunacolección 
usando del v[item] o del[i:j] , o eliminar un atributo usando del v.name , o cualquier otra forma 
deeliminarreferenciasa un objeto,nodesencadenaningunallamada dedestructorni ninguna 
memoria liberada en sí misma.Los objetos solose destruyen cuando su cuenta de referencia 
llega a cero.
>>> gc.collect() # trigger collection 
Destructed
Destructed 
4
    905/1068
    841
>>> import sys
>>> sys.getrefcount(1) 
797
>>> a = 1
>>> b = 1
>>> sys.getrefcount(1) 
799
>>> a = 999999999
>>> sys.getrefcount(999999999) 
3
>>> b = 999999999
>>> sys.getrefcount(999999999) 
3
>>> import sys
>>> a = object()
>>> sys.getrefcount(a) 
2
>>> b = a
>>> sys.getrefcount(a) 
3
>>> del b
>>> sys.getrefcount(a) 
2
>>>another_t =t
>>> print("...")
...
>>> del t
>>> del another_t 
Destructed
# assign another reference
# not destructed yet - another_t still refers to it 
# final reference gone, object is destructed
Reutilización de objetos primitivos.
Una cosa interesante a tener en cuenta que puede ayudar a optimizar sus aplicaciones es que las 
primitivas también se vuelven a contar bajo el capó. Echemos un vistazo a los números; para 
todos los enteros entre -5 y 256, Python siempre reutiliza el mismo objeto:
Tenga en cuenta que refcount aumenta, lo que significa que a y b referencia al mismo objeto 
subyacente cuando se refierena la primitiva 1 .Sinembargo,paranúmeros más grandes,Python 
en realidad no reutiliza el objeto subyacente:
Debido a que el refcount de 999999999 no cambia cuando se asigna a a y b se puede inferir que se 
refieren a dos objetos subyacentes diferentes,aunque ambos se lesasigna el mismo primitivo.
Viendo el refcount de un objeto
Forzar la desasignación de objetos.
Puede forzar la desasignación de objetos incluso si su refcount no es 0 en Python 2 y 3.
    906/1068
    842
import ctypes 
deallocated = 12345
ctypes.pythonapi._Py_Dealloc(ctypes.py_object(deallocated))
import ctypes, sys 
deallocated = 12345
(ctypes.c_char * sys.getsizeof(deallocated)).from_address(id(deallocated))[:4] = '\x00' * 4
import gc
gc.set_threshold(1000, 100, 10) # Values are just for demonstration purpose
Ambas versiones utilizan el módulo ctypes para hacerlo.
ADVERTENCIA: haciendo esto dejará su entorno Python inestable y propenso a estrellarse sin 
un rastreo! El uso de este método también podría introducir problemas de seguridad (bastante 
improbable). Desasigne solo los objetos que está seguro de que nunca volverá a hacer 
referencia. Siempre.
Python 3.x 3.0
Python 2.x 2.3
Después de ejecutar, cualquier referencia al objeto ahora desasignado hará que Python produzca 
un comportamiento indefinido o se bloquee, sin un rastreo. Probablemente hubo una razón por la 
que el recolector de basura no eliminó ese objeto ...
Si desasigna None , aparece un mensaje especial: Fatal Python error: deallocating None antesde 
que se bloquee.
Gestionando la recogida de basura.
Hay dos enfoques para influir cuando se realiza una limpieza de memoria. Influyen en la 
frecuencia con la que se realiza el proceso automático y el otro está activando manualmente una 
limpieza.
El recolector de basura se puede manipular ajustando los umbrales de recolección que afectan la 
frecuencia a la que se ejecuta el recolector. Python utiliza un sistema de gestión de memoria 
basado en la generación. Los nuevos objetos se guardan en la generación más nueva -
generación0 y con cada colección sobrevivida, los objetos se promueven a las generaciones 
anteriores. Después de llegar a la última generación - generación2 , ya no se promocionan.
Los umbrales se pueden cambiar usando el siguiente fragmento de código:
El primer argumento representa el umbral para recolectar generation0 . Cada vez que el número 
de asignaciones supera el número de desasignaciones por 1000, se llamará al recolector de 
basura.
Las generaciones anteriores no se limpian en cada ejecución para optimizar el proceso. El 
segundo y tercer argumento son opcionales y controlan la frecuencia con la que se limpian las 
generaciones anteriores. Si la generación0 se procesó 100 veces sin limpiar la generación1 ,
    907/1068
    843
import gc 
gc.collect()
>>> f = open("test.txt")
>>> del f
entonces se procesará la generación1 . De manera similar, los objetos en la generación 2 se 
procesarán solo cuando los de la generación 1 se hayan limpiado 10 veces sin tocar la 
generación 2 .
Una instancia en la que es beneficioso establecer manualmente los umbrales es cuando el 
programa asigna una gran cantidad de objetos pequeños sin desasignarlos, lo que hace que el 
recolector de basura se ejecute con demasiada frecuencia (cada una de las asignaciones de 
objetos de umbral de generación ). A pesar de que el colector es bastante rápido, cuando se 
ejecuta en una gran cantidad de objetos plantea un problema de rendimiento. De todos modos, no 
hay una estrategia única para todos los límites para elegir los umbrales y es confiable en cada 
caso de uso.
La activación manual de una colección se puede hacer como en el siguiente fragmento de código:
La recolección de basura se activa automáticamente en función del número de asignaciones y 
desasignaciones, no en la memoria consumida o disponible. En consecuencia, cuando se trabaja 
con objetos grandes, la memoria puede agotarse antes de que se active la limpieza automática. 
Esto es un buen caso de uso para llamar manualmente al recolector de basura.
Aunque es posible, no es una práctica recomendada. Evitar las pérdidas de memoria es la mejor 
opción. De todos modos, en grandes proyectos, detectar la pérdida de memoria puede ser una 
tarea fácil y activar manualmente una recolección de basura se puede usar como una solución 
rápida hasta una depuración adicional.
Para los programas de larga duración, la recolección de basura puede activarse en una base de 
tiempo o evento. Un ejemplo para el primero es un servidor web que activa una colección 
después de un número fijo de solicitudes. Para más adelante, un servidor web que activa una 
recolección de basura cuando se recibe un cierto tipo de solicitud.
No espere a que la recolección de basura se limpie
El hecho de que la recolección de basura se limpie no significa que deba esperar a que se limpie 
el ciclo de recolección de basura.
En particular, no debe esperar a que la recolección de basura cierre los manejadores de archivos, 
las conexiones de base de datos y las conexiones de red abiertas.
por ejemplo:
En el siguiente código, asume que el archivo se cerrará en el siguiente ciclo de recolección de 
basura, si f fue la última referencia al archivo.
Una forma más explícita de limpiar es llamar a f.close() . Puede hacerlo aún más elegante, es
    908/1068
    844
>>> with open("test.txt") as f:
... pass
... # do something with f
>>> #now the f object still exists, but it is closed
decir, utilizando la instrucción with , también conocida como administrador de contexto :
La instrucción with permite sangrar su código debajo del archivo abierto. Esto hace que sea 
explícito y más fácil ver cuánto tiempo se mantiene abierto un archivo. También siempre cierra un 
archivo, incluso si se produce una excepción en el bloque while .
    909/1068
    845
from PIL import Image 
import sys
import pyocr
import pyocr.builders
tools = pyocr.get_available_tools()
# The tools are returned in the recommended order of usage 
tool = tools[0]
Capítulo 173: Reconocimiento óptico de 
caracteres
Introducción
El reconocimiento óptico de caracteres es convertir imágenes de texto en texto real. En estos 
ejemplos, encuentre formas de usar OCR en python.
Examples
PyTesseract
PyTesseract es un paquete de Python en desarrollo para OCR. 
Usar PyTesseract es bastante fácil:
PyTesseract es de código abierto y se puede encontrar aquí .
PyOCR
Otro módulo de algún uso es PyOCR , cuyo código fuente está aquí . 
También es fácil de usar y tiene más funciones que PyTesseract.
Para inicializar:
try:
import Image 
except ImportError:
from PIL import Image 
import pytesseract
#Basic OCR 
print(pytesseract.image_to_string(Image.open('test.png')))
#In French
print(pytesseract.image_to_string(Image.open('test-european.jpg'), lang='fra’))
    910/1068
    846
txt = tool.image_to_string( 
Image.open('test.png'), 
lang=lang,
builder=pyocr.builders.TextBuilder()
)
# txt is a Python string
word_boxes = tool.image_to_string( 
Image.open('test.png'), 
lang="eng",
builder=pyocr.builders.WordBoxBuilder()
)
# list of box objects. For each box object:
# box.content is the word in the box
# box.position is its position on the page (in pixels) 
#
# Beware that some OCR tools (Tesseract for instance)
# may return empty boxes
line_and_word_boxes = tool.image_to_string( 
Image.open('test.png'), lang="fra", 
builder=pyocr.builders.LineBoxBuilder()
)
# list of line objects. For each line object:
# line.word_boxes is a list of word boxes (the individual words in the line) 
# line.content is the whole text of the line
# line.position is the position of the whole line on the page (in pixels) 
#
# Beware that some OCR tools (Tesseract for instance)
# may return empty boxes
# Digits - Only Tesseract (not 'libtesseract' yet !) 
digits = tool.image_to_string(
Image.open('test-digits.png'), 
lang=lang, 
builder=pyocr.tesseract.DigitBuilder()
)
# digits is a python string
Y algunos ejemplos de uso:
langs = tool.get_available_languages() 
lang = langs[0]
# Note that languages are NOT sorted in any way. Please refer 
# to the system locale settings for the default language
# to use.
    911/1068
    847
n = 0
for i in range (1, n+1): 
n += i
def recursion(n): 
if n == 1:
return 1
return n + recursion(n - 1)
Capítulo 174: Recursion
Observaciones
La recursión necesita una condición de parada stopCondition para salir de la recursión. 
La variable original se debe pasar a la función recursiva para que se almacene.
Examples
Suma de números del 1 al n
Siquisiera averiguarlasuma delosnúmerosdel 1al ndonde n es un númeronatural, puedo 
hacer 1 + 2 + 3 + 4 + ... + (several hours later) + n . Alternativamente, podría escribir un bucle 
for :
O podría usar una técnica conocida como recursión:
La recursión tiene ventajas sobre los dos métodos anteriores. La recursión toma menos tiempo 
que escribir 1 + 2 + 3 para una suma de 1 a 3. Para la recursion(4) , la recursión se puede usar 
para trabajar hacia atrás:
Llamadas a funciones: (4 -> 4 + 3 -> 4 + 3 + 2 -> 4 + 3 + 2 + 1 -> 10)
Mientras que el bucle for está trabajando estrictamente hacia adelante: (1 -> 1 + 2 -> 1 + 2 + 3 -> 
1 + 2 + 3 + 4 -> 10). A veces, la solución recursiva es más simple que la solución iterativa. Esto es 
evidente cuando se implementa una reversión de una lista vinculada.
El qué, cómo y cuándo de la recursión
La recursión se produce cuando una llamada de función hace que esa misma función se vuelva a 
llamar antes de que finalice la llamada de función original. Por ejemplo, considere la expresión 
matemática conocida x! (Es decir, la operación factorial). La operación factorial se define para 
todos los enteros no negativos de la siguiente manera:
• Si el número es 0, entonces la respuesta es 1.
• De lo contrario, la respuesta es que el número multiplicado por el factorial es uno menos
    912/1068
    848
def factorial(n): 
if n == 0:
return 1 
else:
return n * factorial(n - 1)
que ese número.
En Python, una implementación ingenua de la operación factorial se puede definir como una 
función de la siguiente manera:
Las funciones de recursión pueden ser difíciles de comprender a veces, así que veamos esto 
paso a paso. Considera la expresión factorial(3) . Esta y todas las llamadas a funciones crean 
unnuevoentorno.Un entorno esbásicamenteuna tabla queasignaidentificadores (porejemplo, 
n , factorial , print , etc.) a sus valores correspondientes. En cualquier momento, puede acceder 
al entorno actual utilizando locals() . En la primera llamada a la función, la única variable local 
que se define es n = 3 . Por lo tanto, la impresión de locals() mostraría {'n': 3} . Como n == 3 , el 
valor de retorno se convierte en n * factorial(n - 1).
Enestesiguientepasoes dondelas cosaspueden ser un poco confusas. Mirando nuestra nueva 
expresión, ya sabemos qué es n . Sin embargo, todavía no sabemos qué factorial(n - 1) es.
Primero, n - 1 evalúa a 2 . Entonces, 2 se pasa a factorial como el valor para n . Dado que se 
tratade unanueva llamadade función, se creaun segundo entorno para almacenar estanueva n
. Sea A el primer entorno y B el segundo entorno. A todavía existe y es igual a {'n': 3} , sin 
embargo,B(que esigual a {'n': 2} ) esel entorno actual.Alobservarel cuerpo delafunción, el 
valor de retorno es, nuevamente, n * factorial(n - 1) . Sin evaluar esta expresión, vamos a 
sustituirlaenlaexpresiónderetornooriginal.Alhaceresto,estamosdescartandomentalmenteB
, así que recuerde sustituir n consecuencia (es decir, las referencias a B 's n se reemplazan con n
- 1 que usa A ' s n ). Ahora, la expresión de retorno original se convierte en n * ((n - 1) * 
factorial((n - 1) - 1)).Tomeunsegundoparaasegurarsedequeentiendepor quéestoesasí.
Ahora,evaluemoslaporciónfactorial((n - 1)- 1))deeso.ComoA'sn == 3,estamospasando 
1afactorial.Porlotanto,estamoscreandounnuevoentornoCqueesiguala{'n': 1}.Una 
vezmás,el valorderetorno es n * factorial(n - 1).Entonces,reemplacemos factorial((n - 1)
- 1))delaexpresiónderetorno"original"demanerasimilaracomoajustamoslaexpresiónde 
retorno original anteriormente. La expresión "original" ahora es n * ((n - 1) * ((n - 2) * 
factorial((n - 2) - 1))) .
Casitermino.Ahora,necesitamosevaluarfactorial((n-2)-1).Estavez,estamospasandoen 
0.Porlotanto,estoseevalúaa1.Ahora,vamosarealizarnuestraúltimasustitución.La 
expresión de retorno "original" ahora es n * ((n - 1) * ((n - 2) * 1)) . Recordando que la 
expresiónderetornooriginalseevalúaenA,laexpresiónseconvierteen3 * ((3 - 1) * ((3 - 2)
* 1)) . Esto, por supuesto, se evalúa a 6. Para confirmar que esta es la respuesta correcta,
¡recuerde que 3! == 3 * 2 * 1 == 6 . Antes de seguir leyendo, asegúrese de comprender 
completamente el concepto de entornos y cómo se aplican a la recursión.
La declaración if n == 0: return 1 se llama un caso base. Esto se debe a que no exhibe 
recursión.Uncasobaseesabsolutamente necesario.Sinuno,teencontrarás conunarecursión
    913/1068
    849
def factorial(n): 
if n == 0:
return 1 
elif n == 1:
return 1 
else:
return n * factorial(n - 1)
def fib(n):
if n == 0 or n == 1: 
return n
else:
return fib(n - 2) + fib(n - 1)
(
fib((n - 2) - 2)
+ 
(
fib(((n - 2) - 1) - 2)
+
fib(((n - 2) - 1) - 1)
)
)
+ 
(
(
fib(((n - 1) - 2) - 2)
+
fib(((n - 1) - 2) - 1)
)
+ 
(
fib(((n - 1) - 1) - 2)
+ 
(
fib((((n - 1) - 1) - 1) - 2)
+
infinita. Dicho esto, siempre que tenga al menos un caso base, puede tener tantos casos como 
desee. Por ejemplo, podríamos haber escrito un factorial equivalente de la siguiente manera:
También puede tener varios casos de recursión, pero no vamos a entrar en eso, ya que es 
relativamente poco frecuente y, a menudo, es difícil de procesar mentalmente.
También puede tener llamadas de función recursiva "paralelas". Por ejemplo, considere la 
secuencia de Fibonacci que se define de la siguiente manera:
• Si el número es 0, entonces la respuesta es 0.
• Si el número es 1, entonces la respuesta es 1.
• De lo contrario, la respuesta es la suma de los dos números anteriores de Fibonacci.
Podemos definir esto como sigue:
No recorreré esta función tan a fondo como lo hice con factorial(3) , pero el valor de retorno final 
de fib(5) es equivalente a la siguiente expresión ( sintácticamente no válida):
    914/1068
    850
def factorial(n): 
product = 1 
while n > 1:
product *= n 
n -= 1
return product
def fib(n):
a, b = 0, 1
while n > 0:
a, b = b, a + b 
n -= 1
return a
Esto se convierte en (1 + (0 + 1)) + ((0 + 1) + (1 + (0 + 1))) que, por supuesto, se evalúa en 5 . 
Ahora, vamos a cubrir algunos términos más de vocabulario:
• Unallamadadecolaessimplementeunallamadadefunciónrecursivaqueeslaúltima 
operación que se realiza antes de devolver un valor. Para ser claros, return foo(n - 1) es 
una llamada de cola, pero return foo(n - 1) + 1 no (ya que la adición es la última 
operación).
• La optimización de llamadas de cola (TCO) es una forma de reducir automáticamente la 
recursión en funciones recursivas.
• La eliminación de la llamada de cola (TCE) es la reducción de una llamada de la cola a 
una expresión que se puede evaluar sin recursión. TCE es un tipo de TCO.
La optimización de llamadas de cola es útil por varias razones:
• El intérprete puede minimizar la cantidad de memoria ocupada por los entornos. Como 
ninguna computadora tiene memoria ilimitada, las llamadas excesivas a funciones 
recursivas conducirían a un desbordamiento de pila .
• El intérprete puede reducir el número de interruptores de cuadros de pila .
Python no tiene una forma de TCO implementada por varias razones . Por lo tanto, se requieren 
otras técnicas para evitar esta limitación. El método de elección depende del caso de uso. Con 
algo de intuición, las definiciones de factorial y fib se pueden convertir de manera relativamente 
fácil a código iterativo de la siguiente manera:
Esta suele ser la forma más eficiente de eliminar manualmente la recursión, pero puede ser 
bastante difícil para funciones más complejas.
Otra herramienta útil es el decorador lru_cache de Python, que se puede usar para reducir el 
número de cálculos redundantes.
Ahora tiene una idea de cómo evitar la recursión en Python, pero ¿cuándo debería usar la 
recursión? La respuesta es "no a menudo". Todas las funciones recursivas pueden ser
fib((((n - 1) - 1) - 1) - 1)
)
)
)
    915/1068
    851
def fib(n):
if n <= 1:
return (n,0) 
else:
(a, b) = fib(n - 1) 
return (a + b, a)
root
- A
- AA
- AB
- B
- BA
- BB
- BBA
root = get_root(tree)
for node in get_children(root): 
print(get_name(node))
for child in get_children(node): 
print(get_name(child))
for grand_child in get_children(child): 
print(get_name(grand_child))
# prints: A, AA, AB, B, BA, BB, BBA
implementadas iterativamente. Es simplemente una cuestión de averiguar cómo hacerlo. Sin 
embargo, hay casos raros en los que la recursión está bien. La recursión es común en Python 
cuando las entradas esperadas no causan un número significativo de llamadas a una función 
recursiva.
Si la recursión es un tema que le interesa, le imploro que estudie lenguajes funcionales como 
Scheme o Haskell. En tales idiomas, la recursión es mucho más útil.
Tenga en cuenta que el ejemplo anterior para la secuencia de Fibonacci, aunque es bueno para 
mostrar cómo aplicar la definición en python y el uso posterior de la caché lru, tiene un tiempo de 
ejecución ineficiente ya que realiza 2 llamadas recursivas para cada caso no básico. El número 
de llamadas a la función crece exponencialmente a n .
Más bien, de forma no intuitiva, una implementación más eficiente usaría la recursión lineal:
Pero ese tiene el problema de devolver un par de números. Esto enfatiza que algunas funciones 
realmente no ganan mucho con la recursión.
Exploración de árboles con recursión
Digamos que tenemos el siguiente árbol:
Ahora,si deseamos enumerartodoslos nombres deloselementos, podríamos hacer esto conun 
simple bucle for. Suponemos que hay una función get_name() para devolver una cadena del 
nombre de un nodo, una función get_children() para devolver una lista de todos los get_children() 
de un nodo dado en el árbol, y una función get_root() para obtener el nodo raíz
Esto funciona bien y rápido, pero ¿qué pasa si los subnodos tienen subnodos propios? Y esos
    916/1068
    852
def list_tree_names(node):
for child in get_children(node): 
print(get_name(child)) 
list_tree_names(node=child)
list_tree_names(node=get_root(tree)) 
# prints: A, AA, AB, B, BA, BB, BBA
def list_tree_names(node, lst=[]): 
for child in get_children(node):
lst.append(get_name(child)) 
list_tree_names(node=child, lst=lst)
return lst
list_tree_names(node=get_root(tree))
# returns ['A', 'AA', 'AB', 'B', 'BA', 'BB', 'BBA']
RuntimeError: Maximum Recursion Depth Exceeded
def cursing(depth): 
try:
cursing(depth + 1) # actually, re-cursing 
except RuntimeError as RE:
print('I recursed {} times!'.format(depth)) 
cursing(0)
# Out: I recursed 1083 times!
sys.setrecursionlimit(limit)
sys.getrecursionlimit()
sys.setrecursionlimit(2000)
subnodos podrían tener más subnodos ... ¿Qué pasa si no sabe de antemano cuántos habrá? Un 
método para resolver esto es el uso de la recursión.
Quizás desee no imprimir, pero devuelva una lista plana de todos los nombres de nodo. Esto se 
puede hacer pasando una lista móvil como parámetro.
Incrementando la profundidad máxima de recursión
Hay un límite a la profundidad de la posible recursión, que depende de la implementación de 
Python. Cuando se alcanza el límite, se genera una excepción RuntimeError:
Aquí hay una muestra de un programa que causaría este error:
Es posible cambiar el límite de profundidad de recursión usando
Puede verificar cuáles son los parámetros actuales del límite ejecutando:
Ejecutando el mismo método anterior con nuestro nuevo límite obtenemos
    917/1068
    853
def countdown(n): 
if n == 0:
print "Blastoff!" 
else:
print n 
countdown(n-1)
def find_max(seq, max_so_far): 
if not seq:
return max_so_far 
if max_so_far < seq[0]:
return find_max(seq[1:], seq[0]) 
else:
return find_max(seq[1:], max_so_far)
#!/usr/bin/env python2.4
#Thisprogramshowsoff a python decoratorwhichimplementstail call optimization.It 
# does this by throwing an exception if it is it's own grandparent, and catching such 
# exceptions to recall the stack.
import sys
class TailRecurseException:
def init (self, args, kwargs): 
self.args = args 
self.kwargs = kwargs
Desde Python 3.5, la excepción es un RecursionError, que se deriva de RuntimeError.
Recursión de cola - Mala práctica
Cuando lo único que se devuelve de una función es una llamada recursiva, se la denomina 
recursión de cola.
Aquí hay un ejemplo de cuenta regresiva escrita usando la recursión de la cola:
Cualquier cálculo que se pueda hacer usando la iteración también se puede hacer usando la 
recursión. Aquí hay una versión de find_max escrita usando la recursión de la cola:
La recursión de cola se considera una mala práctica en Python, ya que el compilador de Python 
no maneja la optimización para las llamadas recursivas de cola. La solución recursiva en casos 
como este utiliza más recursos del sistema que la solución iterativa equivalente.
Optimización de la recursión de cola a través de la introspección de la pila
Por defecto, la pila de recursión de Python no puede exceder los 1000 cuadros.Esto se puede 
cambiar configurando sys.setrecursionlimit(15000) que es más rápido, sin embargo, este método 
consume másmemoria.Ensulugar, tambiénpodemos resolverel problemaderecursióndecola 
utilizando la introspección depila.
cursing(0)
# Out: I recursed 1997 times!
    918/1068
    854
@tail_call_optimized 
def factorial(n, acc=1):
"calculate a factorial" 
if n == 0:
return acc
return factorial(n-1, n*acc)
print factorial(10000)
# prints a big, big number,
# but doesn't hit the recursion limit.
@tail_call_optimized
def fib(i, current = 0, next = 1): 
if i == 0:
return current 
else:
return fib(i - 1, next, current + next)
print fib(10000)
# also prints a big number,
# but doesn't hit the recursion limit.
Para optimizar las funciones recursivas, podemos usar el decorador @tail_call_optimized para 
llamara nuestrafunción.Aquíhayalgunosde losejemplos comunesderecursiónqueutilizanel 
decorador descrito anteriormente:
Ejemplo factorial:
Ejemplo de Fibonacci:
def tail_call_optimized(g):
"""
This function decorates a function with tail call 
optimization.It doesthisby throwing anexception 
if it is it's own grandparent, and catching such 
exceptions to fake the tail calloptimization.
This function fails if the decorated 
function recurses in a non-tail context. 
"""
def func(*args, **kwargs): 
f = sys._getframe()
if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code: 
raise TailRecurseException(args, kwargs)
else:
while 1:
try:
return g(*args, **kwargs) 
except TailRecurseException, e:
args = e.args 
kwargs = e.kwargs
func. doc = g. doc
return func
    919/1068
    855
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
serversocket.bind(('localhost', 8089))
serversocket.listen(5) # become a server socket, maximum 5 connections
while True:
connection, address = serversocket.accept() 
buf = connection.recv(64)
if len(buf) > 0: 
print(buf)
break
import socket
clientsocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
clientsocket.connect(('localhost', 8089)) 
clientsocket.send('hello')
Capítulo 175: Redes Python
Observaciones
Ejemplo de socket de cliente Python (muy) básico
Examples
El ejemplo más simple de cliente / servidor de socket de Python.
Lado del servidor:
Lado del cliente:
Primero ejecute el SocketServer.py, y asegúrese de que el servidor esté listo para escuchar / 
recibir algo. Luego, el cliente envía la información al servidor; Después de que el servidor recibió 
algo, termina
Creando un servidor HTTP simple
Para compartir archivos o alojar sitios web simples (http y javascript) en su red local, puede usar 
el módulo SimpleHTTPServer integrado de Python. Python debería estar en tu variable Path.
Vayaa la carpeta donde están sus archivos y escriba: 
Para python 2 :
Para python 3 :
$ python -m SimpleHTTPServer <portnumber>
    920/1068
    856
from sockerserver import BaseRequestHandler, TCPServer
class EchoHandler(BaseRequestHandler): 
def handle(self):
print('connection from:',self.client_address) 
while True:
msg = self.request.recv(8192) 
if not msg:
break 
self.request.send(msg)
if name == ' main ':
server = TCPServer(('', 5000), EchoHandler) 
server.serve_forever()
from socket import socket,AF_INET, SOCK_STREAM 
sock = socket(AF_INET, SOCK_STREAM) 
sock.connect(('localhost', 5000)) 
sock.send(b'Monty Python')
sock.recv(8192) # returns b'Monty Python'
from socketserver import ThreadingTCPServer
...
if name == ' main ':
server = ThreadingTCPServer(('', 5000), EchoHandler) 
server.serve_forever()
Si no se da el número de puerto, 8000 es el puerto predeterminado. Así que la salida será: 
Sirviendo HTTP en el puerto 0.0.0.0 8000 ...
Puedeacceder a sus archivos a través de cualquierdispositivo conectado ala redlocal 
escribiendo http://hostipaddress:8000/ .
hostipaddress es su dirección IP local que probablemente comienza con 192.168.xx
Para finalizar el módulo simplemente presione ctrl+c.
Creando un servidor TCP
Puede crear un servidor TCP utilizando la biblioteca socketserver . Aquí hay un servidor de eco 
simple.
Lado del servidor
Lado del cliente
socketserver hace que sea relativamente fácil crear servidores TCP simples. Sin embargo, debe 
tener en cuenta que, de formapredeterminada, los servidores son de un solohilo y solo pueden 
atender a un cliente a la vez. Si desea manejar múltiples clientes, cree una instancia de 
ThreadingTCPServer lugar.
$ python3 -m http.server <portnumber>
    921/1068
    857
>>> from socket import socket, AF_INET, SOCK_DGRAM
>>> sock = socket(AF_INET, SOCK_DGRAM)
>>> sick.sendto(b'', ('localhost', 5000)) 
0
>>> sock.recvfrom(8192)
(b'Wed Aug 15 20:35:08 2012', ('127.0.0.1', 5000))
from http.server import HTTPServer, CGIHTTPRequestHandler 
import webbrowser
import threading
def start_server(path, port=8000):
'''Start a simple webserver serving path on port''' 
os.chdir(path)
httpd=HTTPServer(('',port),CGIHTTPRequestHandler) 
httpd.serve_forever()
# Start the server in a new thread 
port = 8000
daemon = threading.Thread(name='daemon_server',
target=start_server, 
args=('.', port)
daemon.setDaemon(True) # Set as a daemon so it will be killed once the main thread is dead. 
daemon.start()
# Open the web browser 
webbrowser.open('http://localhost:{}'.format(port))
Creando un Servidor UDP
Un servidor UDP se crea fácilmente utilizando la biblioteca de socketserver . 
un servidor de tiempo simple:
Pruebas:
Inicie Simple HttpServer en un hilo y abra el navegador
Útil si tu programa está generando páginas web a lo largo del camino.
import time
from socketserver import BaseRequestHandler, UDPServer
class CtimeHandler(BaseRequestHandler): 
def handle(self):
print('connectionfrom:',self.client_address) 
# Get message and clientsocket
msg, sock = self.request 
resp = time.ctime()
sock.sendto(resp.encode('ascii'), self.client_address)
if name == ' main ':
server = UDPServer(('', 5000), CtimeHandler) 
server.serve_forever()
    922/1068
    858
    923/1068
    859
sum([1,2,3]) # = 6
''.join(['Hello', ',', ' World']) # = 'Hello,World'
# First falsy item:
next((i for i in [100, [], 20, 0] if not i)) # = []
# No import needed
# No import required...
Capítulo 176: Reducir
Sintaxis
• reducir (función, iterable [, inicializador])
Parámetros
Parámetro Detalles
función Función que se utiliza para reducir lo iterable (debe tomar dos argumentos). (
solo posicional )
iterable iterable que va a ser reducido. ( solo posicional )
inicializador Valor de inicio de la reducción. ( opcional , solo posicional )
Observaciones
reduce podría no ser siempre la función más eficiente. Para algunos tipos hay funciones o 
métodos equivalentes:
• sum() para la suma de una secuencia que contiene elementos sumables (no cadenas):
• str.join para la concatenación decuerdas:
• next junto con un generador podría ser una variante de cortocircuito en comparación con
reduce :
Examples
Visión general
    924/1068
    860
def add(s1, s2): 
return s1 + s2
asequence = [1, 2, 3]
reduce(add, asequence) # equivalent to: add(add(1,2),3) 
# Out: 6
import operator 
reduce(operator.add, asequence) 
# Out: 6
reduce(add, asequence, 10)
# Out: 16
def multiply(s1, s2):
print('{arg1} * {arg2} = {res}'.format(arg1=s1,
arg2=s2, 
res=s1*s2))
return s1 * s2
asequence = [1, 2, 3]
cumprod = reduce(multiply, asequence, 5) 
# Out: 5 * 1 = 5
# 5 * 2 = 10
# 10 * 3 = 30
print(cumprod) 
# Out: 30
cumprod = reduce(multiply, asequence) 
# Out: 1 * 2 = 2
reduce reduceuniterableaplicandounafunciónrepetidamenteenelsiguienteelementodeun 
resultado iterable y acumulativo hasta el momento.
Eneste ejemplo, definimos nuestra propia funciónde add .Sin embargo,Python viene con una 
función equivalente estándar en el módulo del operator :
reduce también se puede pasar un valor inicial:
Utilizando reducir
Dado un initializer la función se inicia aplicándola al inicializador y al primer elemento iterable:
Sin el parámetro initializer , la reduce inicia al aplicar la función a los dos primeros elementos de 
la lista:
from functools import reduce # ... but it can be loaded from the functools module
from functools import reduce # mandatory
    925/1068
    861
import operator 
reduce(operator.mul, [10, 5, -3])
# Out: -150
import operator
# non short-circuit "all"
reduce(operator.and_, [False, True, True, True]) # = False
# non short-circuit "any"
reduce(operator.or_, [True, False, False, False]) # = True
# First falsy element or last element if all are truthy: 
reduce(lambda i, j: i and j, [100, [], 20, 10]) # = [] 
reduce(lambda i, j: i and j, [100, 50, 20, 10]) #= 10
# First truthy element or last element if all falsy: 
reduce(lambda i, j: i or j, [100, [], 20, 0]) # = 100 
reduce(lambda i, j: i or j, ['', {}, [], None]) #=None
# = 100 
# = []
def do_or(i, j): 
return i or j
def do_and(i, j): 
return i andj
reduce(do_or, [100, [], 20, 0])
reduce(do_and, [100, [], 20, 0])
Producto acumulativo
Variante sin cortocircuito de alguno / todos.
reducenoterminarálaiteraciónantesdeque el iterablesehayaiteradocompletamente, porlo 
que se puede usar para crear una función sin cortocircuito en any() o all() :
Primer elemento verdadero / falso de una secuencia (o último elemento si no 
hay ninguno)
En lugar de crear una función lambda , generalmente se recomienda crear una función nombrada:
print(cumprod) 
# Out: 6
# 2 * 3 = 6
    926/1068
    862
object -> string -> object
def repr (self):
return "Card(%s, %d)" % (self.suit, self.pips)
Capítulo 177: Representaciones de cadena de
instancias de clase: métodos 
repr
str y
Observaciones
Una nota sobre la implementación de ambos 
métodos.
Cuandoseimplementanambosmétodos,esalgocomúntenerunmétodo str que devuelve 
unarepresentaciónamigableparaelserhumano(porejemplo,"AsofSpaces")y repr
devuelve una representación amigable deeval .
De hecho, la documentación de Python para repr() nota exactamente esto:
Para muchos tipos, esta función intenta devolver una cadena que produciría un objeto 
con el mismo valor cuando se pasa a eval (), de lo contrario, la representación es una 
cadena entre paréntesis angulares que contiene el nombre del tipo de objeto. con 
información adicional que a menudo incluye el nombre y la dirección del objeto.
Lo que eso significa esque str podría implementarse para devolver algo como "As of 
Spaces" como se mostró anteriormente, repr podría implementarse para devolver una
Card('Spades', 1)
Esta cadena podría pasarse directamente a eval en una especie de "ida y vuelta":
Un ejemplo de una implementación de tal método podría ser:
Notas
[1] Esta salida es específica de la implementación. La cadena mostrada es de cpython.
[2] Es posible que ya hayas visto el resultado de esta división str() / repr() y no lo hayas 
conocido.Cuandolascadenasquecontienencaracteresespeciales,comolasbarrasinvertidas, 
se convierten en cadenas a través de str() las barras diagonales aparecen como están 
(aparecenunavez).Cuandoseconviertenencadenasmedianterepr()(porejemplo,como
    927/1068
    863
class Card:
def init (self, suit, pips): 
self.suit = suit 
self.pips = pips
ace_of_spades = Card('Spades', 1) 
four_of_clubs = Card('Clubs', 4) 
six_of_hearts = Card('Hearts', 6)
my_hand = [ace_of_spades, four_of_clubs, six_of_hearts]
print(my_hand)
[< main .Card instance at 0x0000000002533788>,
< main .Card instance at 0x00000000025B95C8>,
< main .Card instance at 0x00000000025FF508>]
print(ace_of_spades)
< main .Card instance at 0x0000000002533788>
elementos de una lista que se muestra), las barras invertidas se escapan y, por lo tanto, aparecen 
dos veces.
Examples
Motivación
Así que acabas de crear tu primera clase en Python, una clase pequeña y ordenada que 
encapsula una carta de juego:
En otra parte de tu código, creas algunas instancias de esta clase:
Incluso has creado una lista de cartas para representar una "mano":
Ahora, durante la depuración, quieres ver cómo se ve tu mano, así que haces lo que es natural y 
escribes:
Pero lo que obtienes es un montón de galimatías:
Confundido, intenta simplemente imprimir una sola tarjeta:
Y de nuevo, obtienes esta salida extraña:
No tener miedo. Estamos a punto de arreglar esto.
Primero, sin embargo, es importante entender lo que está pasando aquí. Cuando escribió
print(ace_of_spades) le dijo a Python que quería que imprimiera información sobre la instancia de
    928/1068
    864
string_of_card = str(ace_of_spades) 
print(string_of_card)
class Card:
def init (self, suit, pips): 
self.suit = suit 
self.pips = pips
def str (self):
special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'} 
card_name = special_names.get(self.pips, str(self.pips))
return "%s of %s" % (card_name, self.suit)
la Card su código está llamando ace_of_spades . Y para ser justos, lo hizo.
Esasalidasecomponededosbits importantes:el typedeobjetoylaiddel objeto.La segunda 
parte sola (el número hexadecimal) es suficiente para identificar de forma única el objeto en el 
momento de la llamada de print . [1]
Lo que realmente sucedió fue que le pediste a Python que "expresara con palabras" la esencia de 
ese objeto y luego te lo mostrara. Una versión más explícita de la misma maquinaria podría ser:
En la primera línea, intenta convertir la instancia de su Card en una cadena, y en la segunda, la 
muestra.
El problema
El problema con el que se encuentra surge debido al hecho de que, mientras le contaba a Python 
todo lo que necesitaba saber sobre la clase de la Card para que usted creara las tarjetas, no le dijo 
cómo quería que las instancias de la Card se convirtieran en cadenas.
Y como no lo sabía, cuando usted (implícitamente) escribió str(ace_of_spades) , le dio lo que vio, 
una representación genérica de la instancia de la Card .
La Solución (Parte 1)
Pero podemos decirle a Python cómo queremos que las instancias de nuestras clases 
personalizadas se conviertan en cadenas. Y la forma en que lo hacemos es con el método str
"dunder" (para subrayado doble) o "magic".
Siempre quele digas aPythonque cree una cadena desde unainstancia declase, buscará un 
método str en la clase y lo llamará.
Considere la siguiente versión actualizada de nuestra clase de Card :
Aquí, ahora hemos definido el método str en nuestra clase de Card que, después deuna
    929/1068
    865
ace_of_spades = Card('Spades', 1) 
print(ace_of_spades)
Ace of Spades
my_hand = [ace_of_spades, four_of_clubs, six_of_hearts] 
print(my_hand)
[< main .Card instance at 0x00000000026F95C8>,
< main .Card instance at 0x000000000273F4C8>,
< main .Card instance at 0x0000000002732E08>]
simple búsqueda en el diccionario de tarjetas de caras, devuelve una cadena con el formato que 
decidamos.
(Tenga en cuenta que las "devoluciones" están en negrita aquí, para resaltar la importancia de 
devolver una cadena y no simplemente de imprimirla. La impresión puede parecer que funciona, 
pero luego se imprimirá la tarjeta cuando hizo algo como str(ace_of_spades) , sin siquiera tener 
una llamada a la función de impresión en su programa principal. Para que quede claro, asegúrese 
de que str devuelva una cadena.
El método str esun método, porlo que elprimerargumentoserá selfy no debería aceptar, ni 
pasar argumentos adicionales.
Volviendo a nuestro problema de mostrar la tarjeta de una manera más fácil para el usuario, si 
volvemos a ejecutar:
Veremos que nuestra salida es mucho mejor:
Muy bien, hemos terminado, ¿verdad?
Bueno, solo para cubrir nuestras bases, verifiquemos que hemos resuelto el primer problema que 
encontramos, imprimiendo la lista de instancias de la Card , la hand .
Así que volvemos a comprobar el siguiente código:
Y, para nuestra sorpresa, volvemos a obtener esos divertidos códigos hex:
¿Que esta pasando? Le dijimos a Python cómo queríamos que se mostraran nuestras instancias 
de la Card , ¿por qué parece que aparentemente se olvidó?
La Solución (Parte 2)
Bueno, la maquinaria detrás de escena es un poco diferente cuando Python quiere obtener la 
representación de cadena de los elementos en una lista. Resulta que a Python no le importa
 str para este propósito.
En su lugar, busca un método diferente, repr , y si eso no es encontrado, se recurre a la "cosa
    930/1068
    866
class Card:
special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'}
def init (self, suit, pips): 
self.suit = suit 
self.pips = pips
def str (self):
card_name = Card.special_names.get(self.pips, str(self.pips)) 
return "%s of %s (S)" % (card_name, self.suit)
def repr (self):
card_name = Card.special_names.get(self.pips, str(self.pips)) 
return "%s of %s (R)" % (card_name, self.suit)
print(ace_of_spades) # Ace of Spades (S)
print(my_hand) # [Ace of Spades (R), 4 of Clubs (R), 6 of Hearts (R)]
ace_of_spades = Card('Spades', 1) 
four_of_clubs = Card('Clubs', 4) 
six_of_hearts = Card('Hearts', 6)
my_hand = [ace_of_spades, four_of_clubs, six_of_hearts]
str_card = str(four_of_clubs)
hexadecimal". [2]
Entonces, ¿estás diciendo que tengo que hacer dos métodos para hacer lo mismo? ¿Uno para 
cuando quiero print mi tarjeta por sí mismo y otro cuando está en algún tipo de contenedor?
No, pero primero veamos cómo sería nuestra clase si implementáramos los métodos str y
 repr :
Aquí, la implementación de los dos métodos str y repr son exactamente iguales, excepto 
que, paradiferenciarlosdos métodos, seagrega(S)alascadenas devueltas por str y(R)se 
agrega a las cadenas devueltas por repr .
Tenga en cuenta que al igual que nuestro método str , repr no acepta argumentosy
devuelve una cadena.
Podemos ver ahora qué método es responsable de cada caso:
Comosecubrió, sellamóalmétodo str cuandopasamosnuestrainstanciadeCardaprinty 
al método repr cuando pasamos una lista de nuestras instancias a print .
Eneste punto, vale la pena señalar que al igual que podemos crear explícitamente una cadena 
desde una instancia de clase personalizada usando str() comolo hicimos anteriormente, también 
podemoscrearexplícitamenteuna representacióndecadenadenuestraclaseconunafunción 
incorporada llamada repr() .
Por ejemplo:
    931/1068
    867
print(four_of_clubs. repr ()) # 4 of Clubs (R)
print(four_of_clubs. str ()) # 4 of Clubs (S)
class Card:
special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'}
def init (self, suit, pips): 
self.suit = suit 
self.pips = pips
def repr (self):
card_name = Card.special_names.get(self.pips, str(self.pips)) 
return "%s of %s" % (card_name, self.suit)
# 6 of Hearts (implicit conversion) 
# 6 of Hearts (explicit conversion)
print(six_of_hearts) 
print(str(six_of_hearts))
#[6 of Hearts] (implicit conversion) 
# 6 of Hearts (explicit conversion)
print([six_of_hearts]) 
print(repr(six_of_hearts))
Y además, si está definido, podríamos llamar a los métodos directamente (aunque parece un 
poco incierto e innecesario):
Sobre esas funciones duplicadas ...
Losdesarrolladores de Python se dieron cuenta de que, en el caso de quequisieras que se 
devolvieran cadenas idénticas desde str() y repr() es posible que tengas que duplicar 
funcionalmente los métodos, algo que a nadie le gusta.
Entonces, en cambio, existe un mecanismo para eliminar la necesidad de eso. Una que te colgué 
hasta este punto. Resulta que si una clase implementa el método repr pero no el método
 str , y usted pasaunainstanciadeesaclaseastr()(yasea de maneraimplícita oexplícita), 
Python repr su implementación repr y lo usará.
Entonces, para ser claros, considere la siguiente versión de la clase de Card :
Tengaencuentaqueestaversiónsoloimplementaelmétodo repr .Noobstante,lasllamadas 
a str()dan como resultado una versión fácil de usar:
al igual que las llamadas a repr() :
Resumen
# 4 of Clubs (R)
repr_card = repr(four_of_clubs) 
print(repr_card)
print(str_card) # 4 of Clubs (S)
    932/1068
    868
class Card:
special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'}
def init (self, suit, pips): 
self.suit = suit 
self.pips = pips
# Called when instance is converted to a string via str() 
# Examples:
# print(card1)
# print(str(card1) 
def str (self):
card_name = Card.special_names.get(self.pips, str(self.pips)) 
return "%s of %s" % (card_name, self.suit)
# Called when instance is converted to a string via repr() 
# Examples:
# print([card1, card2, card3]) 
# print(repr(card1))
def repr (self):
return "Card(%s, %d)" % (self.suit, self.pips)
Para que pueda habilitar las instancias de su clase para que se "muestren" de manera fácil de 
usar, querrá considerar implementar al menos el método repr su clase. Si la memoria sirve, 
durante una charla, Raymond Hettinger dijo que asegurarse de que las clasesimplementen
 repr es una de las primeras cosas que busca mientras hace revisiones de código Python, y 
hasta ahora debería estar claro por qué. La cantidad de información que podría haber agregado a 
las declaraciones de depuración, los informes de fallos o los archivos de registro con un método 
simple es abrumadora en comparación con la información más escasa y, a menudo, poco útil 
(tipo, id) que se proporciona de forma predeterminada.
Sideseadiferentes representaciones paracuando,porejemplo,dentrodeuncontenedor,querrá 
implementar los métodos repr y str . (Más sobre cómo puede usar estos dos métodos de 
manera diferente a continuación).
Ambos métodos implementados, eval-round-trip style repr ()
    933/1068
    869
a = 7
if a > 5: 
print "foo"
else:
print "bar" 
print "done"
if True: 
print "true"
if True: 
a = 6
b = 5
def isEven(a): 
if a%2 ==0:
return True
#this next line should be even with the if 
return False
print isEven(7)
class ExampleClass:
#Every function belonging to a class must be indented equally 
def init (self):
Capítulo 178: Sangría
Examples
Errores de sangría
El espacio debe ser uniforme y uniforme en todo. La sangría incorrecta puede causar un 
IndentationError o hacer que el programa haga algo inesperado. El siguiente ejemplo genera un 
IndentationError :
O si la línea que sigue a dos puntos no tiene sangría, también se levantará un IndentationError :
Si agrega sangría donde no pertenece, se generará un IndentationError :
Si olvida desmarcar la funcionalidad podría perderse. En este ejemplo, None se devuelve en lugar 
del False esperado:
Ejemplo simple
Para Python, Guido van Rossum basó la agrupación de declaraciones en sangría. Las razones de 
esto se explican en la primera sección de las "Preguntas frecuentes sobre Python de diseño e
historia" . Los dos puntos, : , se utilizan para declarar un bloque de código con sangría , como el 
siguiente ejemplo:
    934/1068
    870
if foo:
if bar:
x = 42
¿Espacios o pestañas?
La sangría recomendada es de 4 espacios, pero se pueden usar tabulaciones o espacios siempre 
que sean consistentes. No mezcle tabulaciones y espacios en Python ya que esto causará un 
error en Python 3 y puede causar errores en Python 2 .
Cómo se analiza la sangría
Los espacios en blanco son manejados por el analizador léxico antes de ser analizados.
El analizadorléxico usa una pila para almacenar niveles de sangría.Al principio, la pila contiene 
solo el valor 0, que es la posición más a la izquierda. Cada vez que comienza un bloque anidado, 
el nuevo nivel de sangría se empuja en la pila, y se inserta un token "INDENT" en el flujo de token 
que se pasa al analizador. Nunca puede haber más de un token "INDENT" en una fila ( 
IndentationError ).
Cuando se encuentra una línea con un nivel de sangría más pequeño, los valores se extraen de 
la pila hasta que un valor está en la parte superior, que es igual al nuevo nivel de sangría (si no se 
encuentra ninguno, se produce un error de sintaxis). Para cada valor que aparece, se genera un 
token "DEDENT". Obviamente, puede haber múltiples tokens "DEDENT" en una fila.
El analizador léxico omite líneas vacías (aquellas que solo contienen espacios en blanco y 
posiblemente comentarios), y nunca generará tokens "INDENT" o "DEDENT" para ellas.
Al final del código fuente, se generan tokens "DEDENT" para cada nivel de sangrado que queda 
en la pila, hasta que solo queda el 0.
Por ejemplo:
name = "example"
def someFunction(self, a):
#Notice everything belonging to a function must be indented 
if a > 5:
return True 
else:
return False
#If a function is not indented to the same level it will not be considers as part of the 
parent class
def separateFunction(b): 
for i in b:
#Loops are also indented and nested conditions start a new indentation 
if i == 1:
return True 
return False
separateFunction([2,3,5,6,1])
    935/1068
    871
se analiza como:
<if> <foo> <:> [0]
<INDENT> <if> <bar> <:> [0, 4]
<INDENT> <x> <=> <42> [0, 4, 8]
<DEDENT> <DEDENT> <else> <:> [0]
<INDENT> <print> <foo> [0, 2]
<DEDENT>
El analizador que maneja los tokens "INDENT" y "DEDENT" como delimitadores de bloque. 
else:
print foo
    936/1068
    872
"This is a string"
b"This is a buffer of bytes"
import hashlib
h = hashlib.new('sha256')
h.update(b'Nobody expects the Spanish Inquisition.') 
h.digest()
# ==>
b'.\xdf\xda\xdaVR[\x12\x90\xff\x16\xfb\x17D\xcf\xb4\x82\xdd)\x14\xff\xbc\xb6Iy\x0c\x0eX\x9eF-
='
h.hexdigest()
Capítulo 179: Seguridad y criptografía
Introducción
Python, siendo uno de los lenguajes más populares en seguridad de computadoras y redes, tiene 
un gran potencial en seguridad y criptografía. Este tema trata sobre las funciones criptográficas y 
las implementaciones en Python desde sus usos en seguridad informática y de red hasta 
algoritmos de hash y cifrado / descifrado.
Sintaxis
• hashlib.new (nombre)
• hashlib.pbkdf2_hmac (nombre, contraseña, salt, rounds, dklen = Ninguno)
Observaciones
Muchos de los métodos en hashlib requerirán que usted pase valores interpretables como buffers 
de bytes, en lugar de cadenas. Este es el caso de hashlib.new().update() así como 
hashlib.pbkdf2_hmac .Sitieneunacadena, puedeconvertirla enunbúfer debytesal añadirel 
carácter b al comienzo de lacadena:
Examples
Cálculo de un resumen del mensaje
El módulo hashlib permite crear generadores de resumen de mensajes a través del new método. 
Estos generadores convertirán una cadena arbitraria en un compendio de longitud fija:
Tengaencuentaquepuedellamaralaupdateunnúmeroarbitrariodevecesantesdellamaral 
digestqueesútilparaagruparunfragmentodearchivograndeporfragmento.Tambiénpuede 
obtener el resumen en formato hexadecimal utilizandohexdigest :
    937/1068
    873
import hashlib 
hashlib.algorithms_available
# ==> {'sha256', 'DSA-SHA', 'SHA512', 'SHA224', 'dsaWithSHA', 'SHA', 'RIPEMD160', 'ecdsa-withSHA1', 'sha1', 'SHA384', 'md5', 'SHA1', 'MD5', 'MD4', 'SHA256', 'sha384', 'md4', 'ripemd160',
'sha224', 'sha512', 'DSA', 'dsaEncryption', 'sha', 'whirlpool'}
hashlib.algorithms_guaranteed
# ==> {'sha256', 'sha384', 'sha1', 'sha224', 'md5', 'sha512'}
import hashlib 
import os
salt = os.urandom(16)
hash = hashlib.pbkdf2_hmac('sha256', b'password', salt, 100000)
import binascii
hexhash = binascii.hexlify(hash)
Algoritmos de hash disponibles
hashlib.new requiere el nombre de un algoritmo cuando lo llama para producir un generador. Para 
averiguar qué algoritmos están disponibles en el intérprete de Python actual, use 
hashlib.algorithms_available :
La lista devuelta variará según la plataforma y el intérprete; Asegúrate de comprobar que tu 
algoritmo está disponible.
Tambiénhayalgunosalgoritmosqueestángarantizadosparaestardisponiblesentodaslas 
plataformas e intérpretes, que están disponibles usando hashlib.algorithms_guaranteed :
Contraseña segura Hashing
El algoritmo hashlib expuesto por el módulo hashlib se puede usar para realizar el hashing de 
contraseña seguro. Si bien este algoritmo no puede evitar los ataques de fuerza bruta para 
recuperar la contraseña original del hash almacenado, hace que dichos ataques sean muy 
costosos.
PBKDF2 puede funcionar con cualquier algoritmo de resumen, el ejemplo anterior utiliza SHA256, 
que generalmente se recomienda. La sal aleatoria debe almacenarse junto con la contraseña 
hash, la necesitará nuevamente para comparar una contraseña ingresada con el hash 
almacenado. Es esencial que cada contraseña tenga una sal diferente. En cuanto al número de 
rondas, se recomienda establecerlo lo más alto posible para su aplicación .
Si desea que el resultado sea hexadecimal, puede usar el módulo binascii :
Nota : si bien PBKDF2 no es malo, bcrypt y especialmente scrypt se consideran más fuertes 
contra los ataques de fuerza bruta. Tampoco es parte de la biblioteca estándar de Python en este
# ==> '2edfdada56525b1290ff16fb1744cfb482dd2914ffbcb649790c0e589e462d3d'
    938/1068
    874
import hashlib
hasher = hashlib.new('sha256') 
with open('myfile', 'r') as f:
contents = f.read() 
hasher.update(contents)
print hasher.hexdigest()
import hashlib 
SIZE = 65536
hasher = hashlib.new('sha256') 
with open('myfile', 'r') as f:
buffer = f.read(SIZE) 
while len(buffer) > 0:
hasher.update(buffer) 
buffer = f.read(SIZE)
print(hasher.hexdigest())
import hashlib 
import math 
import os
from Crypto.Cipher import AES
IV_SIZE = 16 # 128 bit, fixed for the AES algorithm
KEY_SIZE = 32 # 256 bit meaning AES-256, can also be 128 or 192 bits 
SALT_SIZE = 16 # This size is arbitrary
cleartext = b'Lorem ipsum'
password = b'highly secure encryption password' 
salt = os.urandom(SALT_SIZE)
derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000,
momento.
Hash de archivo
Un hash es una función que convierte una secuencia de longitud variable de bytes en una 
secuencia de longitud fija. Los archivos de hash pueden ser ventajosos por muchas razones. Los 
hash se pueden usar para verificar si dos archivos son idénticos o verificar que el contenido de un 
archivo no se haya dañado o cambiado.
Puedes usar hashlib para generar un hash para un archivo:
Para archivos más grandes, se puede usar un búfer de longitud fija:
Cifrado simétrico utilizando pycrypto
La funcionalidad criptográfica incorporada de Python se limita actualmente al hashing. El cifrado 
requiere un módulo de terceros como pycrypto . Por ejemplo, proporciona el algoritmo AES que 
se considera el estado de la técnica para el cifrado simétrico. El siguiente código cifrará un 
mensaje dado usando una frase de contraseña:
    939/1068
    875
salt = encrypted[0:SALT_SIZE]
derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000,
dklen=IV_SIZE + KEY_SIZE)
iv = derived[0:IV_SIZE] 
key = derived[IV_SIZE:]
cleartext = AES.new(key, AES.MODE_CFB, iv).decrypt(encrypted[SALT_SIZE:])
import errno
from Crypto.Hash import SHA256 
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5 
message = b'This message is from me, I promise.'
try:
with open('privkey.pem', 'r') as f: 
key = RSA.importKey(f.read())
except IOError as e:
if e.errno != errno.ENOENT:
El algoritmo AES toma tres parámetros: clave de cifrado, vector de inicialización (IV) y el mensaje 
real a cifrar. Si tiene una clave AES generada aleatoriamente, puede usarla directamente y 
simplemente generar un vector de inicialización aleatorio. Sin embargo, una frase de contraseña 
no tiene el tamaño correcto, ni sería recomendable utilizarla directamente, ya que no esrealmente 
aleatoria y, por lo tanto, tiene una entropía relativamente pequeña. En su lugar, usamos la 
implementación incorporada del algoritmo PBKDF2 para generar un vector de inicialización de 
128 bits y una clave de cifrado de 256 bits a partir de la contraseña.
Tenga en cuenta la sal aleatoria que es importante tener un vector de inicialización diferente y 
una clave para cada mensaje cifrado. Esto garantiza en particular que dos mensajes iguales no 
darán como resultado un texto cifrado idéntico, pero también evita que los atacantes reutilicen el 
trabajo empleado en adivinar una frase de contraseña en los mensajes cifrados con otra frase de 
contraseña. Esta sal debe almacenarse junto con el mensaje cifrado para poder derivar el mismo 
vector de inicialización y la clave para descifrar.
El siguiente código volverá a descifrar nuestro mensaje:
Generando firmas RSA usando pycrypto
RSA se puede utilizar para crear una firma de mensaje. Una firma válida solo se puede generar 
con acceso a la clave RSA privada, por lo que la validación es posible con la clave pública 
correspondiente. Por lo tanto, mientras la otra parte sepa su clave pública, podrán verificar el 
mensaje que usted firmará y no se modificará, por ejemplo, un enfoque utilizado para el correo 
electrónico. Actualmente, se requiere un módulo de terceros como pycrypto para esta
funcionalidad.
dklen=IV_SIZE + KEY_SIZE)
iv = derived[0:IV_SIZE] 
key = derived[IV_SIZE:]
encrypted = salt + AES.new(key, AES.MODE_CFB, iv).encrypt(cleartext)
    940/1068
    876
with open('pubkey.pem', 'rb') as f: 
key = RSA.importKey(f.read())
hasher = SHA256.new(message) 
verifier = PKCS1_v1_5.new(key)
if verifier.verify(hasher, signature): 
print('Nice, the signature is valid!')
else:
print('No, the message was signed with the wrong private key or modified')
from Crypto.Cipher import PKCS1_OAEP 
from Crypto.PublicKey import RSA
message = b'Thisis a very secret message.' 
with open('pubkey.pem', 'rb') as f:
key = RSA.importKey(f.read())
cipher = PKCS1_OAEP.new(key) 
encrypted = cipher.encrypt(message)
with open('privkey.pem', 'rb') as f: 
key = RSA.importKey(f.read())
cipher = PKCS1_OAEP.new(key) 
decrypted = cipher.decrypt(encrypted)
La verificación de la firma funciona de manera similar pero usa la clave pública en lugar de la 
clave privada:
Nota : los ejemplos anteriores utilizan el algoritmo de firma PKCS # 1 v1.5, que es muy común. 
pycrypto también implementa el nuevo algoritmo PKCS # 1 PSS, reemplazando PKCS1_v1_5 por 
PKCS1_PSS en los ejemplos debería funcionar si desea usar ese. Sin embargo, actualmente parece 
que hay pocas razones para usarlo .
Cifrado RSA asimétrico utilizando pycrypto
El cifrado asimétrico tiene la ventaja de que un mensaje puede cifrarse sin intercambiar una clave 
secreta con el destinatario del mensaje. El remitente simplemente necesita conocer la clave 
pública de los destinatarios, esto permite cifrar el mensaje de manera que solo el destinatario 
designado (que tiene la clave privada correspondiente) pueda descifrarlo. Actualmente, se 
requiere un módulo de terceros como pycrypto para esta funcionalidad.
El destinatario puede descifrar el mensaje si tiene la clave privada correcta:
raise
# No private key, generate a new one. This can take a few seconds. 
key = RSA.generate(4096)
with open('privkey.pem', 'wb') as f:
f.write(key.exportKey('PEM')) with
open('pubkey.pem', 'wb') as f:
f.write(key.publickey().exportKey('PEM'))
hasher = SHA256.new(message) 
signer = PKCS1_v1_5.new(key) 
signature = signer.sign(hasher)
    941/1068
    877
Nota : Los ejemplos anteriores utilizan el esquema de cifrado OPAP PKCS # 1. pycrypto también 
implementa el esquema de cifrado PKCS # 1 v1.5, este no se recomienda para nuevos 
protocolos, sin embargo, debido a advertencias conocidas .
    942/1068
    878
Capítulo 180: Serialización de datos
Sintaxis
• unpickled_string = pickle.loads (cadena)
• unpickled_string = pickle.load (file_object)
• pickled_string = pickle.dumps ([('', 'cmplx'), {('object',): None}], 
pickle.HIGHEST_PROTOCOL)
• pickle.dump (('', 'cmplx'), {('object',): None}], file_object, pickle.HIGHEST_PROTOCOL)
• unjsoned_string = json.loads (cadena)
• unjsoned_string = json.load (file_object)
• jsoned_string = json.dumps (('a', 'b', 'c', [1, 2, 3]))
• json.dump (('' a ',' b ',' c ', [1, 2, 3]), file_object)
Parámetros
Parámetro Detalles
Usando pickle o cPickle , es el método por el cual los objetos se serializan o no
protocol serializan.Probablementequierasusar pickle.HIGHEST_PROTOCOL aquí,loque 
significa el método más nuevo.
Observaciones
¿Por qué usar JSON?
• Soporte de idiomas
• Legible para humanos
• A diferencia de Pickle, no tiene el peligro de ejecutar código arbitrario
¿Por qué no usar JSON?
• No admite tipos de datos Pythonic
• Las claves en los diccionarios no deben ser más que tipos de datos de cadena.
¿Por qué Pickle?
• Gran manera de serializar Pythonic (tuplas, funciones, clases)
• Las claves en los diccionarios pueden ser de cualquier tipo de datos.
¿Por qué no pickle?
• Falta soporte de idiomas
• No es seguro cargar datos arbitrarios.
    943/1068
    879
import json
families = (['John'], ['Mark', 'David', {'name': 'Avraham'}]) 
# Dumping it into string
json_families = json.dumps(families)
# [["John"], ["Mark", "David", {"name": "Avraham"}]]
# Dumping it to file
with open('families.json', 'w') as json_file: 
json.dump(families, json_file)
# Loading it from string
json_families = json.loads(json_families)
# Loading it from file
with open('families.json', 'r') asjson_file: 
json_families = json.load(json_file)
# Importing pickle 
try:
import cPickle as pickle # Python 2 
except ImportError:
import pickle # Python 3
# Creating Pythonic object:
class Family(object):
def init (self, names): 
self.sons = names
def str (self):
return ' '.join(self.sons) 
my_family = Family(['John', 'David'])
# Dumping to string
pickle_data = pickle.dumps(my_family, pickle.HIGHEST_PROTOCOL)
# Dumping to file
Examples
Serialización utilizando JSON
JSON es un método de lenguaje cruzado, ampliamente utilizado para serializar datos.
Tipos de datos admitidos: int , float , booleano , cadena , lista y dict . Ver -> JSON Wiki para más 
Aquí hay un ejemplo que demuestra el uso básico de JSON :
Consulte el módulo JSON para obtener información detallada sobre JSON.
Serialización utilizando Pickle
Aquí hay un ejemplo que demuestra el uso básico de pickle :
    944/1068
    880
Consulte Pickle para obtener información detallada acerca de Pickle.
ADVERTENCIA : La documentación oficial para pickle deja en claro que no hay garantías de 
seguridad. No cargues ningún dato en el que no confíes en su origen.
withopen('family.p', 'w') as pickle_file: 
pickle.dump(families, pickle_file, pickle.HIGHEST_PROTOCOL)
# Loading from string
my_family = pickle.loads(pickle_data)
# Loading from file
with open('family.p', 'r') as pickle_file: 
my_family =pickle.load(pickle_file)
    945/1068
    881
Capítulo 181: Serialización de datos de 
salmuera
Sintaxis
• pickle.dump (objeto, archivo, protocolo) # Para serializar un objeto
• pickle.load (archivo) # Para des-serializar un objeto
• pickle.dumps (objeto, protocolo) # Para serializar un objeto a bytes
• pickle.loads (buffer) # Para eliminar un serial de un objeto de bytes
Parámetros
Parámetro Detalles
objeto El objeto que se va a almacenar.
expediente El archivo abierto que contendrá el objeto.
protocolo El protocolo utilizado para el decapado del objeto (parámetro opcional)
buffer Un objeto de bytes que contiene un objeto serializado.
Observaciones
Tipos pickleable
Los siguientes objetos son desmontables.
• None , True y False
• números (de todos los tipos)
• cuerdas (de todo tipo)
• tuple s, list s, set s y dict s que solo contienen objetos que se pueden recoger
• Funciones definidas en el nivel superior de un módulo.
• funciones integradas
• Clases que se definen en el nivel superior de un módulo.
○ instancias de dichas clases cuyo dict o el resultado de llamar a getstate () es 
seleccionable (consulte los documentos oficialespara obtener más información).
Basado en la documentación oficial de Python .
    946/1068
    882
import pickle
# An arbitrary collection of objects supported by pickle. 
data = {
'a': [1, 2.0, 3, 4+6j],
'b': ("character string", b"byte string"), 
'c': {None, True, False}
}
with open('data.pickle', 'wb') as f:
# Pickle the 'data' dictionary using the highest protocol available. 
pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
import pickle
with open('data.pickle', 'rb') as f:
# The protocol version used is detected automatically, so we do not 
# have to specify it.
data = pickle.load(f)
pickle y seguridad
El módulo pickle no es seguro . No debe utilizarse cuando se reciben datos serializados de una 
parte que no es de confianza, como a través de Internet.
Examples
Usando Pickle para serializar y deserializar un objeto
El módulo pickle implementa un algoritmo para convertir un objeto Python arbitrario en una serie 
de bytes. Este proceso también se llama serializar el objeto. El flujo de bytes que representa el 
objeto se puede transmitir o almacenar, y luego reconstruir para crear un nuevo objeto con las 
mismas características.
Para el código más simple, usamos las funciones dump() y load() .
Para serializar el objeto.
Deserializar el objeto.
Usando objetos de pickle y byte
También es posible serializar y deserializar objetos de byte, utilizando la función de dumps y loads ,
    947/1068
    883
serialized_data = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) 
# type(serialized_data) is bytes
deserialized_data = pickle.loads(serialized_data) 
# deserialized_data == data
class A(object):
def init (self, important_data): 
self.important_data = important_data
# Add data which cannot be pickled:
self.func = lambda: 7
# Add data which should never be pickled, because it expires quickly: 
self.is_up_to_date = False
def getstate (self):
return [self.important_data] # only this is needed
def setstate (self, state): 
self.important_data = state[0]
self.func = lambda: 7 # just some hard-coded unpicklable function 
self.is_up_to_date = False # even if it was before pickling
>>> a1 = A('very important')
>>>
>>> s = pickle.dumps(a1) # calls a1. getstate ()
>>>
>>> a2 = pickle.loads(s) # calls a1. setstate (['very important'])
>>> a2
< main .A object at 0x0000000002742470>
>>> a2.important_data 
'very important'
>>> a2.func() 
7
que son equivalentes a dump y load .
Personalizar datos en escabeche
Algunos datos no pueden ser decapados. Otros datos no deben ser decapados por otras razones.
Lo que será decapado se puede definir en el método getstate . Este método debe devolver 
algo que sea pickable.
En el lado opuesto está setstate : recibirá lo que getstate creóytienequeinicializarel 
objeto.
Ahora, esto se puede hacer:
La implementación aquí muestra una lista con un valor: [self.important_data] .Eso fue solo un 
ejemplo, getstate podríahaberdevueltocualquiercosaquesepuedarecoger,siemprey 
cuando setstate sepa cómo hacerel oppoisite.Unabuena alternativa esundiccionario de
    948/1068
    884
todos los valores: {'important_data': self.important_data} .
¡Elconstructornosellama!Tengaencuentaqueenelejemploanterior,lainstanciaa2secreó 
en pickle.loads sin haber llamado a A. init , por lo que A. setstate tuvo que inicializar todo 
lo que init se habría inicializado si se hubierallamado.
    949/1068
    885
python -m SimpleHTTPServer 9000
python -m http.server 9000
import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
HandlerClass = SimpleHTTPRequestHandler 
ServerClass = BaseHTTPServer.HTTPServer 
Protocol = "HTTP/1.0"
if sys.argv[1:]:
port = int(sys.argv[1]) 
else:
port = 8000
server_address = ('127.0.0.1', port)
HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address, HandlerClass)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..." 
httpd.serve_forever()
Capítulo 182: Servidor HTTP de Python
Examples
Ejecutando un servidor HTTP simple
Python 2.x 2.3
Python 3.x 3.0
La ejecución de este comando sirve los archivos del directorio actual en el puerto 9000 .
Si no se proporciona ningún argumento como número de puerto, el servidor se ejecutará en el 
puerto predeterminado 8000 .
El indicador -m buscará en sys.path el archivo .py correspondiente para ejecutarse como un 
módulo.
Si solo quieres servir en localhost, deberás escribir un programa Python personalizado como:
Archivos de servicio
Suponiendo que tiene el siguiente directorio de archivos:
    950/1068
    886
import SimpleHTTPServer 
import SocketServer
PORT = 8000
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("localhost", PORT), handler) 
print "Serving files at port {}".format(PORT) 
httpd.serve_forever()
import http.server 
import socketserver
PORT = 8000
handler = http.server.SimpleHTTPRequestHandler 
httpd = socketserver.TCPServer(("", PORT), handler) 
print("serving at port", PORT) 
httpd.serve_forever()
Puede configurar un servidor web para servir estos archivos de la siguiente manera: 
Python 2.x 2.3
Python 3.x 3.0
El módulo SocketServer proporciona las clases y funcionalidades para configurar un servidor de 
red.
SocketServer 's TCPServer clase configura un servidor utilizando el protocolo TCP. El constructor 
aceptauna tupla que representa la dirección del servidor(es decir, ladirección IP y el puerto) y la 
clase que maneja las solicitudes del servidor.
El SimpleHTTPRequestHandler clase del SimpleHTTPServer módulo permite a los archivos en el 
directorio actual para ser servido.
Guarde el script en el mismo directorio y ejecútelo. 
Ejecuta el servidor HTTP:
Python 2.x 2.3
python -m SimpleHTTPServer 8000 
Python 3.x 3.0
    951/1068
    887
def test(HandlerClass = SimpleHTTPRequestHandler, 
ServerClass =BaseHTTPServer.HTTPServer):
BaseHTTPServer.test(HandlerClass, ServerClass)
if name == ' main ': 
test()
def test(HandlerClass = BaseHTTPRequestHandler, 
ServerClass = HTTPServer, protocol="HTTP/1.0"):
"""Test the HTTP request handler class.
Thisruns an HTTP server on port 8000 (or the first command line 
argument).
"""
if sys.argv[1:]:
port = int(sys.argv[1]) 
else:
port = 8000
python -m http.server 8000
El indicador '-m' buscará 'sys.path' para que el archivo '.py' correspondiente se ejecute como un 
módulo.
Abra localhost: 8000 en el navegador, le dará lo siguiente:
API programática de SimpleHTTPServer
¿Qué sucede cuando ejecutamos python -m SimpleHTTPServer 9000 ?
Para responder a esta pregunta, debemos entender el constructo de SimpleHTTPServer ( 
https://hg.python.org/cpython/file/2.7/Lib/SimpleHTTPServer.py) y BaseHTTPServer ( 
https://hg.python.org/cpython/file /2.7/Lib/BaseHTTPServer.py) .
En primer lugar, Python invoca el módulo SimpleHTTPServer con 9000 como argumento. Ahora 
observando el código SimpleHTTPServer,
La función de prueba se invoca después de los controladores de solicitudes y ServerClass. Ahora 
se invoca BaseHTTPServer.test
    952/1068
    888
|UDPServer| ------->|UnixDatagramServer|
+-----------+ +--------------------+
+--------------------+
+-----------+ +------------------+
| 
v
+-----------+
|TCPServer| ------- >|UnixStreamServer|
+------------------+
+------------+
|BaseServer|
+------------+
| 
v
+-----------+
# from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer # python2 
from http.server import BaseHTTPRequestHandler, HTTPServer # python3 
class HandleRequests(BaseHTTPRequestHandler):
def _set_headers(self): 
self.send_response(200)
self.send_header('Content-type', 'text/html') 
self.end_headers()
def do_GET(self): 
self._set_headers()
self.wfile.write("received get request")
def do_POST(self):
'''Reads post request body''' 
self._set_headers()
content_len = int(self.headers.getheader('content-length', 0)) 
post_body = self.rfile.read(content_len) 
self.wfile.write("received post request:<br>{}".format(post_body))
def do_PUT(self): 
self.do_POST()
Por lo tanto, aquí se analiza el número de puerto, que el usuario pasó como argumento y está 
vinculado a la dirección del host. Se llevan a cabo otros pasos básicos de programación de socket 
con puerto y protocolo dados. Finalmente se inicia el servidor socket.
Esta es una descripción básica de la herencia de la clase SocketServer a otras clases:
Los enlaces https://hg.python.org/cpython/file/2.7/Lib/BaseHTTPServer.py y 
https://hg.python.org/cpython/file/2.7/Lib/SocketServer.py son útiles para encontrar más 
información. información.
Manejo básico de GET, POST, PUT usando BaseHTTPRequestHandler
server_address = ('', port)
HandlerClass.protocol_version = protocol
httpd = ServerClass(server_address, HandlerClass)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..." 
httpd.serve_forever()
    953/1068
    889
$ curl http://localhost/
received get request%
$ curl -X POST http://localhost/
received post request:<br>%
$ curl -X PUT http://localhost/
received post request:<br>%
$ echo 'hello world' | curl --data-binary @- http://localhost/
received post request:<br>hello world
Ejemplo de salida utilizando curl :
host = '' 
port = 80
HTTPServer((host, port), HandleRequests).serve_forever()
    954/1068
    890
from distutils.core import setup
setup(name='foo',
version='1.0', 
py_modules=['foo'],
)
Capítulo 183: setup.py
Parámetros
Parámetro Uso
name Nombre de su distribución.
version Cadena de versión de su distribución.
packages
ListadepaquetesdePython (esdecir,directoriosquecontienenmódulos)para 
incluir. Esto se puede especificar manualmente, pero en su 
setuptools.find_packages() se suele usar una llamada a 
setuptools.find_packages() .
py_modules
Lista de módulos de Python de nivel superior (es decir, archivos .py
individuales) para incluir.
Observaciones
Para más información sobre el embalaje de python, consulte:
Introducción
Para escribir paquetes oficiales hay una guía de usuario de empaquetado .
Examples
Propósito de setup.py
El script de configuración es el centro de toda actividad en la construcción, distribución e 
instalación de módulos utilizando los Distutils. Su propósito es la correcta instalación del software.
Si todo lo que quiere hacer es distribuir un módulo llamado foo, contenido en un archivo foo.py, su 
secuencia de comandos de instalación puede ser tan simple como esto:
Para crear una distribución de origen para este módulo, debe crear un script de configuración, 
setup.py, que contenga el código anterior, y ejecutar este comando desde una terminal:
    955/1068
    891
python setup.py install
greetings/
greetings/
 init .py 
hello_world.py
python greetings/greetings/hello_world.py
hello_world.py
from setuptools import setup 
setup(
name='greetings', 
scripts=['hello_world.py']
)
sdist creará un archivo de archivo (por ejemplo, tarball en Unix, archivo ZIP en Windows) que 
contiene su script de configuración setup.py y su módulo foo.py. El archivo comprimido se llamará 
foo-1.0.tar.gz (o .zip) y se descomprimirá en un directorio foo-1.0.
Si un usuario final desea instalar su módulo foo, todo lo que tiene que hacer es descargar foo1.0.tar.gz (o .zip), descomprimirlo y, desde el directorio foo-1.0, ejecutar
Agregando scripts de línea de comandos a su paquete de Python
Los guiones de línea de comando dentro de los paquetes de python son comunes. Puede 
organizar su paquete de tal manera que cuando un usuario instala el paquete, el script estará 
disponible en su ruta.
Si tenía el paquete de greetings que tenía la secuencia de comandos script hello_world.py .
Puedes ejecutar ese script ejecutando:
Sin embargo si quieres correrlo así:
Puede lograr esto agregando scripts a su setup() en setup.py estamanera:
Cuando instale el paquete de saludos ahora, se agregará a su ruta hello_world.py . 
Otra posibilidad sería agregar un punto de entrada:
De esta manera solo tienes que ejecutarlo como:
entry_points={'console_scripts': ['greetings=greetings.hello_world:main']}
python setup.py sdist
    956/1068
    892
from setuptools import setup, find_packages
setup(
setup_requires=['setuptools_scm'], 
use_scm_version=True, 
packages=find_packages(), 
include_package_data=True,
)
python setup.py install
python setup.py develop
cmdclasses = dict()
class BuildSphinx(Command): 
"""Build Sphinx documentation."""
description = 'Build Sphinx documentation' 
user_options = []
def initialize_options(self): 
pass
def finalize_options(self): 
pass
def run(self):
import sphinx
Usando metadatos de control de fuente en setup.py
setuptools_scm es un paquete oficialmente bendecido que puede usar metadatos de Git o
Mercurial para determinar el número de versión de su paquete, y encontrar paquetes de Python y 
datos de paquetes para incluir en ellos.
Esteejemploutilizaambas características;parausarsololosmetadatosdeSCMparalaversión, 
reemplace la llamada a find_packages() con su lista de paquetes del manual, o para usar solo el 
buscador de paquetes, elimine use_scm_version=True .
Añadiendo opciones de instalación
Como se vio en ejemplos anteriores, el uso básico de este script es:
Pero hay aún más opciones, como instalar el paquete y tener la posibilidad de cambiar el código y 
probarlo sin tener que volver a instalarlo. Esto se hace usando:
Si desea realizar acciones específicas como compilar una documentación de Sphinx o crear un 
código fortran , puede crear su propia opción como esta:
greetings
    957/1068
    893
python setup.py build_sphinx
initialize_options y finalize_options se ejecutarán antes y después de la función de run , tal 
como lo sugieren susnombres.
Después de eso, podrás llamar a tu opción:
sphinx.build_main(['setup.py', '-b', 'html', './doc', './doc/_build/html'])
sphinx.build_main(['setup.py', '-b', 'man', './doc', './doc/_build/man']) 
cmdclasses['build_sphinx'] = BuildSphinx
setup(
...
cmdclass=cmdclasses,
)
    958/1068
    894
2 in [2, 3]
{'0': 2, '1': 3}
Capítulo 184: Similitudes en la sintaxis, 
diferencias en el significado: Python vs. 
JavaScript
Introducción
A veces sucede que dos idiomas ponen significados diferentes en la misma expresión desintaxis 
o similar. Cuando ambos lenguajes son de interés para un programador, aclarar estos puntos de 
bifurcación ayuda a comprender mejor los dos lenguajes en sus conceptos básicos y sutilezas.
Examples
`in` con listas
En Python esto se evalúa como Verdadero, pero en JavaScript como falso. Esto se debe a queen 
Python comprueba si un valor está contenido en una lista, por lo que 2 está en [2, 3] como su 
primer elemento. En JavaScript se usa con objetos y comprueba si un objeto contiene la 
propiedad con el nombre expresado por el valor. Así que JavaScript considera [2, 3] como un 
objeto o un mapa de clave-valor como este:
y verifica si tiene una propiedad o una clave '2' en ella. El entero 2 se convierte silenciosamente a 
la cadena '2'.
    959/1068
    895
import math
class Vector(object): 
# instantiation
def init (self, x, y): 
self.x = x
self.y = y
# unary negation (-v) 
def neg (self):
return Vector(-self.x, -self.y)
# addition (v + u)
def add (self, other):
return Vector(self.x + other.x, self.y + other.y)
# subtraction (v - u) 
def sub (self, other):
return self + (-other)
# equality (v == u) 
def eq (self, other):
return self.x == other.x and self.y == other.y
# abs(v)
def abs (self):
return math.hypot(self.x, self.y)
# str(v)
def str (self):
return '<{0.x}, {0.y}>'.format(self)
# repr(v)
def repr (self):
return 'Vector({0.x}, {0.y})'.format(self)
v = Vector(1, 4)
Capítulo 185: Sobrecarga
Examples
Métodos de magia / Dunder
Los métodos de Magic (también llamados dunder como abreviatura de subrayado doble) en 
Python tienen un propósito similar al de la sobrecarga de operadores en otros idiomas. Permiten a 
una clase definir su comportamiento cuando se usa como un operando en expresiones de 
operador unarias o binarias. También sirven como implementaciones llamadas por algunas 
funciones integradas.
Considere esta implementación de vectores bidimensionales.
Ahora es posible usar naturalmente instancias de la clase Vector en varias expresiones.
    960/1068
    896
class sparselist(object): 
def init (self, size):
self.size = size 
self.data = {}
# l[index]
def getitem (self, index): 
if index < 0:
index += self.size 
if index >= self.size:
raise IndexError(index) 
try:
return self.data[index] 
except KeyError:
return 0.0
# l[index] = value
def setitem (self, index, value): 
self.data[index] = value
# del l[index]
def delitem (self, index): 
if index in self.data:
del self.data[index]
# value in l
def contains (self, value):
return value == 0.0 or value in self.data.values()
# len(l)
def len (self): 
return self.size
# for value in l: ... 
def iter (self):
return (self[i] for i in range(self.size)) # use xrange for python2
l = sparselist(10 ** 6) # list with 1 million elements 
0 in l # True
Contenedor y tipos de secuencia.
Es posible emular tipos de contenedores, que admiten el acceso a valores por clave o índice.
Considere esta implementación ingenua de una lista dispersa, que almacena solo los elementos 
que no son cero para conservar la memoria.
Entonces, podemos usar una lista sparselist como una list normal.
u = Vector(2, 0)
u + v # Vector(3, 4)
print(u + v) # "<3, 4>" (implicit string conversion) 
u - v # Vector(1, -4)
u == v # False 
u + v == v + u # True 
abs(u + v) # 5.0
    961/1068
    897
class adder(object):
def init (self, first): 
self.first = first
# a(...)
def call (self, second): 
return self.first + second
add2 = adder(2) 
add2(1) # 3
add2(2) # 4
class NotAddable(object):
def init (self, value): 
self.value = value
def add (self, other): 
return NotImplemented
class Addable(NotAddable): 
def add (self, other):
return Addable(self.value + other.value)
 radd = add
Tipos callables
Manejando conductas no implementadas.
Sisuclasenoimplementaunoperadorsobrecargadoespecíficoparalostiposdeargumentos 
provistos, debería return NotImplemented (tenga en cuenta que esta es una constante especial , 
nolamisma que NotImplementedError ).Estopermitirá aPythonvolver aprobar otros métodos para 
hacer que la operaciónfuncione:
Cuando se devuelve NotImplemented , el intérprete intentará la operación reflejada en el 
otro tipo,o algún otro repliegue, dependiendo del operador.Si todas las operaciones 
intentadas devuelven No NotImplemented , el intérprete generará una excepción 
apropiada.
Por ejemplo, dado x + y , si x. add (y) devuelve no implementado, y. radd (x) se intenta en 
su lugar.
for v in l:
pass # 0, 0, 0, ... 10, 0, 0 ... 0
# True 
# 10
l[12345] = 10
10 in l
l[12345]
10 in l # False
    962/1068
    898
>>> x = NotAddable(1)
>>> y = Addable(2)
>>> x + x
Traceback (most recent call last): 
File "<stdin>", line 1, in<module>
TypeError: unsupported operand type(s) for +: 'NotAddable' and 'NotAddable'
>>> y + y
<so.Addable object at 0x1095974d0>
>>> z = x + y
>>> z
<so.Addable object at 0x109597510>
>>> z.value 
3
Como este es el método reflejado , debemos implementar add y radd para obtener el 
comportamientoesperadoentodosloscasos;afortunadamente,comoambosestánhaciendolo 
mismo en este simple ejemplo, podemos tomar un atajo.
En uso:
Sobrecarga del operador
A continuación se muestran los operadores que pueden sobrecargarse en clases, junto con las 
definiciones de métodos que se requieren y un ejemplo del operador en uso dentro de una 
expresión.
Nota: el uso de other como nombre de variable no es obligatorio, pero se considera la 
norma.
Operador Método Expresión
+ Adición add (self, other) a1 + a2
- Resta sub (self, other) a1 - a2
* Multiplicación mul (self, other) a1 * a2
@ Matrix Multiplication matmul (self, other) a1 @ a2 ( Python 3.5 )
/ División div (self, other) a1 / a2 ( solo Python 2 )
/ División truediv (self, other) a1 / a2 ( Python 3 )
//División del piso floordiv (self, other) a1 // a2
% Modulo / resto mod (self, other) a1 % a2
** Poder pow (self, other[, modulo]) a1 ** a2
<< Bitwise Left Shift lshift (self, other) a1 << a2
>> Bitwise Right Shift rshift (self, other) a1 >> a2
    963/1068
    899
class A:
def init (self, a): 
self.a = a
def add (self, other): 
return self.a + other
def radd (self, other): 
print("radd")
return other + self.a
A(1) + 2 # Out: 3
2 + A(1) # prints radd. Out: 3
Operador Método Expresión
& Bitwise Y
^ Bitwise XOR
 and (self, other)
xor (self, other)
a1
a1
&
^
a2
a2
|(Bitwise OR) or (self, other) a1 | a2
- Negación(Aritmética) neg (self) -a1
+ Positivo pos (self) +a1
~ Bitwise NO invert (self) ~a1
< Menos que lt (self, other) a1 < a2
<= Menor que o igual a le (self, other) a1 <= a2
== Igual a eq (self, other) a1 == a2
!= No es igual a ne (self, other) a1 != a2
> Mayor que gt (self, other) a1 > a2
>= Mayor que o igual a ge (self, other) a1 >= a2
[index] operador deíndice getitem (self, index) a1[index]
in En operador contains (self, other) a2 in a1
(*args, ...) Llamando call (self, *args, **kwargs) a1(*args, **kwargs)
El modulo parámetro opcionalpara pow solo lo utiliza la función incorporada pow .
Cadaunodelosmétodoscorrespondientes a unoperadorbinariotieneunmétodo"correcto" 
correspondiente que comienza con r , por ejemplo radd :
así como una versión in situ correspondiente, comenzando con i :
    964/1068
    900
Como no hay nada especial en estos métodos, muchas otras partes del lenguaje, partes de la 
biblioteca estándar e incluso módulos de terceros agregan métodos mágicos por sí mismos, como 
métodos para convertir un objeto en un tipo o verificar las propiedades del objeto. Por ejemplo, la 
función str() incorporada llama al método str del objeto, si existe. Algunos de estos usos se 
enumeran a continuación.
Función Método Expresión
Casting a int int (self) int(a1)
Función absoluta abs (self) abs(a1)
Casting a str str (self) str(a1)
Casting a unicode unicode (self) unicode(a1) (solo Python 2)
Representación de cuerdas repr (self) repr(a1)
Casting a bool nonzero (self) bool(a1)
Formato de cadena format (self, formatstr) "Hi {:abc}".format(a1)
Hash hash (self) hash(a1)
Longitud len (self) len(a1)
Invertido reversed (self) reversed(a1)
Piso floor (self) math.floor(a1)
Techo ceil (self) math.ceil(a1)
También existen los métodos especiales enter y exit paraadministradoresdecontexto,y 
muchos más.
class B:
def init (self, b): 
self.b = b
def iadd (self, other): 
self.b += other 
print("iadd") 
return self
b = B(2)
b.b # Out: 2
b += 1 # prints iadd
b.b # Out: 3
    965/1068
    901
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
host = raw_input("Server Address To Be Connected -> ") 
port = int(input("Port of The Server -> ")) 
server.connect((host, port))
Capítulo 186: Sockets y cifrado / descifrado 
de mensajes entre el cliente y el servidor
Introducción
La criptografía se utiliza para fines de seguridad. No hay tantos ejemplos de cifrado / descifrado 
en Python utilizando el CTR de MODO de cifrado de IDEA. Objetivo de esta documentación:
Ampliación e implementación del esquema de firma digital RSA en la comunicación de estación a 
estación. Usando Hashing para la integridad del mensaje, eso es SHA-1. Produce un protocolo 
simple de transporte de llaves. Cifrar clave con cifrado IDEA. El modo de cifrado de bloque es el 
modo contador.
Observaciones
Idioma utilizado: Python 2.7 (enlace de descarga: https://www.python.org/downloads/ )
Biblioteca utilizada:
* PyCrypto (Enlace de descarga: https://pypi.python.org/pypi/pycrypto )
* PyCryptoPlus (Enlace de descarga: https://github.com/doegox/python-cryptoplus )
Instalación de la biblioteca:
PyCrypto: descomprime el archivo. Vaya al directorio y abra el terminal para Linux (alt + ctrl + t) 
y CMD (Mayús + clic con el botón derecho + seleccionar indicador de comando abrir aquí) para 
Windows. Después de eso, escriba python setup.py install (Asegúrese de que Python 
Environment esté configurado correctamente en el sistema operativo Windows)
PyCryptoPlus: igual que la última biblioteca.
Implementación de tareas: La tarea se divide en dos partes. Uno es el proceso de apretón de 
manos y otro es el proceso de comunicación. Configuración de zócalo:
• Como la creación de claves públicas y privadas, así como el hashing de la clave pública, 
necesitamos configurar el socket ahora. Para configurar el socket, debemos importar otro 
módulo con "importar socket" y conectar (para el cliente) o vincular (para el servidor) la 
dirección IP y el puerto con el socket que recibe del usuario.
----------Lado del cliente----------
    966/1068
    902
try:
#setting up socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
server.bind((host,port))
server.listen(5)
except BaseException: print "-----Check Server Address or Port-------"
random_generator = Random.new().read
key = RSA.generate(1024,random_generator) 
public = key.publickey().exportKey()
hash_object = hashlib.sha1(public) 
hex_digest = hash_object.hexdigest()
----------Lado del servidor---------
"Socket.AF_INET, socket.SOCK_STREAM" nos permitirá utilizar la función accept () y 
los aspectos básicos de los mensajes. En lugar de eso, también podemos usar 
"socket.AF_INET, socket.SOCK_DGRAM", pero esa vez tendremos que usar 
setblocking (valor).
Proceso de apretón de manos:
• (CLIENTE) La primera tarea es crear claves públicas y privadas. Para crear la clave privada 
y pública, tenemos que importar algunos módulos. Son: desde Crypto import Random y 
desde Crypto.PublicKey import RSA. Para crear las claves, tenemos que escribir algunas 
líneas simples de códigos:
random_generator se deriva del módulo " desde Crypto import Random ". La clave se deriva de 
" from Crypto.PublicKey import RSA " que creará una clave privada, tamaño de 1024 
generando caracteres aleatorios. Público está exportando clave pública desde clave privada 
generada anteriormente.
• (CLIENTE) Después de crear la clave pública y privada, debemos codificar la clave pública 
para enviarla al servidor mediante el hash SHA-1. Para usar el hash SHA-1 necesitamos 
importar otro módulo escribiendo "importar hashlib". Para codificar la clave pública, 
escribimos dos líneas de código:
Aquíhash_objectyhex_digestesnuestravariable.Despuésdeesto,elclienteenviaráhex_digest 
y public al servidor y el Servidorlos verificará comparando el hash obtenido del cliente y el nuevo 
hash de la clave pública. Si el nuevo hash y el hash del cliente coinciden, pasará al siguiente 
procedimiento. Como el público enviado desde el cliente está en forma de cadena, no podrá 
utilizarse como clave en el lado del servidor. Para evitar esto y convertir la clave pública de 
cadena en rsa clave pública, necesitamos escribir server_public_key = RSA.importKey(getpbk) , aquí 
getpbk es la clave pública del cliente.
• (SERVIDOR) El siguiente paso es crear una clave de sesión. Aquí, he usado el módulo "os" 
para crear una clave aleatoria "key = os.urandom (16)" que nos dará una clave de 16 bits y 
después de eso he cifrado esa clave en "AES.MODE_CTR" y la hash de nuevo conSHA-1:
    967/1068
    903
#encrypting session key and public key 
E = server_public_key.encrypt(encrypto,16)
en = eval(msg)
decrypt = key.decrypt(en) 
# hashing sha1
en_object = hashlib.sha1(decrypt) en_digest = en_object.hexdigest()
Así que el en_digest será nuestra clave de sesión.
• (SERVIDOR) Para la parte final del proceso de protocolo de enlace es cifrar la clave pública 
obtenida del cliente y la clave de sesión creada en el lado del servidor.
Después del cifrado, el servidor enviará la clave al cliente como una cadena.
• (CLIENTE) Después de obtener la cadena cifrada (pública y clave de sesión) del servidor, el 
cliente los descifra usando la clave privada que se creó anteriormente junto con la clave 
pública. Como el cifrado (público y clave de sesión) estaba en forma de cadena, ahora 
debemos recuperarlo como clave mediante el uso de eval (). Si se realiza el descifrado, el 
proceso de intercambio se completa también, ya que ambas partes confirman que están 
utilizando las mismas claves. Para descifrar:
He usado el SHA-1 aquí para que sea legible en la salida.
Proceso de comunicación:
Para el proceso de comunicación, tenemos que usar la clave de sesión de ambos lados como la 
CLAVE para el cifrado IDEA MODE_CTR. Ambos lados cifrarán y descifrarán mensajes con 
IDEA.MODE_CTR usando la clave de sesión.
• (Cifrado) Para el cifrado IDEA, necesitamos una clave de 16 bits de tamaño y contador, 
como debe ser reclamable. El contador es obligatorio en MODE_CTR. La clave de la sesión 
que ciframos y hash tiene ahora un tamaño de 40 que excederá la clave límite del cifrado 
IDEA. Por lo tanto, necesitamos reducir el tamaño de la clave de sesión. Para reducir, 
podemos usar la función normal python integrada en la cadena de función [valor: valor]. 
Donde el valor puede ser cualquier valor según la elección del usuario. En nuestro caso, he 
hecho "clave [: 16]" donde tomará de 0 a 16 valores de la clave. Esta conversión se puede 
hacer de muchas maneras, como la clave [1:17] o la clave [16:]. La siguiente parte es crear 
una nueva función de cifrado de IDEA escribiendo IDEA.new () que tomará 3 argumentos 
para su procesamiento. El primer argumento será CLAVE, el segundo será el modo del 
cifrado de IDEA (en nuestro caso, IDEA.MODE_CTR) y el tercer argumento será el contador
= que es una función que se debe llamar. El contador = mantendrá un tamaño de cadena
#encrypt CTR MODE session key
en = AES.new(key_128,AES.MODE_CTR,counter = lambda:key_128) encrypto = 
en.encrypt(key_128)
#hashing sha1
en_object = hashlib.sha1(encrypto) 
en_digest = en_object.hexdigest()
    968/1068
    904
ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
eMsg = ideaEncrypt.encrypt(whole)
#convertingthe encryptedmessage to HEXADECIMALtoreadable eMsg= 
eMsg.encode("hex").upper()
decoded = newmess.decode("hex")
ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key) 
dMsg = ideaDecrypt.decrypt(decoded)
import socket 
import hashlib 
import os 
import time
import itertools 
import threading 
import sys
import Crypto.Cipher.AES as AES 
from Crypto.PublicKey import RSA
que será devuelto por la función. Para definir el contador =, debemos tener que usar unos 
valores razonables. En este caso, he usado el tamaño de la CLAVE definiendo lambda. En 
lugar de usar lambda, podríamos usar Counter.Util que genera un valor aleatorio para 
counter =. Para usar Counter.Util, necesitamos importar el módulo de contador desde 
crypto. Por lo tanto, el código será:
Una vez que definimos el "IdeaEncrypt" como nuestra variable de cifrado IDEA, podemos usar la 
función integrada de cifrado para cifrar cualquier mensaje.
En este segmento de código, entero es el mensaje que se va a cifrar y eMsg es el mensaje 
cifrado. Después de cifrar el mensaje, lo he convertido en HEXADECIMAL para que sea legible y 
upper () es la función incorporada para hacer que los caracteres estén en mayúsculas. Después 
de eso, este mensaje cifrado se enviará a la estación opuesta para su descifrado.
• (Descifrado)
Para descifrar los mensajes cifrados, necesitaremos crear otra variable de cifrado utilizando los 
mismos argumentos y la misma clave, pero esta vez la variable descifrará los mensajes cifrados. 
El código para este mismo que la última vez. Sin embargo, antes de descifrar los mensajes, 
necesitamos decodificar el mensaje de hexadecimal porque en nuestra parte de cifrado, 
codificamos el mensaje cifrado en hexadecimal para que sea legible. Por lo tanto, todo el código 
será:
Estos procesos se realizarán tanto en el servidor como en el lado del cliente para el cifrado y 
descifrado.
Examples
Implementación del lado del servidor
    969/1068
    905
from CryptoPlus.Cipher import IDEA
#server address and port number input from admin 
host= raw_input("Server Address - > ")
port = int(input("Port - > ")) 
#boolean for checking server and port 
check = False
done = False
def animate():
for c in itertools.cycle(['....','.......','..........','................. ']):
if done:
break
sys.stdout.write('\rCHECKING IP ADDRESS AND NOT USED PORT '+c) 
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\r-----SERVERSTARTED.WAITINGFORCLIENT -----\n')
try:
#setting up socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
server.bind((host,port))
server.listen(5) 
check = True
except BaseException:
print "-----Check Server Address or Port ------"
check = False
if check is True: 
# server Quit
shutdown = False
# printing "Server Started Message" 
thread_load = threading.Thread(target=animate) 
thread_load.start()
time.sleep(4) 
done = True
#binding client and address 
client,address = server.accept()
print ("CLIENT IS CONNECTED. CLIENT'S ADDRESS ->",address)
print ("\n-----WAITING FOR PUBLIC KEY & PUBLIC KEY HASH--------\n")
#client's message(Public Key) 
getpbk = client.recv(2048)
#conversion of string to KEY 
server_public_key = RSA.importKey(getpbk)
#hashing the public key in server side for validating the hash from client 
hash_object = hashlib.sha1(getpbk)
hex_digest = hash_object.hexdigest()
if getpbk != "": 
print (getpbk)
client.send("YES") 
gethash = client.recv(1024)
print ("\n-----HASH OF PUBLIC KEY --------\n"+gethash)
if hex_digest == gethash: 
# creating session key
key_128 = os.urandom(16) 
#encrypt CTR MODE session key
en = AES.new(key_128,AES.MODE_CTR,counter = lambda:key_128)
    970/1068
    906
import time 
import socket 
import threading 
import hashlib 
import itertools 
import sys
from Crypto import Random
from Crypto.PublicKey import RSA 
from CryptoPlus.Cipher import IDEA
#animating loading 
done = False
def animate():
for c in itertools.cycle(['....','.......','..........','................. ']):
if done:
break
sys.stdout.write('\rCONFIRMING CONNECTION TO SERVER '+c) 
sys.stdout.flush()
time.sleep(0.1)
Implementación del lado del cliente
encrypto = en.encrypt(key_128) 
#hashing sha1
en_object = hashlib.sha1(encrypto) 
en_digest = en_object.hexdigest()
print ("\n-----SESSION KEY ----- \n"+en_digest)
#encrypting session key and public key 
E =server_public_key.encrypt(encrypto,16)
print ("\n-----ENCRYPTED PUBLIC KEY AND SESSION KEY ------ \n"+str(E))
print("\n-----HANDSHAKECOMPLETE ----- ")
client.send(str(E)) 
while True:
#message from client 
newmess = client.recv(1024)
#decoding the message from HEXADECIMAL to decrypt the ecrypted version of the message
only
decoded = newmess.decode("hex")
#making en_digest(session_key) as the key 
key = en_digest[:16]
print ("\nENCRYPTED MESSAGE FROM CLIENT -> "+newmess)
#decrypting message from the client
ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key) 
dMsg = ideaDecrypt.decrypt(decoded)
print ("\n**New Message** "+time.ctime(time.time()) +" > "+dMsg+"\n") 
mess = raw_input("\nMessage To Client -> ")
if mess != "":
ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key) 
eMsg = ideaEncrypt.encrypt(mess)
eMsg = eMsg.encode("hex").upper() 
if eMsg != "":
print ("ENCRYPTED MESSAGE TO CLIENT-> " + eMsg)
client.send(eMsg) 
client.close()
else:
print ("\n-----PUBLIC KEY HASH DOESNOT MATCH ------ \n")
    971/1068
    907
#public key and private key 
random_generator = Random.new().read
key =RSA.generate(1024,random_generator) 
public = key.publickey().exportKey() 
private = key.exportKey()
#hashing the public key 
hash_object = hashlib.sha1(public) 
hex_digest = hash_object.hexdigest()
#Setting up socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#host and port input user
host = raw_input("Server Address To Be Connected -> ") 
port = int(input("Port of The Server -> "))
#binding the address and port 
server.connect((host, port))
# printing "Server Started Message" 
thread_load = threading.Thread(target=animate) 
thread_load.start()
time.sleep(4) 
done = True
def send(t,name,key):
mess = raw_input(name + " : ") 
key = key[:16]
#merging the message and the name 
whole = name+" : "+mess
ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key) 
eMsg = ideaEncrypt.encrypt(whole)
#converting the encrypted message to HEXADECIMAL to readable 
eMsg = eMsg.encode("hex").upper()
if eMsg != "":
print ("ENCRYPTED MESSAGE TO SERVER-> "+eMsg)
server.send(eMsg) 
def recv(t,key):
newmess = server.recv(1024)
print ("\nENCRYPTED MESSAGE FROM SERVER-> " + newmess)
key = key[:16]
decoded = newmess.decode("hex")
ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key) 
dMsg = ideaDecrypt.decrypt(decoded)
print ("\n**New MessageFrom Server** " + time.ctime(time.time()) + " : " + dMsg + "\n")
while True:
server.send(public) 
confirm = server.recv(1024) 
if confirm == "YES":
server.send(hex_digest)
#connected msg
msg = server.recv(1024) 
en = eval(msg)
decrypt = key.decrypt(en) 
# hashing sha1
en_object = hashlib.sha1(decrypt) 
en_digest = en_object.hexdigest()
print("\n-----ENCRYPTEDPUBLIC KEY AND SESSION KEY FROM SERVER-------")
    972/1068
    908
print (msg)
print ("\n-----DECRYPTEDSESSION KEY-------")
print (en_digest)
print("\n-----HANDSHAKECOMPLETE-------\n")
alais = raw_input("\nYour Name -> ")
while True:
thread_send = threading.Thread(target=send,args=("------Sending Message------
",alais,en_digest))
thread_recv = threading.Thread(target=recv,args=("------Recieving Message------
",en_digest))
thread_send.start() 
thread_recv.start()
thread_send.join() 
thread_recv.join() 
time.sleep(0.5)
time.sleep(60) 
server.close()
    973/1068
    909
usage: sub <command> 
commands:
status - showstatus 
list - print list
"""
usage: sub <command> 
commands:
status - showstatus 
list - print list
"""
import sys 
def check():
print("status") 
return 0
if sys.argv[1:] == ['status']: 
sys.exit(check())
elif sys.argv[1:] == ['list']: 
print("list")
else:
print( doc .strip())
Capítulo 187: Subcomandos CLI con salida 
de ayuda precisa
Introducción
Diferentes formas de crear subcomandos como en hg o svn con la interfaz de línea de comandos 
exacta y la salida de ayuda, como se muestra en la sección Comentarios.
Análisis de los argumentos de la línea de comandos cubre un tema más amplio de análisis de 
argumentos.
Observaciones
Diferentes formas de crear subcomandos como en hg o svn con la interfaz de línea de comandos 
que se muestra en el mensaje de ayuda:
Examples
Forma nativa (sin bibliotecas)
    974/1068
    910
usage: sub <command> 
commands:
status - showstatus 
list - print list
import argparse 
import sys
def check():
print("status") 
return 0
parser = argparse.ArgumentParser(prog="sub", add_help=False) 
subparser = parser.add_subparsers(dest="cmd")
subparser.add_parser('status', help='show status') 
subparser.add_parser('list', help='print list')
# hack to show help when no arguments supplied 
if len(sys.argv) == 1:
parser.print_help() 
sys.exit(0)
args = parser.parse_args() 
if args.cmd == 'list':
print('list')
elif args.cmd == 'status': 
sys.exit(check())
usage: sub {status,list} ...
positional arguments:
{status,list}
status show status
list print list
Salida sin argumentos:
Pros:
• no deps
• todo el mundo debería ser capaz de leer eso
• Control completo sobre el formato de ayuda.
argparse (formateador de ayuda predeterminado)
Salida sin argumentos:
Pros:
• viene con Python
• Opción de análisis está incluido
    975/1068
    911
argparse (formateador de ayuda personalizado)
Versión extendida de http://www.levcode.com/python/example/25282/argparse--default-helpformatter- que solucionó la salida de ayuda.
import argparse 
import sys
class CustomHelpFormatter(argparse.HelpFormatter): 
def _format_action(self, action):
if type(action) == argparse._SubParsersAction:
# inject newclass variable forsubcommand formatting 
subactions = action._get_subactions()
invocations = [self._format_action_invocation(a) for a in subactions] 
self._subcommand_max_length = max(len(i) for i in invocations)
if type(action) == argparse._SubParsersAction._ChoicesPseudoAction: 
# format subcommand help line
subcommand = self._format_action_invocation(action) # type: str 
width = self._subcommand_max_length
help_text = "" 
if action.help:
help_text = self._expand_help(action)
return " {:{width}} - {}\n".format(subcommand, help_text, width=width)
elif type(action) == argparse._SubParsersAction: 
# process subcommand help section
msg = '\n'
for subaction in action._get_subactions(): 
msg += self._format_action(subaction)
return msg 
else:
return super(CustomHelpFormatter, self)._format_action(action)
def check():
print("status") 
return 0
parser = argparse.ArgumentParser(usage="sub <command>", add_help=False, 
formatter_class=CustomHelpFormatter)
subparser = parser.add_subparsers(dest="cmd") 
subparser.add_parser('status', help='show status') 
subparser.add_parser('list', help='print list')
# custom help messge 
parser._positionals.title = "commands"
# hack to show help when no arguments supplied 
if len(sys.argv) == 1:
parser.print_help() 
sys.exit(0)
args = parser.parse_args() 
if args.cmd == 'list':
print('list')
elif args.cmd == 'status':
    976/1068
    912
usage: sub <command> 
commands:
status - showstatus 
list - print list
Salida sin argumentos:
sys.exit(check())
    977/1068
    913
import sys
from sys import exit
raise RuntimeError("expected 3 command line arguments")
f = open(sys.argv[1], 'rb') # Use first command line argument. 
start_line = int(sys.argv[2]) # All arguments come as strings,so need to be
end_line = int(sys.argv[3]) # converted explicitly if other types are required.
if len(sys.argv) != 4: # The script name needs to be accounted for as well.
# The name of the executed script is at the beginning of the argv list. 
print('usage:', sys.argv[0], '<filename> <start> <end>')
Capítulo 188: sys
Introducción
El módulo sys proporciona acceso a funciones y valores relacionados con el entorno de ejecución 
del programa, como los parámetros de la línea de comando en sys.argv o la función sys.exit() 
para finalizar el proceso actual desde cualquier punto del flujo del programa.
Aunque está bien separado en un módulo, en realidad está incorporado y, como tal, siempre 
estará disponible en circunstancias normales.
Sintaxis
• Importe el módulo sys y haga que esté disponible en el espacio de nombres actual:
• Importe una función específica del módulo sys directamente al espacio de nombres actual:
Observaciones
Para obtener detalles sobre todos los miembros del módulo sys , consulte la documentación
oficial .
Examples
Argumentos de línea de comando
Tenga en cuenta que en programas más grandes y más pulidos, usaría módulos como hacer clic
para manejar los argumentos de la línea de comandos en lugar de hacerlo usted mismo.
Nombre del script
    978/1068
    914
# Error messages should not go to standard output, if possible. 
print('ERROR: We have no cheese at all.', file=sys.stderr)
try:
f = open('nonexistent-file.xyz', 'rb') 
except OSError as e:
print(e, file=sys.stderr)
process_data()
sys.exit(1) # use an exit code to signal the program was unsuccessful
def main():
if len(sys.argv) != 4 or '--help' in sys.argv[1:]:
print('usage: my_program <arg1> <arg2> <arg3>',file=sys.stderr)
Flujo de error estándar
Finalización prematura del proceso y devolución de un código de salida.
# You can use it to generate the path prefix of the executed program
# (as opposed to the current module) to access files relative to that, 
# which would be good for assets of a game, for instance. 
program_file = sys.argv[0]
import pathlib
program_path = pathlib.Path(program_file).resolve().parent
    979/1068
    915
import tempfile
with tempfile.NamedTemporaryFile(delete=False) as t: 
t.write('Hello World!')
path = t.name 
print path
with open(path) as t: 
print t.read()
/tmp/tmp6pireJ 
Hello World!
Capítulo 189: tempfile NamedTemporaryFile
Parámetros
param descripción
modo Modo para abrir archivo, por defecto = w + b
borrar Para borrar el archivo al cierre, por defecto = Verdadero
sufijo sufijo de nombre de archivo, por defecto = ''
prefijo prefijo de nombre de archivo, por defecto = 'tmp'
dir dirname para colocar tempfile, default = None
buffsize por defecto = -1, (se usa por defecto el sistema operativo)
Examples
Cree (y escriba en) un archivo temporal persistente conocido
Puedecrear archivos temporalesque tengan unnombre visibleen el sistemade archivosal que 
se puede acceder a través de la propiedad del name .El archivo se puede configurar en sistemas 
Unix para que se elimine en el cierre (establecido por delete param, el valor predeterminado es 
True) o se puede volver a abrir mástarde.
Lo siguiente creará y abrirá un archivo temporal nombrado y escribirá '¡Hola mundo!' a ese 
archivo. Se puede acceder a la path de archivo del archivo temporal a través del name , en este 
ejemplo, se guarda en la path variable y se imprime para el usuario. El archivo se vuelve a abrir 
después de cerrar el archivo y el contenido del archivo temporal se lee e imprime para el usuario.
Salida:
    980/1068
    916
    981/1068
    917
import typing
T = typing.TypeVar("T")
def get_first_element(l: typing.Sequence[T]) -> T: 
"""Gets the first element of a sequence.""" 
return l[0]
def two_sum(a, b): 
return a + b
Capítulo 190: Tipo de sugerencias
Sintaxis
• typing.Callable [[int, str], None] -> def func (a: int, b: str) -> None
• escribiendo.Mapping [str, int] -> {"a": 1, "b": 2, "c": 3}
• escribiendo.Lista [int] -> [1, 2, 3]
• escribiendo.configurar [int] -> {1, 2, 3}
• escribiendo.Opcional [int] -> Ninguno o int
• escribiendo.Secuencia [int] -> [1, 2, 3] o (1, 2, 3)
• escribiendo.cualquier -> cualquier tipo
• escribiendo.Union [int, str] -> 1 o "1"
• T = escribiendo.TypeVar ('T') -> Tipo genérico
Observaciones
La sugerencia de tipo, tal como se especifica en PEP 484 , es una solución formalizada para indicar 
de forma estática el tipo de valor para el Código Python. Al aparecer junto al módulo de typing , 
las sugerencias de tipo ofrecen a los usuarios de Python la capacidad de anotar su código, 
ayudando así a los verificadores de tipos, mientras que, de forma indirecta, documentan su 
código con más información.
Examples
Tipos genéricos
El typing.TypeVar es una fábrica de tipo genérico. Su objetivo principal es servir como parámetro / 
marcador de posición para las anotaciones genéricas de función / clase / método:
Añadiendo tipos a una función
Tomemos un ejemplo de una función que recibe dos argumentos y devuelve un valor que indica 
su suma:
    982/1068
    918
print(two_sum(2, 1)) # result: 3
print(two_sum("a", "b")) # result: "ab"
def two_sum(a: int, b: int): 
return a + b
def two_sum(a: str, b: str): 
return a + b
def two_sum(a: int, b: int) -> int: 
return a + b
two_sum. annotations
Al observar este código, uno no puede indicar de forma segura y sin duda el tipo de argumentos 
para la función two_sum . Funciona tanto cuando se suministra con valores int :
y con cuerdas:
y con otros valores, como list s, tuple s etcétera.
Debido a esta naturaleza dinámica de los tipos de python, donde muchos son aplicables para una 
operación determinada, cualquier verificador de tipo no podría afirmar razonablemente si una 
llamada para esta función debería permitirse o no.
Para ayudar a nuestro verificador de tipos, ahora podemos proporcionarle sugerencias detipo en 
la definición de función que indica el tipo que permitimos.
Para indicar que solo queremos permitirtipos int , podemos cambiar nuestra definición de función 
para que se vea así:
Las anotaciones siguen al nombre del argumento y están separadas por un carácter : .
De forma similar, para indicar que solo se permiten los tipos str ,cambiaríamos nuestra función 
para especificarlo:
Ademásde especificarel tipo de los argumentos,también se podríaindicarel valor de retornode 
unallamada defunción.Estosehaceagregandoel carácter-> seguidodeltipodespués del 
paréntesisde cierreenlalista de argumentos pero antes de:alfinal dela declaración dela 
función:
Ahorahemos indicadoqueel valorderetornoalllamaratwo_sum debeserdetipoint .De manera 
similar, podemos definir valores apropiados para str ,float , list , set y otros.
Aunque las sugerencias de tipo son utilizadas principalmente por los verificadores de tipo y los 
IDE, a veces es posible que necesite recuperarlos. Esto se puede hacer usando el
 annotations especial annotations :
    983/1068
    919
class A:
x = None # type: float
def init (self, x: float) -> None: 
"""
self should not be annotated
init should be annotated to return None 
"""
self.x = x
@classmethod
def from_int(cls, x: int) -> 'A': 
"""
cls should not be annotated
Use forward reference to refer to current class with string literal 'A' 
"""
return cls(float(x))
x = 3 # type: int 
x = negate(x)
x = 'a type-checker might catch this error'
x: int = 3
y: int
class Foo:
x: int
y: str = 'abc'
Miembros de la clase y métodos
La referencia hacia adelante de la clase actual es necesaria ya que las anotaciones se evalúan 
cuando se define la función. Las referencias directas también se pueden usar cuando se hace 
referencia a una clase que causaría una importación circular si se importara.
Variables y atributos
Las variables son anotadas usando comentarios:
Python 3.x 3.6
A partir de Python 3.6, también hay una nueva sintaxis para las anotaciones de variables . El 
código de arriba podría usar el formulario
A diferencia de los comentarios, también es posible simplemente agregar una sugerencia de tipo 
a una variable que no se declaró anteriormente, sin establecer un valor para ella:
Además, si se utilizan en el módulo o en el nivel de clase, las sugerencias de tipo se pueden 
recuperar utilizando typing.get_type_hints(class_or_module) :
# {'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>}
    984/1068
    920
x: int
print( annotations ) 
# {'x': <class 'int'>}
class C:
s: str
print(C. annotations ) 
# {'s': <class 'str'>}
import typing
Point = typing.NamedTuple('Point', [('x', int), ('y', int)])
def hello_world(greeting: str = 'Hello'): 
print(greeting + 'world!')
Alternativamente, se puede acceder a ellos usando el atributo o variable especial annotations :
NamedTuple
La creación de una doble con nombre con sugerencias de tipo se realiza utilizando la función 
NamedTuple del módulo de typing :
Tenga en cuenta que el nombre del tipo resultante es el primer argumento de la función, pero 
debe asignarse a una variable con el mismo nombre para facilitar el trabajo de los verificadores 
de tipos.
Escriba sugerencias para argumentos de palabras clave
Tenga en cuenta los espacios alrededor del signo igual en contraposición a la forma en que se 
suelen diseñar los argumentos de palabras clave.
print(typing.get_type_hints(Foo))
# ChainMap({'x': <class 'int'>, 'y': <class 'str'>}, {})
    985/1068
    921
float_num = 10.2 #float value 
complex_num = 3.14j #complex value
long_num = 1234567L #long value
int_num = 10 #int value
a_str = 'Hello World'
print(a_str) #output will be whole string. Hello World 
print(a_str[0]) #output will be first character. H 
print(a_str[0:5]) #output will be first five characters. Hello
print(list) #will ouput whole list. [123,'abcd',10.2,'d']
print(list[0:2]) #will output first two element of list. [123,'abcd'] print(list1
* 2) #will gave list1 two times. ['hello','world','hello','world']
print(list + list1) #willgaveconcatenationofboththelists. 
[123,'abcd',10.2,'d','hello','world']
list = [123,'abcd',10.2,'d'] #can be a array of any data type or single data type.
list1 = ['hello','world']
Capítulo 191: Tipos de datos de Python
Introducción
Los tipos de datos no son más que variables que utilizaste para reservar algo de espacio en la 
memoria. Las variables de Python no necesitan una declaración explícita para reservar espacio 
de memoria. La declaración ocurre automáticamente cuando asignas un valor a una variable.
Examples
Tipo de datos numeros
Los números tienen cuatro tipos en Python. Int, flotador, complejo, y largo.
Tipo de datos de cadena
Las cadenas se identifican como un conjunto contiguo de caracteres representados en las 
comillas. Python permite pares de comillas simples o dobles. Las cadenas son tipos de datos de 
secuencia inmutables, es decir, cada vez que se realizan cambios en una cadena, se crea un 
objeto de cadena completamente nuevo.
Tipo de datos de lista
Una lista contiene elementos separados por comas y encerrados entre corchetes []. Las listas son 
casi similares a las matrices en C. Una diferencia es que todos los elementos que pertenecen a 
una lista pueden ser de diferentes tipos de datos.
Tipo de datos de la tupla
    986/1068
    922
tuple = (123,'hello') 
tuple1 = ('world')
print(tuple) #will output whole tuple. (123,'hello') 
print(tuple[0]) #will output first value. (123) 
print(tuple + tuple1)#will output (123,'hello','world') 
tuple[1]='update' #this will give you error.
print(dic['name']) #will output only value with 'name' key. 'red' 
print(dic.values()) #will output list of values in dic. ['red',10] 
print(dic.keys()) #will output list of keys. ['name','age']
print(dic) #will output all the key-value pairs. {'name':'red','age':10}
dic={'name':'red','age':10}
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} 
print(basket) # duplicates will beremoved
> {'orange', 'banana', 'pear', 'apple'} 
a = set('abracadabra')
print(a) # unique letters in a
> {'a', 'r', 'b', 'c', 'd'}
a.add('z') 
print(a)
> {'a', 'c', 'r', 'b', 'z', 'd'}
b = frozenset('asdfagsa') 
print(b)
> frozenset({'f', 'g', 'd', 'a', 's'})
cities = frozenset(["Frankfurt", "Basel","Freiburg"]) 
print(cities)
> frozenset({'Frankfurt', 'Basel', 'Freiburg'})
Las listas están entre paréntesis [] y sus elementos y tamaño pueden cambiarse, mientras que las 
tuplas están entre paréntesis () y no se pueden actualizar. Las tuplas son inmutables.
Tipo de datos del diccionario
El diccionario consta de pares clave-valor. Está encerrado entre llaves {} y los valores se pueden 
asignar y acceder mediante corchetes [].
Establecer tipos de datos
Los conjuntos son colecciones desordenadas de objetos únicos, hay dos tipos de conjuntos:
1. Conjuntos: son mutables y se pueden agregar nuevos elementos una vez que se definen los 
conjuntos
2. Conjuntos congelados: son inmutables y no se pueden agregar nuevos elementos después 
de su definición.
    987/1068
    923
foo = "bar"
foo[0] = "c" # Error
foo = ("bar", 1, "Hello!",) 
foo[1] = 2 # ERROR!!
foo = frozenset(["bar", 1, "Hello!"]) 
foo[2] = 7 #ERROR
foo.add(3) # ERROR
Capítulo 192: Tipos de datos inmutables (int, 
float, str, tuple y frozensets)
Examples
Los caracteres individuales de las cadenas no son asignables
El valor de la variable inmutable no se puede cambiar una vez que se crean.
Los miembros individuales de Tuple no son asignables
La segunda línea devolvería un error ya que los miembros de la tupla una vez creados no son 
asignables. Debido a la inmutabilidad de la tupla.
Los Frozenset son inmutables y no asignables.
La segunda línea devolvería un error ya que los miembros de frozenset una vez creados no son
asignables. La tercera línea devolvería el error, ya que los frozensets no admiten funciones que 
puedan manipular a los miembros.
    988/1068
    924
from Tkinter import * # Capitalized
from tkinter import * # Lowercase
try:
from Tkinter import * 
except ImportError:
from tkinter import *
from sys import version_info 
if version_info.major == 2:
from Tkinter import * 
elif version_info.major == 3:
from tkinter import *
Capítulo 193: tkinter
Introducción
Lanzado en Tkinter es la biblioteca GUI (interfaz gráfica de usuario) más popular de Python. Este 
tema explica el uso adecuado de esta biblioteca y sus características.
Observaciones
La capitalización del módulo tkinter es diferente entre Python 2 y 3. Para Python 2 use lo 
siguiente:
Para Python 3 usa lo siguiente:
Para el código que funciona con Python 2 y 3, puede hacer
o
Ver la Documentación tkinter para más detalles.
Examples
Una aplicación tkinter mínima
tkinter es un kit de herramientas de GUI que proporciona un envoltorio alrededor de la biblioteca 
de GUI de Tk / Tcl y se incluye con Python. El siguiente código crea una nueva ventana usando 
tkinter y coloca algún texto en el cuerpo de la ventana.
Nota: En Python 2, el uso de mayúsculas puede ser ligeramente diferente, consulte la 
sección de Comentarios a continuación.
    989/1068
    925
Gerentes de geometría
Tkinter tiene tres mecanismos para la gestión de la geometría: place , pack y grid . 
El place gestor utiliza coordenadas absolutas de píxeles.
El gestor de pack coloca los widgets en uno de los 4 lados. Los nuevos widgets se colocan al lado 
de los widgets existentes.
El administrador de grid coloca los widgets en una cuadrícula similar a una hoja de cálculo de 
cambio de tamaño dinámico.
Lugar
Los argumentos de palabras clave más comunes para widget.place son los siguientes:
• x , la coordenada x absoluta del widget
• y , la coordenada y absoluta del widget
• height , la altura absoluta delwidget
• width ,elanchoabsoluto del widget 
Un ejemplo de código usando place :
class PlaceExample(Frame): 
def init (self,master):
Frame. init(self,master) 
self.grid()
top_text=Label(master,text="This is on top at the origin")
import tkinter as tk
# GUI window is a subclass of the basic tkinter Frame object 
class HelloWorldFrame(tk.Frame):
def init (self, master):
# Call superclass constructor 
tk.Frame. init (self, master) 
# Place frame into main window 
self.grid()
# Create text box with "Hello World" text
hello = tk.Label(self, text="Hello World! This label can hold strings!") 
# Place text box into frame
hello.grid(row=0, column=0)
# Spawn window
if name == " main ":
# Create main window object 
root = tk.Tk()
# Set title of window 
root.title("Hello World!")
# Instantiate HelloWorldFrame object 
hello_frame = HelloWorldFrame(root) 
# Start GUI
hello_frame.mainloop()
    990/1068
    926
from tkinter import *
class GridExample(Frame): 
def init (self,master):
Frame. init(self,master) 
self.grid()
top_text=Label(self,text="This text appears on top left") 
top_text.grid() # Default position 0, 0 
bottom_text=Label(self,text="This text appears on bottom left") 
bottom_text.grid() # Default position 1, 0
right_text=Label(self,text="This text appears on the right and spans both rows", 
wraplength=100)
# Position is 0,1
Paquete
widget.pack puede tomar los siguientes argumentos de palabras clave:
• expand , ya sea para llenar o no el espacio dejado por elpadre
• fill,sideseaexpandirparallenartodoelespacio(NINGUNO(predeterminado),X,Yo 
AMBOS)
• side , el lado contra el que empacar (TOP (predeterminado), ABAJO, IZQUIERDO o 
DERECHO)
Cuadrícula
Los argumentos de palabras clave más utilizados de widget.grid son los siguientes:
• row , la fila del widget (por defecto el más pequeño desocupado)
• rowspan , el número de columnas que un widget abarca (valor predeterminado 1)
• column , la columna del widget (por defecto 0)
• columnspan , el número de columnas que abarca un widget (por defecto1)
• sticky , dónde colocar el widget si la celda de la cuadrícula es más grande que él 
(combinación de N, NE, E, SE, S, SW, W, NW)
Las filas y columnas están indexadas a cero. Las filas aumentan bajando y las columnas 
aumentan yendo a la derecha.
Un ejemplo de código usando grid :
#top_text.pack() 
top_text.place(x=0,y=0,height=50,width=200)
bottom_right_text=Label(master,text="This is at position 200,400") 
#top_text.pack() 
bottom_right_text.place(x=200,y=400,height=50,width=200)
# Spawn Window
if name ==" main ": 
root=Tk()
place_frame=PlaceExample(root) 
place_frame.mainloop()
    991/1068
    927
¡Nunca mezcle el pack y la griddentro del mismo marco! ¡Al hacerlo se producirá un 
interbloqueo en la aplicación!
# Rowspan means actual position is [0-1],1 
right_text.grid(row=0,column=1,rowspan=2)
# Spawn Window
if name ==" main ": 
root=Tk() 
grid_frame=GridExample(root) 
grid_frame.mainloop()
    992/1068
    928
Capítulo 194: Trabajando alrededor del 
bloqueo global de intérpretes (GIL)
Observaciones
¿Por qué hay un GIL?
El GIL ha existido en CPython desde el inicio de los hilos de Python, en 1992. Está diseñado para 
garantizar la seguridad de los hilos al ejecutar el código de Python. Los intérpretes de Python 
escritos con un GIL impiden que varios subprocesos nativos ejecuten códigos de byte de Python 
a la vez. Esto facilita que los complementos se aseguren de que su código sea seguro para 
subprocesos: simplemente bloquee la GIL, y solo su subproceso activo puede ejecutarse, por lo 
que su código es automáticamente seguro para subprocesos.
Versión corta: la GIL garantiza que no importa cuántos procesadores y subprocesos tenga, solo 
se ejecutará un subproceso de un intérprete de Python al mismo tiempo.
Esto tiene muchos beneficios de facilidad de uso, pero también tiene muchos beneficios 
negativos.
Tenga en cuenta que un GIL no es un requisito del lenguaje Python. Por consiguiente, no puede 
acceder a la GIL directamente desde el código estándar de Python. No todas las 
implementaciones de Python utilizan un GIL.
Intérpretes que tienen un GIL: CPython, PyPy, Cython (pero puede desactivar el GIL con nogil )
Intérpretes que no tienen un GIL: Jython, IronPython
Detalles sobre cómo funciona el GIL:
Cuando se está ejecutando un hilo, bloquea la GIL. Cuando un hilo quiere ejecutarse, solicita el 
GIL y espera hasta que esté disponible. En CPython, antes de la versión 3.2, el hilo en ejecución 
verificaba después de un cierto número de instrucciones de Python para ver si otro código quería 
el bloqueo (es decir, liberó el bloqueo y luego lo solicitó nuevamente). Este método tendía a 
provocar la hambruna de hilos, en gran parte porque el hilo que liberaba el bloqueo lo volvería a 
adquirir antes de que los hilos en espera tuvieran la oportunidad de despertarse. Desde la versión 
3.2, los subprocesos que desean que el GIL espere el bloqueo por algún tiempo, y después de 
ese tiempo, establecen una variable compartida que obliga al hilo en ejecución a ceder. Sin 
embargo, esto todavía puede resultar en tiempos de ejecución drásticamente más largos.
Consulte los siguientes enlaces en dabeaz.com (en la sección de referencias) para obtener más 
detalles.
CPython libera automáticamente la GIL cuando un hilo realiza una operación de E / S. Las
    993/1068
    929
bibliotecas de procesamiento de imágenes y las operaciones de procesamiento de números 
numpy liberan la GIL antes de realizar su procesamiento.
Beneficios de la GIL
Para los intérpretes que usan la GIL, la GIL es sistémica. Se utiliza para preservar el estado de la 
aplicación. Beneficios incluidos:
• Recolección de basura: los recuentos de referencia seguros para subprocesos deben 
modificarse mientras la GIL está bloqueada. En CPython, toda la colección de garbarge está 
vinculada a la GIL. Este es un grande; vea el artículo de la wiki de python.org sobre la GIL 
(que se encuentra en las Referencias, a continuación) para obtener detalles sobre lo que 
aún debe ser funcional si se desea eliminar la GIL.
• Facilidad para los programadores que tratan con GIL: bloquear todo es simplista, pero fácil 
de codificar
• Facilita la importación de módulos desde otros idiomas.
Consecuencias de la GIL
La GIL solo permite que un hilo ejecute el código de Python a la vez dentro del intérprete de 
python. Esto significa que el multihilo de procesos que ejecutan código de Python estricto 
simplemente no funciona. Al usar subprocesos contra GIL, es probable que tenga un peor 
rendimiento con los subprocesos que si se ejecutara en un solo subproceso.
Referencias:
https://wiki.python.org/moin/GlobalInterpreterLock - resumen rápido de lo que hace, detalles finos 
sobre todos los beneficios
http://programmers.stackexchange.com/questions/186889/why-was-python-written-with-the-gil -
resumen claramente escrito
http://www.dabeaz.com/python/UnderstandingGIL.pdf : cómo funciona GIL y por qué se ralentiza 
en varios núcleos
http://www.dabeaz.com/GIL/gilvis/index.html : visualización de los datos que muestran cómo GIL 
bloquea los subprocesos
http://jeffknupp.com/blog/2012/03/31/pythons-hardest-problem/ - fácil de entender la historia del 
problema GIL
https://jeffknupp.com/blog/2013/06/30/pythons-hardest-problem-revisited/ - detalles sobre las 
formas de solucionar las limitaciones de la GIL
    994/1068
    930
from threading import Thread 
import time
def countdown(n): 
while n > 0:
n -= 1
COUNT = 10000000
t1 = Thread(target=countdown,args=(COUNT/2,)) 
t2 = Thread(target=countdown,args=(COUNT/2,)) 
start = time.time()
t1.start();t2.start()
t1.join();t2.join() 
end = time.time() 
print end-start
import multiprocessing 
import time
def countdown(n): 
while n > 0:
n -= 1
COUNT = 10000000
start = time.time()
with multiprocessing.Pool as pool: 
pool.map(countdown, [COUNT/2, COUNT/2])
pool.close() 
pool.join()
end = time.time() 
print(end-start)
Examples
Multiprocesamiento.Pool
La respuesta simple, cuando se pregunta cómo usar hilos en Python es: "No. Utilice procesos, en 
su lugar". El módulo de multiprocesamiento le permite crear procesos con una sintaxis similar a la 
creación de subprocesos, pero prefiero usar su conveniente objeto Pool.
Usando el código que David Beazley utilizó por primera vez para mostrar los peligros de los hilos
en contra de la GIL , lo reescribiremos usando multiprocesamiento .
Código de David Beazley que mostraba 
problemas de subprocesos de GIL
Reescrita utilizando multiproceso.
En lugar de crear hilos, esto crea nuevos procesos. Dado que cada proceso es su propio
    995/1068
    931
from threading import Thread 
import time
def countdown(n): 
while n > 0:
n -= 1
COUNT = 10000000
t1 = Thread(target=countdown,args=(COUNT/2,)) 
t2 = Thread(target=countdown,args=(COUNT/2,)) 
start = time.time()
t1.start();t2.start()
t1.join();t2.join() 
end = time.time() 
print end-start
from threading import Thread 
import time
def countdown(n): 
while n > 0:
n -= 1
COUNT = 10000000
intérprete, no hay colisiones de GIL. multiprocessing.Pool abrirá tantos procesos como núcleos 
haya en la máquina, aunque en el ejemplo anterior solo necesitaría dos. En un escenario del 
mundo real, desea diseñar su lista para que tenga al menos la misma longitud que procesadores 
en su máquina. El Pool ejecutará la función que le indica que ejecute con cada argumento, hasta 
el número de procesos que cree. Cuando la función finalice, cualquier función restante en la lista 
se ejecutará en ese proceso.
Descubrí que, incluso utilizando la instrucción with , si no cierra y se une al grupo, los procesos 
continúan existiendo. Para limpiar recursos, siempre cierro y me uno a mis piscinas.
Cython Nogil:
Cython es un intérprete alternativo de python. Utiliza el GIL, pero te permite deshabilitarlo. Ver su
documentación
Como ejemplo, usando el código que David Beazley usó por primera vez para mostrar los peligros
de los hilos contra la GIL , lo reescribiremos usando nogil:
Código de David Beazley que mostraba 
problemas de subprocesos de GIL
Reescrito usando nogil (SOLO FUNCIONA EN 
CYTHON):
    996/1068
    932
Es así de simple, siempre y cuando estés usando cython. Tenga en cuenta que la documentación 
indica que debe asegurarse de no cambiar ningún objeto de Python:
El código en el cuerpo de la declaración no debe manipular los objetos de Python de 
ninguna manera, y no debe llamar a nada que manipule los objetos de Python sin 
volver a adquirir la GIL. Cython actualmente no comprueba esto.
with nogil:
t1 = Thread(target=countdown,args=(COUNT/2,)) 
t2 = Thread(target=countdown,args=(COUNT/2,)) 
start = time.time()
t1.start();t2.start()
t1.join();t2.join()
end = time.time() 
print end-start
    997/1068
    933
import zipfile 
filename = 'zipfile.zip'
zip = zipfile.ZipFile(filename) 
print(zip)
# <zipfile.ZipFile object at 0x0000000002E51A90> 
zip.close()
with zipfile.ZipFile(filename, 'r') as z: 
print(zip)
# <zipfile.ZipFile object at 0x0000000002E51A90>
Capítulo 195: Trabajando con archivos ZIP
Sintaxis
• importar archivo zip
• clase zipfile. ZipFile ( archivo, modo = 'r', compresión = ZIP_STORED, allowZip64 = True )
Observaciones
Si intenta abrir un archivo que no es un archivo ZIP, se zipfile.BadZipFile la excepción
zipfile.BadZipFile .
En Python 2.7, este fue escrito zipfile.BadZipfile , y este nombre antiguo se conserva junto con 
el nuevo en Python 3.2+
Examples
Apertura de archivos zip
Para comenzar, importe el módulo zipfile y establezca el nombre del archivo.
Trabajar con archivos zip es muy similar a trabajar con archivos , usted crea el objeto abriendo el 
archivo zip, que le permite trabajar en él antes de cerrar el archivo nuevamente.
EnPython 2.7 y enPython 3 versiones superiores a 3.2, podemos usar el administrador de 
contexto with .Abrimos el archivo en modo "leer", y luego imprimimos una lista de nombres de 
archivos:
Examinando los contenidos de Zipfile
Hay algunas formas de inspeccionar el contenido de un archivo zip. Se puede utilizar el printdir
que acaba de obtener una variedad de información que se envía a stdout
    998/1068
    934
with zipfile.ZipFile(filename) as zip: 
zip.printdir()
with zipfile.ZipFile(filename) as zip: 
print(zip.namelist())
# Out: ['pyexpat.pyd', 'python.exe', 'python3.dll', 'python35.dll', ... etc...... ]
with zipfile.ZipFile(filename) as zip: 
info = zip.infolist() 
print(zip[0].filename) 
print(zip[0].date_time) 
print(info[0].file_size)
# Out: pyexpat.pyd
# Out: (2016, 6, 25, 22, 13, 34)
# Out: 157336
import zipfile
with zipfile.ZipFile('zipfile.zip','r') as zfile: 
zfile.extractall('path')
import zipfile 
f=open('zipfile.zip','rb') 
zfile=zipfile.ZipFile(f) 
forcontinzfile.namelist():
zfile.extract(cont,path)
#
#
Out:
File Name Modified Size
# pyexpat.pyd 2016-06-25 22:13:34 157336
# python.exe 2016-06-25 22:13:34 39576
# python3.dll 2016-06-25 22:13:34 51864
# python35.dll 2016-06-25 22:13:34 3127960
# etc.
También podemos obtener una lista de nombres de archivo con la namelist método. Aquí, 
simplemente imprimimos la lista:
En lugar de namelist de namelist , podemos llamar al método infolist , que devuelve una lista de 
objetosZipInfo,quecontieneninformaciónadicionalsobrecadaarchivo,porejemplo,unamarca 
de tiempo y el tamaño delarchivo:
Extraer el contenido del archivo zip a un directorio.
Extraer todo el contenido de un archivo zip
Si desea extraer un solo archivo, use el método de extracción, toma la lista de nombres y la ruta 
como parámetro de entrada
Creando nuevos archivos
    999/1068
    935
import zipfile 
new_arch=zipfile.ZipFile("filename.zip",mode="w")
new_arch.write('filename.txt','filename_in_archive.txt') #first parameter is filename and 
second parameter is filename in archive by default filename will taken if not provided 
new_arch.close()
str_bytes="string buffer" 
new_arch.writestr('filename_string_in_archive.txt',str_bytes) 
new_arch.close()
Para crear un nuevo archivo, abra el archivo zip con el modo de escritura.
Para agregar archivos a este archivo use el método write ().
Si desea escribir una cadena de bytes en el archivo, puede usar el método writestr ().
    1000/1068
    936
plt.plot(x, y)
plt.show()
# sine function
# Plotting tutorials in Python 
# Launching a simple plot
import numpy as np
import matplotlib.pyplot as plt
# angle varying between 0 and 2*pi 
x = np.linspace(0, 2.0*np.pi, 101)
y = np.sin(x)
Capítulo 196: Trazado con matplotlib
Introducción
Matplotlib ( https://matplotlib.org/) es una biblioteca para el trazado 2D basada en NumPy. Aquí 
hay algunos ejemplos básicos. Se pueden encontrar más ejemplos en la documentación oficial ( 
https://matplotlib.org/2.0.2/gallery.html y https://matplotlib.org/2.0.2/examples/index.html) , así 
como en http: //www.levcode.com/topic/881
Examples
Una parcela simple en Matplotlib
Este ejemplo ilustra cómo crear una curva sinusoidal simple utilizando Matplotlib
    1001/1068
    937
# Plotting tutorials in Python 
# Enhancing a plot
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2.0*np.pi, 101) 
y = np.sin(x)
# values for making ticks in x and y axis 
xnumbers = np.linspace(0, 7, 15)
ynumbers = np.linspace(-1, 1, 11)
plt.plot(x, y, color='r', label='sin') # r - red colour 
plt.xlabel("Angle in Radians") 
plt.ylabel("Magnitude")
plt.title("Plot of some trigonometric functions") 
plt.xticks(xnumbers)
plt.yticks(ynumbers) 
plt.legend() 
plt.grid()
plt.axis([0, 6.5, -1.1, 1.1]) # [xstart, xend, ystart, yend]
Agregar más características a un gráfico simple: etiquetas de eje, título, 
marcas de eje, cuadrícula y leyenda
En este ejemplo, tomamos una gráfica de curva sinusoidal y le agregamos más características; a 
saber, el título, etiquetas de eje, título, marcas de eje, cuadrícula y leyenda.
    1002/1068
    938
# Plotting tutorials in Python
# Adding Multiple plots by superimposition 
# Good for plots sharing similar x, y limits 
# Using single plot command and legend
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2.0*np.pi, 101) 
y = np.sin(x)
z = np.cos(x)
# values for making ticks in x and y axis 
xnumbers = np.linspace(0, 7, 15)
ynumbers = np.linspace(-1, 1, 11)
plt.plot(x, y, 'r', x, z, 'g') # r, g - red, green colour 
plt.xlabel("Angle in Radians") 
plt.ylabel("Magnitude")
Haciendo múltiples parcelas en la misma figura por superposición similar a 
MATLAB
En este ejemplo, una curva sinusoidal y una curva de coseno se trazan en la misma figura 
mediante la superposición de los gráficos uno encima del otro.
plt.show()
    1003/1068
    939
# Plotting tutorials in Python
# Adding Multiple plots by superimposition
# Good for plots sharing similar x, y limits 
# Using multiple plot commands
# Much better and preferred than previous
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2.0*np.pi, 101) 
y = np.sin(x)
z = np.cos(x)
Realización de varios gráficos en la misma figura utilizando la superposición 
de gráficos con comandos de gráficos separados
Al igual que en el ejemplo anterior, aquí, una curva senoidal y una curva coseno se trazan en la 
misma figura utilizando comandos de trazado separados. Esto es más Pythonic y se puede usar 
para obtener identificadores separados para cada gráfico.
plt.title("Plot of some trigonometric functions") 
plt.xticks(xnumbers)
plt.yticks(ynumbers) 
plt.legend(['sine', 'cosine']) 
plt.grid()
plt.axis([0, 6.5, -1.1, 1.1]) # [xstart, xend, ystart, yend] 
plt.show()
    1004/1068
    940
# Plotting tutorials in Python
# Adding Multiple plots by twin x axis
# Good for plots having different y axis range 
# Separate axes and figure objects
Gráficos con eje X común pero eje Y diferente: usando twinx ()
En este ejemplo, trazaremos una curva sinusoidal y una curva sinusoidal hiperbólica en la misma 
gráfica con un eje x común que tiene un eje y diferente. Esto se logra mediante el uso del 
comando twinx () .
# values for making ticks in x and y axis 
xnumbers = np.linspace(0, 7, 15)
ynumbers = np.linspace(-1, 1, 11)
plt.plot(x, y, color='r', label='sin') # r - red colour 
plt.plot(x, z, color='g', label='cos') # g - green colour
plt.xlabel("Angle in Radians") 
plt.ylabel("Magnitude")
plt.title("Plot of some trigonometric functions")
plt.xticks(xnumbers) 
plt.yticks(ynumbers) 
plt.legend() 
plt.grid()
plt.axis([0, 6.5, -1.1, 1.1]) # [xstart, xend, ystart, yend] 
plt.show()
    1005/1068
    941
# replicate axes object and plot curves 
# use axes to set attributes
# Note:
# Grid for second curve unsuccessful : let me know if you find it! :(
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2.0*np.pi, 101) 
y = np.sin(x)
z = np.sinh(x)
# separate the figure object and axes object 
# from the plotting object
fig, ax1 = plt.subplots()
# Duplicate the axes with a different y axis 
# and the same x axis
ax2 = ax1.twinx() # ax2 and ax1 will have common x axis and different y axis
# plot the curves on axes 1, and 2, and get the curve handles 
curve1, = ax1.plot(x, y, label="sin", color='r')
curve2, = ax2.plot(x, z, label="sinh", color='b')
# Make a curves list to access the parameters in the curves 
curves = [curve1, curve2]
# add legend via axes 1 or axes 2 object. 
# one command is usuallysufficient
# ax1.legend() # will not display the legend of ax2 
# ax2.legend() # will not display the legend of ax1
ax1.legend(curves, [curve.get_label() for curve in curves])
# ax2.legend(curves, [curve.get_label() for curve in curves]) # also valid
# Global figure properties
plt.title("Plot of sine and hyperbolic sine") 
plt.show()
    1006/1068
    942
# Plotting tutorials in Python
# Adding Multiple plots by twin y axis
# Good for plots having different x axis range 
# Separate axes and figure objects
# replicate axes object and plot curves 
# use axes to set attributes
import numpy as np
import matplotlib.pyplot as plt
y = np.linspace(0, 2.0*np.pi, 101) 
x1 = np.sin(y)
x2 = np.sinh(y)
# values for making ticks in x and y axis 
ynumbers = np.linspace(0, 7, 15)
xnumbers1 = np.linspace(-1, 1, 11)
xnumbers2 = np.linspace(0, 300, 7)
# separate the figure object and axes object 
# from the plotting object
Gráficos con eje Y común y eje X diferente usando twiny ()
En este ejemplo, una gráfica con curvas que tienen un eje y común pero un eje x diferente se 
demuestra utilizando el método twiny () . Además, algunas características adicionales como el 
título, la leyenda, las etiquetas, las cuadrículas, las marcas de eje y los colores se agregan a la 
trama.
    1007/1068
    943
fig, ax1 = plt.subplots()
# Duplicate the axes with a different x axis 
# and the same y axis
ax2 = ax1.twiny() # ax2 and ax1 will have common y axis and different x axis
# plot the curves on axes 1, and 2, and get the axes handles 
curve1, = ax1.plot(x1, y, label="sin", color='r')
curve2, = ax2.plot(x2, y, label="sinh", color='b')
# Make a curves list to access the parameters in the curves 
curves = [curve1, curve2]
# add legend via axes 1 or axes 2 object. 
# one command is usually sufficient
# ax1.legend() # will not display the legend of ax2 
# ax2.legend() # will not display the legend of ax1
# ax1.legend(curves, [curve.get_label() for curve in curves]) 
ax2.legend(curves, [curve.get_label() for curve in curves]) # also valid
# x axis labels via the axes 
ax1.set_xlabel("Magnitude", color=curve1.get_color()) 
ax2.set_xlabel("Magnitude", color=curve2.get_color())
# y axis label via the axes 
ax1.set_ylabel("Angle/Value", color=curve1.get_color())
# ax2.set_ylabel("Magnitude", color=curve2.get_color()) # does not work 
# ax2 has no property control over y axis
# y ticks - make them coloured as well 
ax1.tick_params(axis='y', colors=curve1.get_color())
# ax2.tick_params(axis='y', colors=curve2.get_color()) # does not work 
# ax2 has no property control over y axis
# x axis ticks via the axes 
ax1.tick_params(axis='x', colors=curve1.get_color()) 
ax2.tick_params(axis='x', colors=curve2.get_color())
# set x ticks 
ax1.set_xticks(xnumbers1) 
ax2.set_xticks(xnumbers2)
# set y ticks 
ax1.set_yticks(ynumbers)
# ax2.set_yticks(ynumbers) # also works
# Grids via axes 1 # use this if axes 1 is used to 
# define the properties of common x axis
# ax1.grid(color=curve1.get_color())
# To make grids using axes 2 
ax1.grid(color=curve2.get_color()) 
ax2.grid(color=curve2.get_color()) 
ax1.xaxis.grid(False)
# Global figure properties
plt.title("Plot of sine and hyperbolic sine") 
plt.show()
    1008/1068
    944
    1009/1068
    945
x = (1, 2, 3)
x[0] # 1
x[1] # 2
x[2] # 3
x[3] # IndexError: tuple index out of range
Capítulo 197: Tupla
Introducción
Una tupla es unalistainmutable de valores. Las tuplas son uno de los tipos de colección más 
simples y comunes de Python, y se pueden crear con el operador de coma ( value = 1, 2, 3 ).
Sintaxis
• (1, a, "hola") # a debe ser una variable
• () # una tupla vacía
• (1,) # una tupla de 1 elemento. (1) no es una tupla.
• 1, 2, 3 # la tupla de 3 elementos (1, 2, 3)
Observaciones
Los paréntesis solo son necesarios para las tuplas vacías o cuando se usan en una llamada de 
función.
Una tupla es una secuencia de valores. Los valores pueden ser de cualquier tipo, y están 
indexados por números enteros, por lo que en este aspecto las tuplas se parecen mucho a las 
listas. La diferencia importante es que las tuplas son inmutables y hashable, por lo que se pueden 
usar en conjuntos y mapas
Examples
Tuplas de indexación
La indexación con números negativos comenzará desde el último elemento como -1:
x[-1] # 3
x[-2] # 2
x[-3] # 1
x[-4] # IndexError: tuple index out of range
Indexando una gama de elementos
    1010/1068
    946
>>> t = (1, 4, 9)
>>> t[0] = 2
Traceback (most recent call last): 
File "<stdin>", line 1, in<module>
TypeError: 'tuple' object does not support item assignment
>>> t = (1, 2)
>>> q = t
>>> t += (3, 4)
>>> t
(1, 2, 3, 4)
>>> q 
(1, 2)
>>> t = (1, 2, 3, [1, 2, 3])
(1, 2, 3, [1, 2, 3])
>>> t[3] += [4, 5]
TypeError: 'tuple' object does not support item assignment
>>> t
(1, 2, 3, [1, 2, 3, 4, 5])
hash( (1, 2) ) # ok
Las tuplas son inmutables
Una de las principales diferencias entre las list y las tuple enPython es que las tuplas son 
inmutables, esdecir,no sepueden agregar o modificarelementos una vez que seinicializa la 
tupla. Por ejemplo:
De manera similar, las tuplas no tienen los métodos .append y .extend como la list . Usar += es 
posible, pero cambia el enlace de la variable, y no la tupla en sí:
Tenga cuidado al colocar objetos mutables, como lists, dentro de tuplas.Esto puede llevar a 
resultados muy confusos al cambiarlos. Por ejemplo:
Ayude a poner de un error y cambiar el contenido de la lista dentro de la tupla:
Puede usar el operador += para "agregar" a una tupla; esto funciona creando una nueva tupla con 
el nuevo elemento que "agregó" y asignándola a su variable actual; La tupla antigua no se 
cambia, pero se reemplaza!
Esto evita la conversión hacia y desde una lista, pero esto es lento y es una mala práctica, 
especialmente si se va a agregar varias veces.
Tuple son elementos sabios hashable y equiparables
print(x[:-1]) # (1, 2)
print(x[-1:]) # (3,)
print(x[1:3]) # (2, 3)
    1011/1068
    947
{ (1, 2)} # ok
{ ([], {"hello"}) ) # not ok
t = 'a', 'b', 'c', 'd', 'e'
t = ('a', 'b', 'c', 'd', 'e')
# <type 'tuple'>
t0 = ()
type(t0)
# <type 'tuple'>
t1 = 'a',
type(t1)
# <type 'str'>
t2 = ('a')
type(t2)
# <type 'tuple'>
t2 = ('a',)
type(t2)
# PEP8-compliant
# this notation is not recommended by PEP8 
# this notation is not recommended by PEP8
t2 = ('a',) 
t2 = 'a', 
t2 = ('a', )
Por lo tanto, una tupla se puede poner dentro de un set o como una clave en un dict solo si cada 
uno de sus elementos puede.
Tupla
Sintácticamente, una tupla es una lista de valores separados por comas:
Aunque no es necesario, es común encerrar las tuplas entre paréntesis:
Crea una tupla vacía con paréntesis:
Para crear una tupla con un solo elemento, debe incluir una coma final:
Tenga en cuenta que un solo valor entre paréntesis no es una tupla:
Para crear una tupla de singleton es necesario tener una coma al final.
Tenga en cuenta que para las tuplas singleton se recomienda (vea PEP8 en comas al final ) usar 
paréntesis. Además, no hay espacios en blanco después de la coma final (ver PEP8 en espacios
en blanco )
Otra forma de crear una tupla es la función integrada tuple .
hash( ([], {"hello"}) # not ok, since lists and sets are not hashabe
    1012/1068
    948
a = 1, 2, 3 # a is the tuple (1, 2, 3)
a = (1, 2, 3) # a is the tuple (1, 2, 3)
a = 1 # a is the value1
a = 1, # a is the tuple (1,)
a = (1,) # a is the tuple (1,)
a = (1) # a is the value 1 and not a tuple
# unpacking AKA multiple assignment 
x, y, z = (1, 2, 3)
# x == 1 
# y == 2 
# z == 3
a = 1, 2, 3, 4
_, x, y, _ = a 
# x == 2
# y == 3
t = tuple('lupins') 
print(t)
t =tuple(range(3)) 
print(t)
# ('l', 'u', 'p', 'i', 'n', 's') 
# (0, 1, 2)
Estos ejemplos se basan en material del libro Think Python de Allen B. Downey .
Embalaje y desembalaje de tuplas
Las tuplas en Python son valores separados por comas. Los paréntesis que se incluyen para 
ingresar las tuplas son opcionales, por lo que las dos asignaciones
y
son equivalentes La asignación a = 1, 2, 3 también se denomina empaquetamiento porque reúne 
valores en una tupla.
Tenga en cuenta que una tupla de un solo valor también es una tupla. Para decirle a Python que 
una variable es una tupla y no un solo valor, puedes usar una coma al final
También se necesita una coma si usa paréntesis
Para desempaquetar valores de una tupla y hacer múltiples asignaciones use
El símbolo _ se puede usar como un nombre de variable desechable si solo se necesitan algunos 
elementos de una tupla, actuando como un marcador de posición:
Tuplas de un solo elemento:
    1013/1068
    949
first, *more, last = (1, 2, 3, 4, 5) 
# first ==1
# more == [2, 3, 4]
# last == 5
colors = "red", "green", "blue" 
rev = colors[::-1]
# rev: ("blue", "green", "red") 
colors = rev
# colors: ("blue", "green", "red")
rev = tuple(reversed(colors)) 
# rev: ("blue", "green", "red") 
colors = rev
# colors: ("blue", "green", "red")
tuple1 = ('a', 'b', 'c', 'd', 'e') 
tuple2 = ('1','2','3')
tuple3 = ('a', 'b', 'c', 'd', 'e')
En Python 3, una variable de destino con un prefijo * se puede usar como una variable de captura
(ver Desempaquetando los iterables ):
Python 3.x 3.0
Elementos de inversión
Invertir elementos dentro de una tupla
O usando reversa (invertida da un iterable que se convierte en una tupla):
Funciones de tupla incorporadas
Las tuplas soportan las siguientes funciones integradas
Comparación
Si los elementos son del mismo tipo, python realiza la comparación y devuelve el resultado. Si los 
elementos son de diferentes tipos, verifica si son números.
• Si son números, realice la comparación.
• Si cualquiera de los elementos es un número, se devuelve el otro elemento.
• De lo contrario, los tipos se ordenan alfabéticamente.
Si llegamos al final de una de las listas, la lista más larga es "más grande". Si ambas listas son 
iguales devuelve 0.
x, = 1, # x is the value1
x = 1, # x is the tuple (1,)
    1014/1068
    950
len(tuple1) 
Out: 5
max(tuple1) 
Out: 'e'
max(tuple2) 
Out: '3'
min(tuple1) 
Out: 'a'
min(tuple2) 
Out: '1'
list = [1,2,3,4,5]
tuple(list)
Out: (1, 2, 3, 4, 5)
Longitud de la tupla
La función len devuelve la longitud total de la tupla.
Max de una tupla
La función max devuelve el elemento de la tupla con el valor máximo
Min de una tupla
La función min devuelve el elemento de la tupla con el valor mínimo
Convertir una lista en tupla
La función integrada tuple convierte una lista en una tupla.
cmp(tuple1, tuple2)
Out: 1
cmp(tuple2, tuple1)
Out: -1
cmp(tuple1, tuple3) 
Out: 0
    1015/1068
    951
tuple1 + tuple2
Out: ('a', 'b', 'c', 'd', 'e', '1', '2', '3')
Concatenación de tuplas
Usa + para concatenar dos tuplas
    1016/1068
    952
>>> u'□'.encode('utf-8') 
'\xf0\x9f\x90\x8d'
>>> b'\xf0\x9f\x90\x8d'.decode('utf-8') 
u'\U0001f40d'
Capítulo 198: Unicode
Examples
Codificación y decodificación.
Codifique siempre de unicode a bytes. En esta dirección, puedes elegir la codificación .
La otra forma es decodificar de bytes a unicode. En esta dirección, tienes que saber qué es la 
codificación .
    1017/1068
    953
type("f") == type(u"f") # True, <class 'str'> 
type(b"f") # <class 'bytes'>
type("f") == type(b"f") # True, <type 'str'> 
type(u"f") # <type 'unicode'>
>>> "£13.55".encode('utf8')
Capítulo 199: Unicode y bytes
Sintaxis
• str.encode (codificación, errores = 'estricto')
• bytes.decode (codificación, errores = 'estricto')
• abierto (nombre de archivo, modo, codificación = Ninguno)
Parámetros
Parámetro Detalles
codificación La codificación a utilizar, por ejemplo, 'ascii' , 'utf8' , etc ...
errores
El modo de errores, por ejemplo, 'replace' parareemplazarlos caracteres 
incorrectosconsignosdeinterrogación,'ignore'paraignorarloscaracteres 
incorrectos, etc.
Examples
Lo esencial
En Python 3, str es el tipo para cadenas habilitadas para Unicode, mientras que bytes es el tipo 
para secuencias de bytes sin procesar.
En Python 2, una cadena casual era una secuencia de bytes sin procesar por defecto y la 
cadena Unicode era cada cadena con el prefijo "u".
Unicode a bytes
Las cadenas Unicode se pueden convertir a bytes con .encode(encoding) .
Python 3
    1018/1068
    954
>>> print type(u"£13.55".encode('utf8'))
<type 'str'>
>>> print u"£13.55".encode('utf8') 
SyntaxError:Non-ASCII character'\xc2' in...
# with encoding set inside a file 
# -*- coding: utf-8 -*-
>>> print u"£13.55".encode('utf8')
£13.55
>>> "£13.55".encode('ascii') 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xa3' in position 0: ordinal not in 
range(128)
>>> b'\xc2\xa313.55'.decode('utf8') 
'£13.55'
>>> b'\xc2\xa313.55'.decode('utf16') 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/csaftoiu/csaftoiu-github/yahoo-groupsbackup/.virtualenv/bin/../lib/python3.5/encodings/utf_16.py", line 16, in decode
return codecs.utf_16_decode(input, errors, True)
UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x35 in position 6: truncated data
Python 2
enpy2,lacodificacióndelaconsolapredeterminadaessys.getdefaultencoding() == 'ascii'yno 
utf-8comoenpy3,porlotanto,imprimirlacomoenelejemploanteriornoesdirectamente 
posible.
Si la codificación no puede manejar la cadena, se genera un `UnicodeEncodeError`:
Bytes a Unicode
Los bytes se pueden convertir en cadenas Unicode con .decode(encoding) .
¡Una secuencia de bytes solo se puede convertir en una cadena Unicode a través de la 
codificación apropiada!
Si la codificación no puede manejar la cadena, se UnicodeDecodeError un UnicodeDecodeError :
b'\xc2\xa313.55'
>>> "£13.55".encode('utf16') 
b'\xff\xfe\xa3\x001\x003\x00.\x005\x005\x00'
    1019/1068
    955
>>> "£13.55".encode('ascii', errors='replace') 
b'?13.55'
>>> "£13.55".encode('ascii', errors='ignore') 
b'13.55'
>>> "£13.55".encode('ascii', errors='namereplace') 
b'\\N{POUND SIGN}13.55'
>>> "£13.55".encode('ascii', errors='xmlcharrefreplace') 
b'&#163;13.55'
>>> "£13.55".encode('ascii', errors='backslashreplace') 
b'\\xa313.55'
>>> b = "£13.55".encode('utf8')
>>> b.decode('ascii', errors='replace') 
'��13.55'
>>> b.decode('ascii', errors='ignore') 
'13.55'
>>> b.decode('ascii', errors='backslashreplace') 
'\\xc2\\xa313.55'
open(fn, mode='r', encoding='utf16') # opens file for reading utf16
#ERROR: cannot write byteswhena string is expected: 
open("foo.txt", "w").write(b"foo")
open(fn, mode='r') # opens file for reading in utf8
Codificación / decodificación de manejo de errores.
.encode y .decode tienen modos de error.
Elvalorpredeterminadoes'strict',quegeneraexcepcionesencasodeerror.Otrosmodosson 
más indulgentes.
Codificación
Descodificación
Moral
De lo anterior se desprende claramente que es vital mantener sus codificaciones rectas cuando 
se trata de unicode y bytes.
Archivo I / O
Losarchivosabiertos enunmodonobinario (por ejemplo,'r'o'w') tratancon cadenas. La 
codificación sordera es 'utf8' .
Los archivos abiertos en modo binario (por ejemplo, 'rb' o 'wb' ) tratan con bytes. No se puede
    1020/1068
    956
open(fn, mode='wb') # open file for writing bytes
# ERROR: cannot write string when bytes is expected: 
open(fn, mode='wb').write("hi")
especificar ningún argumento de codificación ya que no hay codificación.
    1021/1068
    957
import urllib
response = urllib.urlopen('http://stackoverflow.com/documentation/')
print response.code 
# Prints: 200
print response.read()
'<!DOCTYPE html>\r\n<html>\r\n<head>\r\n\r\n<title>Documentation - Stack. etc'
import urllib.request
print(urllib.request.urlopen("http://stackoverflow.com/documentation/")) 
# Prints: <http.client.HTTPResponse at 0x7f37a97e3b00>
response = urllib.request.urlopen("http://stackoverflow.com/documentation/")
print(response.code)
# Prints: 200
print(response.read())
# Prints: b'<!DOCTYPE html>\r\n<html>\r\n<head>\r\n\r\n<title>Documentation - Stack 
Overflow</title>
Capítulo 200: urllib
Examples
HTTP GET
Python 2.x 2.7
Python 2
Elusodeurllib.urlopen() devolveráunobjetoderespuesta,quesepuedemanejardemanera 
similar a un archivo.
El response.code representa el valor de retorno de http. 200 está bien, 404 es NotFound, etc.
response.read() y response.readlines() se pueden usar para leer el archivo html real devuelto por 
la solicitud. Estos métodos funcionan de manera similar a file.read*
Python 3.x 3.0
Python 3
El módulo se ha actualizado para Python 3.x, pero los casos de uso siguen siendo básicamente 
los mismos. urllib.request.urlopen devolverá un objeto similar a un archivo similar.
    1022/1068
    958
import urllib
query_parms = {'username':'stackoverflow', 'password':'me.me'} 
encoded_parms = urllib.urlencode(query_parms)
response = urllib.urlopen("https://stackoverflow.com/users/login", encoded_parms) 
response.code
# Output: 200 
response.read()
# Output: '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n\r\n<title>Log In - Stack Overflow'
import urllib
query_parms = {'username':'stackoverflow', 'password':'me.me'} 
encoded_parms = urllib.parse.urlencode(query_parms).encode('utf-8')
response = urllib.request.urlopen("https://stackoverflow.com/users/login", encoded_parms) 
response.code
# Output: 200 
response.read()
#Output: b'<!DOCTYPEhtml>\r\n<html> ....etc'
import urllib.request
response = urllib.request.urlopen("http://stackoverflow.com/")
data = response.read()
encoding = response.info().get_content_charset() 
html = data.decode(encoding)
import urllib2
response = urllib2.urlopen("http://stackoverflow.com/")
data = response.read()
encoding = response.info().getencoding()
POST HTTP
Para POST, los datos pasan los argumentos de consulta codificados como datos a urlopen () 
Python 2.x 2.7
Python 2
Python 3.x 3.0
Python 3
Decodificar bytes recibidos de acuerdo a la codificación del tipo de contenido
Los bytes recibidos deben decodificarse con la codificación de caracteres correcta para 
interpretarlos como texto:
Python 3.x 3.0
Python 2.x 2.7
    1023/1068
    959
html = data.decode(encoding)
    1024/1068
    960
def func(params):
for value in params:
print ('Got value {}'.format(value))
if value == 1:
# Returns from function as soon as value is 1 
print (">>>> Got 1")
return
print ("Still looping") 
return "Couldn't find 1"
func([5, 3, 1, 2, 8, 9])
Got value 5 
Still looping 
Got value 3 
Still looping 
Got value 1
>>>> Got 1
Capítulo 201: Usando bucles dentro de 
funciones
Introducción
En Python, la función se devolverá tan pronto como la ejecución llegue a la declaración de 
"retorno".
Examples
Declaración de retorno dentro del bucle en una función
En este ejemplo, la función regresará tan pronto como el valor var tenga 1
salida
    1025/1068
    961
Capítulo 202: Uso del módulo "pip": PyPI 
Package Manager
Introducción
A veces es posible que necesite usar el administrador de paquetes pip dentro de Python, por 
ejemplo. cuando algunas importaciones pueden aumentar ImportError y desea manejar la 
excepción. Si desembala en Windows Python_root/Scripts/pip.exe dentro del archivo main .py 
se almacena, donde se importa la clase main del paquete pip . Esto significa que el paquete pip se 
usa siempre que uses el ejecutable pip.Para el uso de pip como ejecutable, consulte: pip: PyPI
Package Manager
Sintaxis
• pip. <function | attribute | class> donde function es uno de:
○ autocompletar ()
○ Finalización de comandos y opciones para el analizador de opciones principal (y 
opciones) y sus subcomandos (y opciones). Habilite mediante la obtención de 
uno de los scripts de shell de finalización (bash, zsh o fish).
○ check_isolated (args)
○ param args {lista}
○ devuelve {booleano}
○ create_main_parser ()
○ devuelve el objeto {pip.baseparser.ConfigOptionParser}
○ main (args = None)
○ param args {lista}
○ devuelve {entero} Si no falla, devuelve 0
○ parseopts (args)
○ param args {lista}
○ get_installed_distributions ()
○ devuelve {lista}
○ get_similar_commands (nombre)
○ Nombre del comando auto-correcto.
○ nombre de parámetro {cadena}
○ devuelve {booleano}
○ get_summaries (ordenado = Verdadero)
○ Rendimientos ordenados (nombre del comando, resumen del comando) tuplas.
○ get_prog ()
○ devuelve {cadena}
○ dist_is_editable (dist)
○ ¿Es la distribución una instalación editable?
○ param dist {objeto}
○ devuelve {booleano}
    1026/1068
    962
import pip
command = 'install' 
parameter = 'selenium'
second_param = 'numpy' # You can give as many package names as needed 
switch = '--upgrade'
pip.main([command, parameter, second_param, switch])
import pip
installed = pip.get_installed_distributions() 
list = []
for i in installed: 
list.append(i.key)
pip.main(['install']+list+['--upgrade'])
for i in installed:
pip.main(['install']+i.key+['--upgrade'])
if name == ' main ': 
try:
import requests 
except ImportError:
print("To use thismodule you need 'requests' module") 
t = input('Install requests? y/n: ')
if t == 'y':
import pip
pip.main(['install', 'requests'])
○ comandos_dicto
○
Examples
atributo {diccionario}
Ejemplo de uso de comandos
Solo los parámetros necesarios son obligatorios, por lo que tanto pip.main(['freeze']) como
pip.main(['freeze', '', '']) son aceptables.
Instalación por lotes
Es posible pasar muchos nombres de paquetes en una llamada, pero si falla una instalación / 
actualización, todo el proceso de instalación se detiene y termina con el estado '1'.
Si no desea detenerse cuando fallan algunas instalaciones, llame a la instalación en bucle.
Manejo de la excepción de ImportError
Cuando usa el archivo python como módulo, no es necesario verificar siempre si el paquete está 
instalado, pero sigue siendo útil para los scripts.
    1027/1068
    963
Fuerza de instalación
Muchos paquetes, por ejemplo, en la versión 3.4 se ejecutarán en 3.6 muy bien, pero si no hay 
distribuciones para una plataforma específica, no se pueden instalar, pero hay una solución 
alternativa. En la convención de nombres de los archivos .whl (conocidos como ruedas), decida si 
puede instalar el paquete en la plataforma especificada. P.ej.
scikit_learn‑ 0.18.1‑ cp36‑ cp36m‑ win_amd64.whl [nombre_paquete] - [versión] - [intérprete de python]
-[intérpretedepython]-[Sistemaoperativo].whl.Sisecambiaelnombredelarchivoderueda, 
para quelaplataforma coincida,pip intenta instalar el paquete incluso si la plataforma o la versión 
depythonnocoinciden.Eliminarlaplataformaoelintérpretedelnombregeneraráunerrorenla 
versión más reciente del módulo pip kjhfkjdf.whl is not a valid wheel filename. .
Alternativamente, el archivo .whl se puede desempaquetar usando un archivador como 7-zip. -
Por lo general, contiene la meta carpeta de distribución y la carpeta con archivos de origen.Estos 
archivos de origen se pueden desempaquetar simplemente en el directorio de site-packges menos 
que esta rueda contenga el script de instalación, de ser así, debe ejecutarse primero.
import requests 
import os 
import sys
pass 
else:
import os 
import sys
print('Some functionality can be unavailable.')
else:
import requests 
import os 
import sys
    1028/1068
    964
def list_check(to_check, the_list): 
for item in the_list:
if to_check == item: 
return True
return False
Capítulo 203: Velocidad de Python del 
programa.
Examples
Notación
Idea básica
La notación utilizada al describir la velocidad de su programa Python se llama notación Big-O. 
Digamos que tienes una función:
Esta es una función simple para verificar si un elemento está en una lista. Para describir la 
complejidad de esta función, dirá O (n). Esto significa "Orden de n", ya que la función O se 
conoce como la función Orden.
O (n): generalmente n es el número de elementos en el contenedor
O (k): generalmente k es el valor del parámetro o el número de elementos en el parámetro
Lista de operaciones
Operaciones: Caso promedio (se supone que los parámetros se generan aleatoriamente)
Anexo: O (1) 
Copia: O (n) 
Del slice: O (n)
Eliminar elemento: O (n) 
Insertar: O (n)
Obtener artículo: O (1) 
Elemento de ajuste: O (1) 
Iteración: O (n)
Obtener rebanada: O (k)
    1029/1068
    965
class Deque:
def init (self): 
self.items = []
def isEmpty(self):
return self.items == []
def addFront(self, item): 
self.items.append(item)
def addRear(self, item): 
self.items.insert(0,item)
def removeFront(self): 
return self.items.pop()
def removeRear(self):
return self.items.pop(0)
def size(self):
return len(self.items)
Establecer rebanada: O (n + k) 
Extender: O (k)
Ordenar: O (n log n) 
Multiplicar: O (nk)
x en s: O (n)
min (s), max (s): O (n) 
Obtener longitud: O (1) 
Operaciones de deque
Un deque es una cola de doble final.
Operaciones: Caso promedio (se supone que los parámetros se generan aleatoriamente)
Anexo: O (1)
Apéndice: O (1) 
Copia: O (n) 
Extender: O (k) 
Extendente: O (k) 
Pop: O (1)
Personas: O (1)
    1030/1068
    966
Eliminar: O (n) 
Girar: O (k)
Establecer operaciones
Operación: Caso promedio (asume parámetros generados aleatoriamente): Peor caso
x en s: O (1)
Diferencia s - t: O (len (s))
Intersección s & t: O (min (len (s), len (t))): O (len (s) * len (t)
Intersección múltiple s1 & s2 & s3 & ... & sn:: (n-1) * O (l) donde l es max (len (s1), ..., len (sn)) 
s.difference_update (t): O (len (t)): O (len (t) * len (s))
ymetric_difference_update (t): O (len (t)) 
Diferencia simétrica s ^ t: O (len (s)): O (len (s) * len (t)) 
Unión s | t: O (len (s) + len (t))
Notaciones algorítmicas ...
Hay ciertos principios que se aplican a la optimización en cualquier lenguaje de computadora, y 
Python no es una excepción. No optimice a medida que avanza : escriba su programa sin 
importar las posibles optimizaciones, concentrándose en asegurarse de que el código sea limpio, 
correcto y comprensible. Si es demasiado grande o demasiado lento cuando haya terminado, 
entonces puede considerar optimizarlo.
Recuerde la regla 80/20 : en muchos campos puede obtener el 80% del resultado con el 20% del 
esfuerzo (también llamada regla 90/10 - depende de con quién hable). Cuando esté a punto de 
optimizar el código, use la creación de perfiles para averiguar a dónde va ese 80% del tiempo de 
ejecución, para que sepa dónde concentrar su esfuerzo.
Ejecute siempre los puntos de referencia "antes" y "después" : ¿De qué otra manera sabrá 
que sus optimizaciones realmente hicieron una diferencia? Si su código optimizado resulta ser 
solo un poco más rápido o más pequeño que la versión original, deshaga los cambios y vuelva al 
código original y sin cifrar.
Use los algoritmos y las estructuras de datos correctos: No use un algoritmo de clasificación de 
burbuja O (n2) para ordenar mil elementos cuando haya una ordenación rápida O (n log n) 
disponible. Del mismo modo, no almacene mil elementos en una matriz que requiera una 
búsqueda O (n) cuando podría usar un árbol binario O (log n) o una tabla hash O (1) de Python.
Para más información, visite el siguiente enlace ... Python Speed Up
Las siguientes 3 notaciones asintóticas se usan principalmente para representar la complejidad
    1031/1068
    967
del tiempo de los algoritmos.
1. Θ Notación : la notación theta limita las funciones desde arriba y desde abajo, por lo que 
define el comportamiento asintótico exacto. Una forma sencilla de obtener la notación Theta 
de una expresión es eliminar los términos de orden inferior e ignorar las constantes iniciales. 
Por ejemplo, considere la siguiente expresión. 3n3 + 6n2 + 6000 = Θ (n3) La eliminación de 
los términos de orden inferior siempre está bien porque siempre habrá un n0, luego de lo 
cual Θ (n3) tiene valores más altos que Θn2) independientemente de las constantes 
involucradas. Para una función dada g (n), denotamos que Θ (g (n)) está siguiendo un 
conjunto de funciones. Θ (g (n)) = {f (n): existen constantes positivas c1, c2 y n0 tales que 0
<= c1 g (n) <= f (n) <= c2 g (n) para todo n> = n0} La definición anterior significa que si f (n)
es theta de g (n), entonces el valor f (n) siempre está entre c1 g (n) y c2 g (n) para valores 
grandes de n (n> = n0). La definición de theta también requiere que f (n) no sea negativa 
para valores de n mayores que n0.
2. Notación Big O : La notación Big O define un límite superior de un algoritmo, limita una 
función solo desde arriba. Por ejemplo, considérese el caso de Insertion Sort. Lleva tiempo 
lineal en el mejor de los casos y el tiempo cuadrático en el peor de los casos. Podemos 
decir con seguridad que la complejidad temporal de la ordenación de inserción es O (n ^ 2). 
Tenga en cuenta que O (n ^ 2) también cubre el tiempo lineal. Si usamos la notación para 
representar la complejidad de tiempo de la ordenación por Inserción, tenemos que usar dos 
afirmaciones para el mejor y el peor de los casos:
1. La complejidad en el peor de los casos de Insertion Sort es Θ (n ^ 2).
2. El mejor caso de complejidad en el tiempo de Insertion Sort es Θ (n).
La notación Big O es útil cuando solo tenemos un límite superior en la complejidad de tiempo de 
un algoritmo. Muchas veces encontramos fácilmente un límite superior simplemente mirando el 
algoritmo. O (g (n)) = {f (n): existen constantes positivas c y n0 tales que 0 <= f (n) <= cg (n) para 
todos n> = n0}
3. Ω Notación : al igual que la notación Big O proporciona un límite superior asintótico en una 
función, la notación provides proporciona un límite inferior asintótico. Ω La notación <puede 
ser útil cuando tenemos un límite inferior en la complejidad del tiempo de un algoritmo. 
Como se discutió en la publicación anterior, el mejor rendimiento de un algoritmo 
generalmente no es útil, la notación Omega es la notación menos utilizada entre las tres. 
Para una función dada g (n), denotamos por Ω (g (n)) el conjunto de funciones. Ω (g (n)) = {f 
(n): existen constantes positivas c y n0 tales que 0 <= cg (n) <= f (n) para todos n> = n0}. 
Consideremos el mismo ejemplo de orden de inserción aquí. La complejidad temporal de la 
clasificación de inserción se puede escribir como Ω (n), pero no es una información muy útil 
sobre la clasificación de inserción, ya que generalmente estamos interesados en el peor de 
los casos y, a veces, en el caso promedio.
    1032/1068
    968
import matplotlib.pyplot as plt
# Generate some data for plotting. 
x = [0, 1, 2, 3, 4, 5, 6]
y = [i**2 for i in x]
# Plot the data x, y with some keyword arguments that control the plot style.
# Use two different plot commands to plot both points (scatter) and a line (plot).
plt.scatter(x, y, c='blue', marker='x', s=100) # Create blue markers of shape "x" and size 100 
plt.plot(x, y, color='red', linewidth=2) # Create a red line with linewidth 2.
# Add some text to the axes and a title. 
plt.xlabel('x data')
plt.ylabel('y data') 
plt.title('An example plot')
# Generate the plot and show to the user. 
plt.show()
Capítulo 204: Visualización de datos con 
Python
Examples
Matplotlib
Matplotlib es una biblioteca de trazado matemático para Python que proporciona una variedad de 
funciones de trazado diferentes.
La documentación de matplotlib se puede encontrar aquí , con los SO Docs disponibles 
aquí .
Matplotlib proporciona dos métodos distintos para trazar, aunque son intercambiables en su 
mayor parte:
• En primer lugar, matplotlib proporciona la interfaz pyplot , una interfaz directa y fácil de usar 
que permite trazar gráficos complejos en un estilo similar a MATLAB.
• En segundo lugar, matplotlib permite al usuario controlar los diferentes aspectos (ejes, 
líneas, tics, etc.) directamente mediante un sistema basado en objetos. Esto es más difícil 
pero permite un control completo sobre toda la trama.
A continuación se muestra un ejemplo del uso de la interfaz pyplot para trazar algunos datos 
generados:
    1033/1068
    969
import numpy as np # numpy used to create data from plotting 
import seaborn as sns # common form of importingseaborn
Tenga en cuenta que se plt.show() que plt.show() es problemático en algunos entornos debido a 
la ejecución de matplotlib.pyplot en modo interactivo, y si es así, el comportamiento de bloqueo 
se puede anular explícitamente al pasar un argumento opcional, plt.show(block=True) , para paliar 
el problema.
Seaborn
Seaborn es una envoltura alrededor de Matplotlib que facilita la creación de gráficos estadísticos 
comunes. La lista de gráficos admitidos incluye gráficos de distribución univariada y bivariada, 
gráficos de regresión y varios métodos para representar variables categóricas. La lista completa 
de las parcelas que proporciona Seaborn se encuentra en su referencia API .
Crear gráficos en Seaborn es tan simple como llamar a la función de gráficos apropiada. Este es 
un ejemplo de la creación de un histograma, una estimación de la densidad del kernel y una 
gráfica de tap para datos generados aleatoriamente.
    1034/1068
    970
# Using previously created imports and data.
# Use a dark background with no grid. 
sns.set_style('dark')
# Create the plot again 
sns.distplot(data, kde=True, rug=True)
El estilo de la trama también se puede controlar mediante una sintaxis declarativa.
# Generate normally distributed data 
data = np.random.randn(1000)
# Plot a histogram with both a rugplot and kde graph superimposed 
sns.distplot(data, kde=True, rug=True)
    1035/1068
    971
# Using previously created data and style
# Access to matplotlib commands 
import matplotlib.pyplot as plt
# Previously created plot. 
sns.distplot(data, kde=True, rug=True) 
# Set the axis labels. 
plt.xlabel('This is my x-axis') 
plt.ylabel('This is my y-axis')
Como un bono adicional, los comandos normales de matplotlib todavía se pueden aplicar a los 
gráficos de Seaborn. Aquí hay un ejemplo de cómo agregar títulos de ejes a nuestro histograma 
creado anteriormente.
    1036/1068
    972
MayaVI
MayaVI es una herramienta de visualización 3D para datos científicos. Utiliza el kit de 
herramientas de visualización o VTK debajo del capó. Usando el poder de VTK , MayaVI es 
capaz de producir una variedad de gráficos y figuras tridimensionales. Está disponible como una 
aplicación de software independiente y también como una biblioteca. Similar a Matplotlib , esta 
biblioteca proporciona una interfaz de lenguaje de programación orientada a objetos para crear 
gráficos sin tener que saber acerca de VTK .
¡MayaVI está disponible solo en la serie Python 2.7x! ¡Se espera que esté disponible en la 
serie Python 3-x pronto! (Aunque se nota cierto éxito al usar sus dependencias en Python 
3)
La documentación se puede encontrar aquí . Algunos ejemplos de galerías se encuentran aquí.
Aquí hay una muestra de la parcela creada usando MayaVI de la documentación.
#Author: Gael Varoquaux<gael.varoquaux@normalesup.org>
# Copyright (c) 2007, Enthought, Inc.
# License: BSD Style.
    1037/1068
    973
Plotly
Plotly es una plataforma moderna para el trazado y visualización de datos. Útil para producir una 
variedad de gráficos, especialmente para ciencias de datos, Plotly está disponible como una 
biblioteca para Python , R , JavaScript , Julia y MATLAB . También se puede utilizar como una 
aplicación web con estos idiomas.
Los usuarios pueden instalar plotly library y usarlo fuera de línea después de la autenticación del 
usuario. La instalación de esta biblioteca y la autenticación fuera de línea se da aquí . Además, 
las parcelas se pueden hacer en Jupyter Notebooks también.
El uso de esta biblioteca requiere una cuenta con nombre de usuario y contraseña. Esto 
proporciona el espacio de trabajo para guardar gráficos y datos en la nube.
La versión gratuita de la biblioteca tiene algunas características ligeramente limitadas y está
from numpy import sin, cos, mgrid, pi, sqrt 
from mayavi import mlab
mlab.figure(fgcolor=(0, 0, 0), bgcolor=(1, 1, 1)) 
u, v = mgrid[- 0.035:pi:0.01, - 0.035:pi:0.01]
X = 2 / 3. * (cos(u) * cos(2 * v)
+ sqrt(2) * sin(u) * cos(v)) * cos(u) / (sqrt(2) -
sin(2 * u) * sin(3 * v))
Y = 2 / 3. * (cos(u) * sin(2 * v) -
sqrt(2) * sin(u) * sin(v)) * cos(u) / (sqrt(2)
- sin(2 * u) * sin(3 * v))
Z = -sqrt(2) * cos(u) * cos(u) / (sqrt(2) - sin(2 * u) * sin(3 * v)) 
S = sin(u)
mlab.mesh(X, Y, Z, scalars=S, colormap='YlGnBu', ) 
# Nice view from the front
mlab.view(.0, - 5.0, 4)
mlab.show()
    1038/1068
    974
import plotly.graph_objs as go 
import plotly as ply
# Create random data with numpy 
import numpy as np
N = 100
random_x = np.linspace(0, 1, N) 
random_y0 = np.random.randn(N)+5 
random_y1 = np.random.randn(N) 
random_y2 = np.random.randn(N)-5
# Create traces 
trace0 = go.Scatter(
x = random_x, 
y = random_y0, 
mode = 'lines', 
name = 'lines'
)
trace1 = go.Scatter( 
x = random_x,
y = random_y1,
mode = 'lines+markers', 
name = 'lines+markers'
)
trace2 = go.Scatter( 
x = random_x,
y = random_y2, 
mode = 'markers', 
name = 'markers'
)
data = [trace0, trace1, trace2]
ply.offline.plot(data, filename='line-mode')
diseñada para hacer 250 parcelas por día. La versión de pago tiene todas las características, 
descargas de parcelas ilimitadas y más almacenamiento de datos privados. Para más detalles, se 
puede visitar la página principal aquí .
Para documentación y ejemplos, se puede ir aquí.
Un diagrama de muestra de los ejemplos de documentación:
    1039/1068
    975
    1040/1068
    976
Capítulo 205: Web raspado con Python
Introducción
El raspado web es un proceso automatizado y programático a través del cual los datos se pueden 
" raspar " constantemente de las páginas web. También conocido como raspado de pantalla o 
recolección web, el raspado web puede proporcionar datos instantáneos desde cualquier página 
web de acceso público. En algunos sitios web, el raspado web puede ser ilegal.
Observaciones
Paquetes de Python útiles para raspado web 
(orden alfabético)
Realización de solicitudes y recogida de datos.
requests
Un paquete simple, pero poderoso para hacer peticiones HTTP.
requests-cache
Caché para requests ; almacenar datos en caché es muy útil. En desarrollo, significa que puede 
evitar golpear un sitio innecesariamente. Mientras ejecuta una colección real, significa que si su 
raspador se bloquea por algún motivo (tal vez no haya manejado algún contenido inusual en el 
sitio ... ¿Tal vez el sitio se haya caído ...?) Puede repetir la colección muy rápidamente de donde 
lo dejaste.
scrapy
Útil para crear rastreadores web, donde necesita algo más potente que usar requests e iterar a 
través de páginas.
selenium
Enlaces Python para Selenium WebDriver, para la automatización del navegador. El uso de 
requests para realizar solicitudes HTTP directamente es a menudo más sencillo para recuperar 
páginas web. Sin embargo, esto sigue siendo una herramienta útil cuando no es posible replicar 
el comportamiento deseado de un sitio usando solo las requests , particularmente cuando se 
requiere JavaScript para representar elementos en una página.
Análisis de HTML
    1041/1068
    977
# For Python 2 compatibility.
from future import print_function
import lxml.html 
import requests
def main():
r = requests.get("https://httpbin.org") 
html_source = r.text
root_element = lxml.html.fromstring(html_source)
# Note root_element.xpath() gives a *list* of results. 
# XPath specifies a path to the element we want.
page_title = root_element.xpath('/html/head/title/text()')[0] 
print(page_title)
if name == ' main ': 
main()
import requests
with requests.Session() as session:
# all requests through session now have User-Agent header set
session.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'}
# set cookies
session.get('http://httpbin.org/cookies/set?key=value')
# get cookies
response = session.get('http://httpbin.org/cookies')
print(response.text)
BeautifulSoup
ConsultedocumentosHTMLyXML,utilizandovariosanalizadoresdiferentes(elanalizadorHTML 
incorporado de Python, html5lib , lxml o lxml.html )
lxml
Procesos HTML y XML. Puede usarse para consultar y seleccionar contenido de documentos 
HTML a través de selectores de CSS y XPath.
Examples
Ejemplo básico de uso de solicitudes y lxml para raspar algunos datos
Mantenimiento de sesión web-scraping con peticiones.
Es una buena idea mantener una sesión de raspado web para conservarlas cookies y otros 
parámetros. Además, puede dar lugar a una mejora del rendimiento porque requests.Session 
reutiliza la conexión TCP subyacente a un host:
    1042/1068
    978
scrapy startproject projectName
import scrapy
class StackOverflowSpider(scrapy.Spider):
name = 'stackoverflow' # each spider has a unique name
start_urls = ['http://stackoverflow.com/questions?sort=votes'] # the parsing starts from 
a specific set of urls
def parse(self, response): # for each request this generator yields, its response is sent 
to parse_question
for href in response.css('.question-summary h3 a::attr(href)'): # do some scraping 
stuff using css selectors to find question urls
full_url = response.urljoin(href.extract())
yield scrapy.Request(full_url, callback=self.parse_question)
def parse_question(self, response): 
yield {
'title': response.css('h1 a::text').extract_first(),
'votes': response.css('.question .vote-count-post::text').extract_first(), 
'body': response.css('.question .post-text').extract_first(),
'tags': response.css('.question .post-tag::text').extract(), 
'link': response.url,
}
scrapy crawl stackoverflow
#USER_AGENT = 'projectName (+http://www.yourdomain.com)'
Raspado utilizando el marco de Scrapy
Primero tienes que configurar un nuevo proyecto Scrapy. Ingrese un directorio donde le gustaría 
almacenar su código y ejecute:
Para raspar necesitamos una araña. Las arañas definen cómo se raspará un determinado sitio. 
Aquí está el código para una araña que sigue los enlaces a las preguntas más votadas en 
StackOverflow y raspa algunos datos de cada página ( fuente ):
Guarda tus clases de arañas en el directorio nombre de projectName\spiders . En este caso,
projectName\spiders\stackoverflow_spider.py .
Ahora puedes usar tu araña. Por ejemplo, intente ejecutar (en el directorio del proyecto):
Modificar agente de usuario de Scrapy
En ocasiones, el host bloquea el agente de usuario de Scrapy predeterminado ( "Scrapy/VERSION 
(+http://scrapy.org)" ). Para cambiar el agente de usuario predeterminado, abra settings.py , 
elimine el comentario y edite la siguiente línea como desee.
Por ejemplo
    1043/1068
    979
from bs4 import BeautifulSoup 
import requests
# Use the requests module to obtain a page
res = requests.get('https://www.codechef.com/problems/easy')
# Create a BeautifulSoup object
page = BeautifulSoup(res.text, 'lxml') # the text field contains the source of the page
# Now use a CSS selector in order to get the table containing the list of problems 
datatable_tags = page.select('table.dataTable') # The problems are in the <table> tag,
# with class "dataTable" 
# We extract the first tag from the list, since that's what we desire 
datatable = datatable_tags[0]
# Now since we want problem names, they are contained in <b> tags, which are 
# directly nested under <a> tags
prob_tags = datatable.select('a > b')
prob_names = [tag.getText().strip() for tag in prob_tags]
print prob_names
title = browser.find_element_by_css_selector('h1').text # page title (first h1 element) 
questions = browser.find_elements_by_css_selector('.question-summary') # question list
for question in questions: # iterate over questions
question_title = question.find_element_by_css_selector('.summary h3 a').text 
question_excerpt = question.find_element_by_css_selector('.summary .excerpt').text 
question_vote = question.find_element_by_css_selector('.stats .vote .votes .vote-countpost').text
print "%s\n%s\n%s votes\n----------- \n" % (question_title, question_excerpt,
question_vote)
# load url
from selenium import webdriver
browser = webdriver.Firefox() # launch firefox browser
browser.get('http://stackoverflow.com/questions?sort=votes')
Raspado utilizando BeautifulSoup4
Raspado utilizando Selenium WebDriver
Algunos sitios web no les gusta ser raspado. En estos casos, es posible que necesite simular a un 
usuario real que trabaja con un navegador. Selenium lanza y controla un navegador web.
El selenio puede hacer mucho más. Puede modificar las cookies del navegador, rellenar 
formularios, simular clics del ratón, tomar capturas de pantalla de páginas web y ejecutar 
JavaScript personalizado.
Descarga de contenido web simple con urllib.request
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/51.0.2704.103 Safari/537.36'
    1044/1068
    980
from urllib.request import urlopen
response = urlopen('http://stackoverflow.com/questions?sort=votes')
data = response.read()
# The received bytes should usually be decoded according the response's character set 
encoding = response.info().get_content_charset()
html = data.decode(encoding)
from subprocess import Popen, PIPE 
from lxml import etree
from io import StringIO
user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/55.0.2883.95 Safari/537.36'
url = 'http://stackoverflow.com'
get = Popen(['curl', '-s', '-A', user_agent, url], stdout=PIPE) 
result = get.stdout.read().decode('utf8')
El módulo de biblioteca estándar urllib.request se puede usar para descargar contenido web:
Un módulo similar también está disponible en Python 2 .
Raspado con rizo
importaciones:
Descargando:
-s : descarga silenciosa
-A : bandera de agente de usuario 
Análisis:
tree = etree.parse(StringIO(result), etree.HTMLParser()) 
divs = tree.xpath('//div')
    1045/1068
    981
import asyncio
from aiohttp import ClientSession 
class EchoWebSocket(ClientSession):
URL = "wss://echo.websocket.org"
def init (self): 
super(). init () 
self.websocket=None
async def connect(self):
"""Connect to the WebSocket."""
self.websocket = await self.ws_connect(self.URL)
async def send(self, message):
"""Send a message to the WebSocket."""
assert self.websocket is not None, "You must connect first!" 
self.websocket.send_str(message)
print("Sent:", message)
import asyncio
from aiohttp import ClientSession
with ClientSession() as session: 
async def hello_world():
websocket = await session.ws_connect("wss://echo.websocket.org") 
websocket.send_str("Hello, world!")
print("Received:", (await websocket.receive()).data) 
await websocket.close()
loop = asyncio.get_event_loop() 
loop.run_until_complete(hello_world())
Capítulo 206: Websockets
Examples
Eco simple con aiohttp
aiohttp proporciona websockets asíncronos. 
Python 3.x 3.5
Clase de envoltura con aiohttp
aiohttp.ClientSession puede usarse como padre para una clase de WebSocket personalizada. 
Python 3.x 3.5
    1046/1068
    982
python -m pip install autobahn
from autobahn.asyncio.websocket import WebSocketServerProtocol 
class MyServerProtocol(WebSocketServerProtocol):
Usando Autobahn como una Websocket Factory
El paquete Autobahn se puede utilizar para las fábricas de servidores de socket web de Python. 
Documentación del paquete Python Autobahn
Para instalar, normalmente uno simplemente usaría el comando de terminal 
(Para Linux):
(Para ventanas):
Luego, se puede crear un servidor de eco simple en un script de Python:
sudo pip install autobahn
async def receive(self):
"""Receive one message from the WebSocket."""
assert self.websocket is not None, "You must connect first!" 
return (await self.websocket.receive()).data
async def read(self):
"""Read messages from the WebSocket."""
assert self.websocket is not None, "You must connect first!"
while self.websocket.receive(): 
message = await self.receive() 
print("Received:", message) 
if message == "Echo9!":
break
async def send(websocket): 
for n in range(10):
await websocket.send("Echo {}!".format(n)) 
await asyncio.sleep(1)
loop = asyncio.get_event_loop() 
with EchoWebSocket() aswebsocket:
loop.run_until_complete(websocket.connect())
tasks = (
send(websocket), 
websocket.read()
)
loop.run_until_complete(asyncio.wait(tasks)) 
loop.close()
    1047/1068
    983
'''When creating server protocol, the 
user defined class inheriting the 
WebSocketServerProtocol needstooverride 
the onMessage, onConnect, et-c eventsfor 
user specified functionality, these events
define your server's protocol, in essence''' 
def onMessage(self,payload,isBinary):
'''The onMessage routine is called 
when the server receives a message.
It has the required arguments payload 
and the bool isBinary. The payload isthe
actual contents of the "message" and isBinary 
is simply a flag to let the user know that 
the payload contains binary data. I typically 
elsewise assume that the payload is a string.
In this example, the payload is returned to sender verbatim.''' 
self.sendMessage(payload,isBinary)
if name ==' main ': 
try:
importasyncio 
except ImportError:
'''Trollius = 0.3 was renamed''' 
import trollius as asyncio
from autobahn.asyncio.websocketimportWebSocketServerFactory 
factory=WebSocketServerFactory()
'''Initialize the websocket factory, and set the protocol to the 
above defined protocol(the class that inherits from 
autobahn.asyncio.websocket.WebSocketServerProtocol)''' 
factory.protocol=MyServerProtocol
'''This above line can be thought of as "binding" the methods
onConnect, onMessage, et-c that were described in the MyServerProtocol class 
to the server, setting the servers functionality, ie, protocol''' 
loop=asyncio.get_event_loop() 
coro=loop.create_server(factory,'127.0.0.1',9000) 
server=loop.run_until_complete(coro)
'''Run the server in an infinite loop''' 
try:
loop.run_forever() 
except KeyboardInterrupt:
pass 
finally:
server.close() 
loop.close()
En este ejemplo, se está creando un servidor en el host local (127.0.0.1) en el puerto 9000. Esta 
es la IP y el puerto de escucha. Esta información es importante, ya que al usar esto, puede 
identificar la dirección LAN de su computadora y el puerto hacia adelante desde su módem, 
aunque cualquier enrutador que tenga a la computadora. Luego, utilizando google para investigar 
su IP WAN, puede diseñar su sitio web para enviar mensajes WebSocket a su IP WAN, en el 
puerto 9000 (en este ejemplo).
Es importante que retroceda desde su módem, lo que significa que si tiene enrutadores 
conectados en cadena al módem, ingrese a los ajustes de configuración del módem, transfiera el 
puerto desde el módem al enrutador conectado, y así sucesivamente hasta el enrutador final de 
su computadora está conectado está recibiendo la información que se está recibiendo en el 
puerto de módem 9000 (en este ejemplo).
    1048/1068
    984
    1049/1068
    985
Creditos
S.
No Capítulos Contributors
1
Empezando con 
Python Language
A. Raza, Aaron Critchley, Abhishek Jain, AER, afeique,
Akshay Kathpal, alejosocorro, Alessandro Trinca Tornidor,
Alex Logan, ALinuxLover, Andrea, Andrii Abramov, Andy, Andy
Hayden, angussidney, Ani Menon, Anthony Pham, Antoine
Bolvy, Aquib Javed Khan, Ares, Arpit Solanki, B8vrede, Baaing
Cow, baranskistad, Brian C, Bryan P, BSL-5, BusyAnt,
Cbeb24404, ceruleus, ChaoticTwist, Charlie H, Chris Midgley,
Christian Ternus, Claudiu, Clíodhna, CodenameLambda, cʟᴅs
ᴇᴇᴅ, Community, Conrad.Dean, Daksh Gupta, Dania, Daniel
Minnaar, Darth Shadow, Dartmouth, deeenes, Delgan,
depperm, DevD, dodell, Douglas Starnes, duckman_1991,
Eamon Charles, edawine, Elazar, eli-bd, Enrico Maria De
Angelis, Erica, Erica, ericdwang, Erik Godard, EsmaeelE, Filip
Haglund, Firix, fox, Franck Dernoncourt, Fred Barclay, Freddy,
Gerard Roche, glS, GoatsWearHats, GThamizh, H. Pauwelyn,
hardmooth, hayalci, hichris123, Ian, IanAuld, icesin, Igor
Raush, Ilyas Mimouni, itsthejoker, J F, Jabba, jalanb, James,
James Taylor, Jean-Francois T., jedwards, Jeffrey Lin, jfunez,
JGreenwell, Jim Fasarakis Hilliard, jim opleydulven, jimsug,
jmunsch, Johan Lundberg, John Donner, John Slegers,
john400, jonrsharpe, Joseph True, JRodDynamite, jtbandes,
Juan T, Kamran Mackey, Karan Chudasama, KerDam, Kevin
Brown, Kiran Vemuri, kisanme, Lafexlos, Leon, Leszek Kicior,
LostAvatar, Majid, manu, MANU, Mark Miller, Martijn Pieters,
Mathias711, matsjoyce, Matt, Mattew Whitt, mdegis, Mechanic,
Media, mertyildiran, metahost, Mike Driscoll, MikJR, Miljen
Mikic, mnoronha, Morgoth, moshemeirelles, MSD, MSeifert,
msohng, msw, muddyfish, Mukund B, Muntasir Alam, Nathan
Arthur, Nathaniel Ford, Ned Batchelder, Ni., niyasc, noɥʇʎԀ
ʎzɐɹƆ, numbermaniac, orvi, Panda, Patrick Haugh, Pavan
Nath, Peter Masiar, PSN, PsyKzz, pylang, pzp, Qchmqs, Quill,
Rahul Nair, Rakitić, Ram Grandhi, rfkortekaas, rick112358,
Robotski, rrao, Ryan Hilbert, Sam Krygsheld, Sangeeth
Sudheer, SashaZd, Selcuk, Severiano Jaramillo Quintanar,
Shiven, Shoe, Shog9, Sigitas Mockus, Simplans, Slayther,
stark, StuxCrystal, SuperBiasedMan, Sнаđошƒа, taylor swift,
techydesigner, Tejus Prasad, TerryA, The_Curry_Man,
TheGenie OfTruth, Timotheus.Kampik, tjohnson, Tom Barron,
Tom de Geus, Tony Suffolk 66, tonyo, TPVasconcelos,
    1050/1068
    986
user2314737, user2853437, user312016, Utsav T, 
vaichidrewar, vasili111, Vin, W.Wong, weewooquestionaire, 
Will, wintermute, Yogendra Sharma, Zach Janicki, Zags
2 * args y ** kwargs
cjds, Eric Zhang, ericmarkmartin, Geeklhem, J F, Jeff Hutchins
, Jim Fasarakis Hilliard, JuanPablo, kdopen, loading..., Marlon
Abeykoon, Mattew Whitt, Pasha, pcurry, PsyKzz, Scott
Mermelstein, user2314737, Valentin Lorentz, Veedrac
3
Acceso a la base de 
datos
Alessandro Trinca Tornidor, Antonio, bee-sting, cʟᴅsᴇᴇᴅ, D.
Alveno, John Y, LostAvatar, mbsingh, Michel Touw, qwertyuip9
, RamenChef, rrawat, Stephen Leppik, Stephen Nyamweya, 
sumitroy, user2314737, valeas, zweiterlinde
4
Acceso al código 
fuente y código de 
bytes de Python
muddyfish, StuxCrystal, user2314737
5 Acceso de atributo Elazar, SashaZd, SuperBiasedMan
6 agrupar por() Parousia, Thomas Gerot
7
Alcance variable y 
vinculante
Anthony Pham, davidism, Elazar, Esteis, Mike Driscoll, 
SuperBiasedMan, user2314737, zvone
8 Almohada Razik
9
Alternativas para 
cambiar la 
declaración de otros 
idiomas
davidism, J F, zmo, Валерий Павлов
10 Ambiente Virtual 
Python - virtualenv Vikash Kumar Jain
11
Análisis de 
argumentos de línea 
de comandos
amblina, Braiam, Claudiu, cledoux, Elazar, Gerard Roche, 
krato, loading..., Marco Pashkov, Or Duan, Pasha, RamenChef
, rfkortekaas, Simplans, Thomas Gerot, Topperfalkon, zmo, 
zondo
12 Análisis de HTML alecxe, talhasch
13 Anti-patrones de 
Python
Alessandro Trinca Tornidor, Annonymous, eenblam, Mahmoud
Hashemi, RamenChef, Stephen Leppik
14 Apilar
ADITYA, boboquack, Chromium, cjds, depperm, Hannes
Karppila, JGreenwell, Jonatan, kdopen, OliPro007, orvi, 
SashaZd, Sнаđошƒа, textshell, Thomas Ahle, user2314737
15 Árbol de sintaxis Teepeemm
    1051/1068
    987
abstracta
16 Archivos y carpetas I
/ O
Ajean, Anthony Pham, avb, Benjamin Hodgson, Bharel, 
Charles, crhodes, David Cullen, Dov, Esteis, ilse2005, isvforall, 
jfsturtz, Justin, Kevin Brown, mattgathu, MSeifert, nlsdfnbch, 
Ozair Kafray, PYPL, pzp, RamenChef, Ronen Ness, rrao, 
Serenity, Simplans, SuperBiasedMan, Tasdik Rahman, 
Thomas Gerot, Umibozu, user2314737, Will, WombatPM, 
xgord
17 ArcPy Midavalo, PolyGeo, Zhanping Shi
18 Arrays Andy, Pavan Nath, RamenChef, Vin
19 Audio blueberryfields, Comrade SparklePony, frankyjuang, jmunsch, 
orvi, qwertyuip9, Stephen Leppik, Thomas Gerot
20
Aumentar errores / 
excepciones 
personalizados
naren
21 Biblioteca de 
subproceso
Adam Matan, Andrew Schade, Brendan Abel, jfs, jmunsch, 
Riccardo Petraglia
22
Bloques de código, 
marcos de ejecución 
y espacios de 
nombres.
Jeremy, Mohammed Salman
23 Bucles
Adriano, Alex L, alfonso.kim, Alleo, Anthony Pham, Antti
Haapala, Chris Hunt, Christian Ternus, Darth Kotik, 
DeepSpace, Delgan, DhiaTN, ebo, Elazar, Eric Finn, Felix D., 
Ffisegydd, Gal Dreiman, Generic Snake, ghostarbeiter, 
GoatsWearHats, Guy, Inbar Rose, intboolstring, J F, James, 
Jeffrey Lin, JGreenwell, Jim Fasarakis Hilliard, jrast, Karl
Knechtel, machine yearning, Mahdi, manetsus, Martijn Pieters, 
Math, Mathias711, MSeifert, pnhgiol, rajah9, Rishabh Gupta, 
Ryan, sarvajeetsuman, sevenforce, SiggyF, Simplans, 
skrrgwasme, SuperBiasedMan, textshell, The_Curry_Man, 
Thomas Gerot, Tom, Tony Suffolk 66, user1349663, 
user2314737, Vinzee, Will
24 buscando Dan Sanderson, Igor Raush, MSeifert
25 Características 
ocultas
Aaron Hall, Akshat Mahajan, Anthony Pham, Antti Haapala, 
Byte Commander, dermen, Elazar, Ellis, ericmarkmartin, Fermi
paradox, Ffisegydd, japborst, Jim Fasarakis Hilliard, jonrsharpe
, Justin, kramer65, Lafexlos, LDP, Morgan Thrapp, muddyfish, 
nico, OrangeTux, pcurry, Pythonista, Selcuk, Serenity, Tejas
    1052/1068
    988
Jadhav, tobias_k, Vlad Shcherbina, Will
26 ChemPy - paquete 
de python Biswa_9937
27 Clases base 
abstractas (abc)
Akshat Mahajan, Alessandro Trinca Tornidor, JGreenwell, 
Kevin Brown, Mattew Whitt, mkrieger1, SashaZd, Stephen
Leppik
28 Clasificación, mínimo 
y máximo
Antti Haapala, APerson, GoatsWearHats, Mirec Miskuf, 
MSeifert, RamenChef, Simplans, Valentin Lorentz
29 Comentarios y 
Documentación
Ani Menon, FunkySayu, MattCorr, SuperBiasedMan, 
TuringTux
30 Comparaciones Anthony Pham, Ares, Elazar, J F, MSeifert, Shawn Mehan, 
SuperBiasedMan, Will, Xavier Combelle
31 Complementos y 
clases de extensión 2Cubed, proprefenetre, pylang, rrao, Simon Hibbs, Simplans
32
Comprobando la 
existencia de ruta y 
permisos
Esteis, Marlon Abeykoon, mnoronha, PYPL
33 Computación 
paralela
Akshat Mahajan, Dair, Franck Dernoncourt, J F, Mahdi, 
nlsdfnbch, Ryan Smith, Vinzee, Xavier Combelle
34 Comunicación Serial 
Python (pyserial)
Alessandro Trinca Tornidor, Ani Menon, girish946, mnoronha, 
Saranjith, user2314737
35 Concurrencia de 
Python
David Heyman, Faiz Halde, Iván Rodríguez Torres, J F, 
Thomas Moreau, Tyler Gubala
36 Condicionales
Andy Hayden, BusyAnt, Chris Larson, deepakkt, Delgan, 
Elazar, evuez, Ffisegydd, Geeklhem, Hannes Karppila, James, 
Kevin Brown, krato, Max Feng, noɥʇʎԀʎzɐɹƆ, rajah9, rrao, 
SashaZd, Simplans, Slayther, Soumendra Kumar Sahoo, 
Thomas Gerot, Trimax, Valentin Lorentz, Vinzee, wwii, xgord, 
Zack
37 Conectando Python a 
SQL Server metmirr
38 Conexión segura de 
shell en Python mnoronha, Shijo
39 configparser Chinmay Hegde, Dunatotatos
40 Conjunto Andrzej Pronobis, Andy Hayden, Bahrom, Cimbali, Cody
    1053/1068
    989
Piersall, Conrad.Dean, Elazar, evuez, J F, James, Or East, 
pylang, RahulHP, RamenChef, Simplans, user2314737
41 Contando Andy Hayden, MSeifert, Peter Mølgaard Pallesen, pylang
42 Copiando datos hashcode55, StuxCrystal
43
Corte de listas 
(selección de partes 
de listas)
Greg, JakeD
44 Creando paquetes de Claudiu, KeyWeeUsr, Marco Pashkov, pylang, 
Python SuperBiasedMan, Thtu
45
Creando un servicio 
de Windows usando 
Python
Simon Hibbs
Crear entorno virtual
46 con Sirajus Salayhin
virtualenvwrapper en
windows
47 ctypes Or East
48 Datos binarios Eleftheria, evuez, mnoronha
49 Decoradores
Alessandro Trinca Tornidor, ChaoticTwist, Community, Dair, 
doratheexplorer0911, Emolga, greut, iankit, JGreenwell, 
jonrsharpe, kefkius, Kevin Brown, Mattew Whitt, MSeifert, 
muddyfish, Mukunda Modell, Nearoo, Nemo, Nuno André, 
Pasha, Rob Bednark, seenu s, Shreyash S Sarnayak,
Simplans, StuxCrystal, Suhas K, technusm1, Thomas Gerot, 
tyteen4a03, Wladimir Palant, zvone
50
Definiendo funciones 
con argumentos de 
lista
zenlc2000
51 dejar de lado Biswa_9937
52 Depuración Aldo, B8vrede, joel3000, Sardathrion, Sardorbek Imomaliev, 
Vlad Bezden
53 Descomprimir 
archivos andrew
54 Descriptor bbayles, cizixs, Nemo, pylang, SuperBiasedMan
55 Despliegue Gal Dreiman, Iancnorden, Wayne Werner
    1054/1068
    990
56 Diccionario
Amir Rachum, Anthony Pham, APerson, ArtOfCode, BoppreH, 
Burhan Khalid, Chris Mueller, cizixs, depperm, Ffisegydd, 
Gareth Latty, Guy, helpful, iBelieve, Igor Raush, Infinity, James
, JGreenwell, jonrsharpe, Karsten 7., kdopen, machine
yearning, Majid, mattgathu, Mechanic, MSeifert, muddyfish, 
Nathan, nlsdfnbch, noɥʇʎԀʎzɐɹƆ, ronrest, Roy Iacob, Shawn
Mehan, Simplans, SuperBiasedMan, TehTris, Valentin Lorentz, 
viveksyngh, Xavier Combelle
57 Diferencia entre 
Módulo y Paquete DeepSpace, Simplans, tjohnson
58 Distribución Alessandro Trinca Tornidor, JGreenwell, metahost, Pigman168
, RamenChef, Stephen Leppik
59 Django code_geek, orvi
60
Ejecución de código 
dinámico con `exec` 
y` eval`
Antti Haapala, Ilja Everilä
61 El dis módulo muddyfish, user2314737
62
El intérprete (consola 
de línea de 
comandos)
Aaron Christiansen, David, Elazar, Peter Shinners, ppperry
63 El módulo base64 Thomas Gerot
64
El módulo de 
configuración 
regional
Will, XonAether
65 El módulo os Andy, Christian Ternus, JelmerS, JL Peyret, mnoronha, Vinzee
66 Empezando con 
GZip orvi
67 Enchufes David Cullen, Dev, MattCorr, nlsdfnbch, Rob H, StuxCrystal, 
textshell, Thomas Gerot, Will
68 entorno virtual con 
virtualenvwrapper Sirajus Salayhin
69 Entornos virtuales
Adrian17, Artem Kolontay, ArtOfCode, Bhargav, brennan, Dair, 
Daniil Ryzhkov, Darkade, Darth Shadow, edwinksl, Fernando, 
ghostarbeiter, ha_1694, Hans Then, Iancnorden, J F, Majid, 
Marco Pashkov, Matt Giltaji, Mattew Whitt, nehemiah, Nuhil
Mehdy, Ortomala Lokni, Preston, pylang, qwertyuip9,
    1055/1068
    991
RamenChef, Régis B., Sebastian Schrader, Serenity, 
Shantanu Alshi, Shrey Gupta, Simon Fraser, Simplans, wrwrwr
, ychaouche, zopieux, zvezda
70 Entrada y salida 
básica
Doraemon, GoatsWearHats, J F, JNat, Marco Pashkov, Mark
Miller, Martijn Pieters, Nathaniel Ford, Nicolás, pcurry, pzp, 
SashaZd, SuperBiasedMan, Vilmar
71
Entrada, subconjunto 
y salida de archivos 
de datos externos 
utilizando Pandas
Mark Miller
72 Enumerar Andy, Elazar, evuez, Martijn Pieters, techydesigner
73 Errores comunes
abukaj, ADITYA, Alec, Alessandro Trinca Tornidor, Alex, 
Antoine Bolvy, Baaing Cow, Bhargav Rao, Billy, bixel, Charles, 
Cheney, Christophe Roussy, Dartmouth, DeepSpace, DhiaTN, 
Dilettant, fox, Fred Barclay, Gerard Roche, greatwolf, hiro
protagonist, Jeffrey Lin, JGreenwell, Jim Fasarakis Hilliard, 
Lafexlos, maazza, Malt, Mark, matsjoyce, Matt Dodge, MervS, 
MSeifert, ncmathsadist, omgimanerd, Patrick Haugh, pylang, 
RamenChef, Reut Sharabani, Rob Bednark, rrao, SashaZd, 
Shihab Shahriar, Simplans, SuperBiasedMan, Tim D, Tom
Dunbavan, tyteen4a03, user2314737, Will Vousden, Wombatz
74 Escribiendo a CSV 
desde String o List Hriddhi Dey, Thomas Crowley
75 Eventos enviados de 
Python Server Nick Humrich
76 Examen de la unidad
Alireza Savand, Ami Tavory, antimatter15, Arpit Solanki, 
bijancn, Claudiu, Dartmouth, engineercoding, Ffisegydd, J F, 
JGreenwell, jmunsch, joel3000, Kevin Brown, Kinifwyne, Mario
Corchero, Matt Giltaji, Mattew Whitt, mgilson, muddyfish, 
pylang, strpeter
77 Excepciones
Adrian Antunez, Alessandro Trinca Tornidor, Alfe, Andy, 
Benjamin Hodgson, Brian Rodriguez, BusyAnt, Claudiu, driax, 
Elazar, flazzarini, ghostarbeiter, Ilia Barahovski, J F, Marco
Pashkov, muddyfish, noɥʇʎԀʎzɐɹƆ, Paul Weaver, Rahul Nair, 
RamenChef, Shawn Mehan, Shiven, Shkelqim Memolla, 
Simplans, Slickytail, Stephen Leppik, Sudip Bhandari, 
SuperBiasedMan, user2314737
78 Excepciones del 
Commonwealth Juan T, TemporalWolf
    1056/1068
    992
79 Explotación florestal Gal Dreiman, Jörn Hees, sxnwlfkk
80 Exposiciónción Anthony Pham, intboolstring, jtbandes, Luke Taylor, MSeifert, 
Pasha, supersam654
81 Expresiones 
Regulares (Regex)
Aidan, alejosocorro, andandandand, Andy Hayden, ashes999, 
B8vrede, Claudiu, Darth Shadow, driax, Fermi paradox, 
ganesh gadila, goodmami, Jan, Jeffrey Lin, jonrsharpe, Julien
Spronck, Kevin Brown, Md.Sifatul Islam, Michael M.,mnoronha
, Nander Speerstra, nrusch, Or East, orvi, regnarg, 
sarvajeetsuman, Simplans, SN Ravichandran KR, 
SuperBiasedMan, user2314737, zondo
82 Extensiones de 
escritura
Dartmouth, J F, mattgathu, Nathan Osman, techydesigner, 
ygram
83 Fecha y hora
Ajean, alecxe, Andy, Antti Haapala, BusyAnt, Conrad.Dean, 
Elazar, ghostarbeiter, J F, Jeffrey Lin, jonrsharpe, Kevin Brown
, Nicole White, nlsdfnbch, Ohad Eytan, Paul, paulmorriss, 
proprius, RahulHP, RamenChef, sagism, Simplans, Sirajus
Salayhin, Suku, Will
84 Filtrar APerson, cfi, J Atkin, MSeifert, rajah9, SuperBiasedMan
85 Formato de cadena
4444, Aaron Christiansen, Adam_92, ADITYA, Akshit Soota, 
aldanor, alecxe, Alessandro Trinca Tornidor, Andy Hayden, Ani
Menon, B8vrede, Bahrom, Bhargav, Charles, Chris, Darth
Shadow, Dartmouth, Dave J, Delgan, dreftymac, evuez,
Franck Dernoncourt, Gal Dreiman, gerrit, Giannis Spiliopoulos, 
GiantsLoveDeathMetal, goyalankit, Harrison, James Elderfield, 
Jean-Francois T., Jeffrey Lin, jetpack_guy, JL Peyret, joel3000, 
Jonatan, JRodDynamite, Justin, Kevin Brown, knight, krato, 
Marco Pashkov, Mark, Matt, Matt Giltaji, mu , MYGz, Nander
Speerstra, Nathan Arthur, Nour Chawich, orion_tvv, ragesz, 
SashaZd, Serenity, serv-inc, Simplans, Slayther, 
Sometowngeek, SuperBiasedMan, Thomas Gerot, tobias_k, 
Tony Suffolk 66, UloPe, user2314737, user312016, Vin, zondo
86 Formato de fecha surfthecity
87 Función de mapa
APerson, cfi, Igor Raush, Jon Ericson, Karl Knechtel, Marco
Pashkov, MSeifert, noɥʇʎԀʎzɐɹƆ, Parousia, Simplans, 
SuperBiasedMan, tlama, user2314737
88 Funciones
Adriano, Akshat Mahajan, AlexV, Andy, Andy Hayden, Anthony
Pham, Arkady, B8vrede, Benjamin Hodgson, btel, 
CamelBackNotation, Camsbury, Chandan Purohit, 
ChaoticTwist, Charlie H, Chris Larson, Community, D. Alveno, 
danidee, DawnPaladin, Delgan, duan, duckman_1991, elegent
    1057/1068
    993
, Elodin, Emma, EsmaeelE, Ffisegydd, Gal Dreiman, 
ghostarbeiter, Hurkyl, J F, James, Jeffrey Lin, JGreenwell, Jim
Fasarakis Hilliard, jkitchen, Jossie Calderon, Justin, Kevin
Brown, L3viathan, Lee Netherton, Martijn Pieters, Martin
Thurau, Matt Giltaji, Mike - SMT, Mike Driscoll, MSeifert, 
muddyfish, Murphy4, nd., noɥʇʎԀʎzɐɹƆ, Pasha, pylang, pzp, 
Rahul Nair, Severiano Jaramillo Quintanar, Simplans, Slayther, 
Steve Barnes, Steven Maude, SuperBiasedMan, textshell, 
then0rTh, Thomas Gerot, user2314737, user3333708, user405
, Utsav T, vaultah, Veedrac, Will, Will, zxxz, λuser
89 Funciones parciales FrankBr
90 Generadores
2Cubed, Ahsanul Haque, Akshat Mahajan, Andy Hayden, 
Arthur Dent, ArtOfCode, Augustin, Barry, Chankey Pathak, 
Claudiu, CodenameLambda, Community, deeenes, Delgan, 
Devesh Saini, Elazar, ericmarkmartin, Ernir, ForceBru, Igor
Raush, Ilia Barahovski, J0HN, jackskis, Jim Fasarakis Hilliard, 
Juan T, Julius Bullinger, Karl Knechtel, Kevin Brown, Kronen, 
Luc M, Lyndsy Simon, machine yearning, Martijn Pieters, Matt
Giltaji, max, MSeifert, nlsdfnbch, Pasha, Pedro, PsyKzz, pzp, 
satsumas, sevenforce, Signal, Simplans, Slayther, StuxCrystal, 
tversteeg, Valentin Lorentz, Will, William Merrill, xtreak, Zaid
Ajaj, zarak, λuser
91 Gestores de contexto 
(declaración “con”)
Abhijeet Kasurde, Alessandro Trinca Tornidor, Andy Hayden, 
Antoine Bolvy, carrdelling, Conrad.Dean, Dartmouth, David
Marx, DeepSpace, Elazar, Kevin Brown, magu_, Majid, Martijn
Pieters, Matthew, nlsdfnbch, Pasha, Peter Brittain, petrs, Shuo, 
Simplans, SuperBiasedMan, The_Cthulhu_Kid, Thomas Gerot, 
tyteen4a03, user312016, Valentin Lorentz, vaultah, λuser
92 Gráficos de tortuga Luca Van Oort, Stephen Leppik
93 hashlib Mark Omo, xiaoyi
94 Heapq ettanany
95 Herramienta 2to3 Alessandro Trinca Tornidor, Dartmouth, Firix, Kevin Brown, 
Naga2Raja, Stephen Leppik
96 herramienta grafica xiaoyi
97 ijson Prem Narain
98 Implementaciones no 
oficiales de Python Jacques de Hooge, Squidward
99 Importando modulos angussidney, Anthony Pham, Antonis Kalou, Brett Cannon,
    1058/1068
    994
BusyAnt, Casebash, Christian Ternus, Community, 
Conrad.Dean, Daniel, Dartmouth, Esteis, Ffisegydd, FMc, 
Gerard Roche, Gideon Buckwalter, J F, JGreenwell, Kinifwyne, 
languitar, Lex Scarisbrick, Matt Giltaji, MSeifert, niyasc, 
nlsdfnbch, Paulo Freitas, pylang, Rahul Nair, Saiful Azad, 
Serenity, Simplans, StardustGogeta, StuxCrystal, 
SuperBiasedMan, techydesigner, the_cat_lady, Thomas Gerot, 
Tony Meyer, Tushortz, user2683246, Valentin Lorentz, Valor
Naram, vaultah, wnnmaw
100
Incompatibilidades 
que se mueven de 
Python 2 a Python 3
671620616, Abhishek Kumar, Akshit Soota, Alex Gaynor, Allan
Burleson, Alleo, Amarpreet Singh, Andy Hayden, Ani Menon, 
Antoine Bolvy, AntsySysHack, Antti Haapala, Antwan, arekolek
, Ares, asmeurer, B8vrede, Bakuriu, Bharel, Bhargav Rao, 
bignose, bitchaser, Bluethon, Cache Staheli, Cameron Gagnon
, Charles, Charlie H, Chris Sprague, Claudiu, Clayton
Wahlstrom, cʟᴅsᴇᴇᴅ, Colin Yang, Cometsong, Community, 
Conrad.Dean, danidee, Daniel Stradowski, Darth Shadow, 
Dartmouth, Dave J, David Cullen, David Heyman, deeenes, 
DeepSpace, Delgan, DoHe, Duh-Wayne-101, Dunno, 
dwanderson, Ekeyme Mo, Elazar, enderland, enrico.bacis, 
erewok, ericdwang, ericmarkmartin, Ernir, ettanany, 
Everyone_Else, evuez, Franck Dernoncourt, Fred Barclay, 
garg10may, Gavin, geoffspear, ghostarbeiter,GoatsWearHats,
H. Pauwelyn, Haohu Shen, holdenweb, iScrE4m, Iván C., J F,
J. C. Leitão, James Elderfield, James Thiele, jarondl, jedwards,
Jeffrey Lin, JGreenwell, Jim Fasarakis Hilliard, Jimmy Song,
John Slegers, Jojodmo, jonrsharpe, Josh, Juan T, Justin,
Justin M. Ucar, Kabie, kamalbanga, Karl Knechtel, Kevin
Brown, King's jester, Kunal Marwaha, Lafexlos, lenz, linkdd,
l'L'l, Mahdi, Martijn Pieters, Martin Thoma, masnun, Matt, Matt
Dodge, Matt Rowland, Mattew Whitt, Max Feng, mgwilliams,
Michael Recachinas, mkj, mnoronha, Moinuddin Quadri,
muddyfish, Nathaniel Ford, niemmi, niyasc, noɥʇʎԀʎzɐɹƆ,
OrangeTux, Pasha, Paul Weaver, Paulo Freitas, pcurry,
pktangyue, poppie, pylang, python273, Pythonista, RahulHP,
Rakitić, RamenChef, Rauf, René G, rfkortekaas, rrao, Ryan,
sblair, Scott Mermelstein, Selcuk, Serenity, Seth M. Larson,
ShadowRanger, Simplans, Slayther, solarc, sricharan, Steven
Hewitt, sth, SuperBiasedMan, Tadhg McDonald-Jensen,
techydesigner, Thomas Gerot, Tim, tobias_k, Tyler, tyteen4a03
, user2314737, user312016, Valentin Lorentz, Veedrac, Ven, 
Vinayak, Vlad Shcherbina, VPfB, WeizhongTu, Wieland, wim, 
Wolf, Wombatz, xtreak, zarak, zcb, zopieux, zurfyx, zvezda
101 Indexación y corte Alleo, amblina, Antoine Bolvy, Bonifacio2, Ffisegydd, Guy, Igor
Raush, Jonatan, Martec, MSeifert, MUSR, pzp, RahulHP, Reut
    1059/1068
    995
Sharabani, SashaZd, Sayed M Ahamad, SuperBiasedMan, 
theheadofabroom, user2314737, yurib
102
Interfaz de puerta de 
enlace de servidor 
web (WSGI)
David Heyman, Kevin Brown, Preston, techydesigner
103
Introducción a 
RabbitMQ utilizando 
AMQPStorm
eandersson
104 Iterables e iteradores 4444, Conrad.Dean, demonplus, Ilia Barahovski, Pythonista
105
kivy - Framework 
Python 
multiplataforma para 
el desarrollo de NUI
dhimanta
106 La declaración de 
pase
Anaphory
107 La función de 
impresión
Beall619, Frustrated, Justin, Leon Z., lukewrites, 
SuperBiasedMan, Valentin Lorentz
108 La variable especial
name
Annonymous, BusyAnt, Christian Ternus, jonrsharpe, Lutz
Prechelt, Steven Elliott
109 Las clases
Aaron Hall, Ahsanul Haque, Akshat Mahajan, Andrzej Pronobis
, Anthony Pham, Avantol13, Camsbury, cfi, Community, 
Conrad.Dean, Daksh Gupta, Darth Shadow, Dartmouth, 
depperm, Elazar, Ffisegydd, Haris, Igor Raush, InitializeSahib, 
J F, jkdev, jlarsch, John Militer, Jonas S, Jonathan, Kallz, 
KartikKannapur, Kevin Brown, Kinifwyne, Leo, Liteye, 
lmiguelvargasf, Mailerdaimon, Martijn Pieters, Massimiliano
Kraus, Mattew Whitt, MrP01, Nathan Arthur, ojas mohril, 
Pasha, Peter Steele, pistache, Preston, pylang, Richard
Fitzhugh, rohittk239, Rushy Panchal, Sempoo, Simplans, 
Soumendra Kumar Sahoo, SuperBiasedMan, techydesigner, 
then0rTh, Thomas Gerot, Tony Suffolk 66, tox123, UltraBob, 
user2314737, wrwrwr, Yogendra Sharma
110 Lectura y Escritura 
CSV
Adam Matan, Franck Dernoncourt, Martin Valgur, mnoronha, 
ravigadila, Setu
111 Lista
Adriano, Alexander, Anthony Pham, Ares, Barry, blueenvelope, 
Bosoneando, BusyAnt, Çağatay Uslu, caped114, Chandan
Purohit, ChaoticTwist, cizixs, Daniel Porteous, Darth Kotik, 
deeenes, Delgan, Elazar, Ellis, Emma, evuez, exhuma, 
Ffisegydd, Flickerlight, Gal Dreiman, ganesh gadila,
    1060/1068
    996
ghostarbeiter, Igor Raush, intboolstring, J F, j3485, jalanb, 
James, James Elderfield, jani, jimsug, jkdev, JNat, jonrsharpe, 
KartikKannapur, Kevin Brown, Lafexlos, LDP, Leo Thumma, 
Luke Taylor, lukewrites, lxer, Majid, Mechanic, MrP01,MSeifert
, muddyfish, n12312, noɥʇʎԀʎzɐɹƆ, Oz Bar-Shalom, Pasha, 
Pavan Nath, poke, RamenChef, ravigadila, ronrest, Serenity, 
Severiano Jaramillo Quintanar, Shawn Mehan, Simplans, sirin, 
solarc, SuperBiasedMan, textshell, The_Cthulhu_Kid, 
user2314737, user6457549, Utsav T, Valentin Lorentz, vaultah
, Will, wythagoras, Xavier Combelle
112 Lista de 
Comprensiones
3442, Akshit Soota, André Laszlo, Andy Hayden, Annonymous
, Ari, Bhargav, Chris Mueller, Darth Shadow, Dartmouth, 
Delgan, enrico.bacis, Franck Dernoncourt, garg10may, 
intboolstring, Jeff Langemeier, Josh Caswell, JRodDynamite, 
justhalf, kdopen, Ken T, Kevin Brown, kiliantics, longyue0521, 
Martijn Pieters, Mattew Whitt, Moinuddin Quadri, MSeifert, 
muddyfish, noɥʇʎԀʎzɐɹƆ, pktangyue, Pyth0nicPenguin, Rahul
Nair, Riccardo Petraglia, SashaZd, shrishinde, Simplans, 
Slayther, sudo bangbang, theheadofabroom, then0rTh, Tim
McNamara, Udi, Valentin Lorentz, Veedrac, Zags
113
Lista de 
desestructuración 
(también conocido 
como embalaje y 
desembalaje)
J F, sth, zmo
114 Listar comprensiones
3442, 4444, acdr, Ahsanul Haque, Akshay Anand, Akshit
Soota, Alleo, Amir Rachum, André Laszlo, Andy Hayden, Ankit
Kumar Singh, Antoine Bolvy, APerson, Ashwinee K Jha, 
B8vrede, bfontaine, Brian Cline, Brien, Casebash, Celeo, cfi, 
ChaoticTwist, Charles, Charlie H, Chong Tang, Community, 
Conrad.Dean, Dair, Daniel Stradowski, Darth Shadow, 
Dartmouth, David Heyman, Delgan, Dima Tisnek, eenblam, 
Elazar, Emma, enrico.bacis, EOL, ericdwang, ericmarkmartin, 
Esteis, Faiz Halde, Felk, Fermi paradox, Florian Bender, 
Franck Dernoncourt, Fred Barclay, freidrichen, G M, Gal
Dreiman, garg10may, ghostarbeiter, GingerHead, griswolf, 
Hannele, Harry, Hurkyl, IanAuld, iankit, Infinity, intboolstring, J
F, J0HN, James, JamesS, Jamie Rees, jedwards, Jeff
Langemeier, JGreenwell, JHS, jjwatt, JKillian, JNat, joel3000, 
John Slegers, Jon, jonrsharpe, Josh Caswell, JRodDynamite, 
Julian, justhalf, Kamyar Ghasemlou, kdopen, Kevin Brown, 
KIDJourney, Kwarrtz, Lafexlos, lapis, Lee Netherton, Liteye, 
Locane, Lyndsy Simon, machine yearning, Mahdi, Marc, 
Markus Meskanen, Martijn Pieters, Matt, Matt Giltaji, Matt S,
    1061/1068
    997
116 Llama a Python
desde C # Julij Jegorov
115 Listas enlazadas Nemo
117 Maldiciones básicas 
con pitón 4444, Guy, kollery, Vinzee
119 Matemáticas
complejas Adeel Ansari, Bosoneando, bpachev
121 Matrices
multidimensionales boboquack, Buzz, rrao
122 Metaclases
2Cubed, Amir Rachum, Antoine Pinsard, Camsbury, 
Community, driax, Igor Raush, InitializeSahib, Marco Pashkov, 
Martijn Pieters, Mattew Whitt, OozeMeister, Pasha, Paulo
Scardine, RamenChef, Rob Bednark, Simplans, sisanared, 
zvone
123 Método Anulando DeepSpace, James
124 Métodos de cuerda
Amitay Stern, Andy Hayden, Ares, Bhargav Rao, Brien, 
BusyAnt, Cache Staheli, caped114, ChaoticTwist, Charles, 
Dartmouth, David Heyman, depperm, Doug Henderson, Elazar
, ganesh gadila, ghostarbeiter, GoatsWearHats, idjaw, Igor
Raush, Ilia Barahovski, j , Jim Fasarakis Hilliard, JL Peyret, 
Kevin Brown, krato, MarkyPython, Metasomatism, Mikail Land, 
MSeifert, mu , Nathaniel Ford, OliPro007, orvi, pzp, ronrest,
120 Matraz Stephen Leppik, Thomas Gerot
118 Manipulando XML 4444, Brad Larson, Chinmay Hegde, Francisco Guimaraes,
greuze, heyhey2k, Rob Murray
Mattew Whitt, Maximillian Laumeister, mbrig, Mirec Miskuf, 
Mitch Talmadge, Morgan Thrapp, MSeifert, muddyfish, 
n8henrie, Nathan Arthur, nehemiah, noɥʇʎԀʎzɐɹƆ, Or East, 
Ortomala Lokni, pabouk, Panda, Pasha, pktangyue, Preston, 
Pro Q, pylang, R Nar, Rahul Nair, rap-2-h, Riccardo Petraglia, 
rll, Rob Fagen, rrao, Ryan Hilbert, Ryan Smith, ryanyuyu, 
Samuel McKay, sarvajeetsuman, Sayakiss, Sebastian Kreft, 
Shoe, SHOWMEWHATYOUGOT, Simplans, Slayther, 
Slickytail, solidcell, StuxCrystal, sudo bangbang, Sunny Patel,
SuperBiasedMan, syb0rg, Symmitchry, The_Curry_Man, 
theheadofabroom, Thomas Gerot, Tim McNamara, Tom
Barron, user2314737, user2357112, Utsav T, Valentin Lorentz, 
Veedrac, viveksyngh, vog, W.P. McNeill, Will, Will, Wladimir
Palant, Wolf, XCoder Real, yurib, Yury Fedorov, Zags, Zaz
    1062/1068
    998
Shrey Gupta, Simplans, SuperBiasedMan, theheadofabroom, 
user1349663, user2314737, Veedrac, WeizhongTu, wnnmaw
125 Métodos definidos 
por el usuario
Alessandro Trinca Tornidor, Beall619, mnoronha, RamenChef, 
Stephen Leppik, Sun Qingyao
126 Mixins Doc, Rahul Nair, SashaZd
127 Modismos Benjamin Hodgson, Elazar, Faiz Halde, J F, Lee Netherton, 
loading..., Mister Mister
128 Módulo aleatorio
Alex Gaynor, Andrzej Pronobis, Anthony Pham, Community, 
David Robinson, Delgan, giucal, Jim Fasarakis Hilliard, 
michaelrbock, MSeifert, Nobilis, ppperry, RamenChef, 
Simplans, SuperBiasedMan
129 Módulo asyncio
2Cubed, Alessandro Trinca Tornidor, Cimbali, hiro protagonist, 
obust, pylang, RamenChef, Seth M. Larson, Simplans, 
Stephen Leppik, Udi
130 Módulo de cola Prem Narain
131 Módulo de 
colecciones
asmeurer, Community, Elazar, jmunsch, kon psych, Marco
Pashkov, MSeifert, RamenChef, Shawn Mehan, Simplans, 
Steven Maude, Symmitchry, void, XCoder Real
132 Módulo de funciones
Alessandro Trinca Tornidor, enrico.bacis, flamenco, 
RamenChef, Shrey Gupta, Simplans, Stephen Leppik, 
StuxCrystal
133 Módulo de 
matemáticas
Anthony Pham, ArtOfCode, asmeurer, Christofer Ohlsson, Ellis
, fredley, ghostarbeiter, Igor Raush, intboolstring, J F, James
Elderfield, JGreenwell, MSeifert, niyasc, RahulHP, rajah9, 
Simplans, StardustGogeta, SuperBiasedMan, yurib
134 Módulo de 
navegador web Thomas Gerot
135 Módulo Deque Anthony Pham, BusyAnt, matsjoyce, ravigadila, Simplans, 
Thomas Ahle, user2314737
136 Módulo Itertools
ADITYA, Alessandro Trinca Tornidor, Andy Hayden, balki, 
bpachev, Ffisegydd, jackskis, Julien Spronck, Kevin Brown, 
machine yearning, nlsdfnbch, pylang, RahulHP, RamenChef, 
Simplans, Stephen Leppik, Symmitchry, Wickramaranga, 
wnnmaw
137 Módulo JSON Indradhanush Gupta, Leo, Martijn Pieters, pzp, 
theheadofabroom, Underyx, Wolfgang
    1063/1068
    999
138 Módulo operador MSeifert
139 módulo pyautogui Damien, Rednivrug
140 Módulo Sqlite3 Chinmay Hegde, Simplans
141 Multihilo
Alu, cʟᴅsᴇᴇᴅ, juggernaut, Kevin Brown, Kristof,mattgathu, 
Nabeel Ahmed, nlsdfnbch, Rahul, Rahul Nair, Riccardo
Petraglia, Thomas Gerot, Will, Yogendra Sharma
142 Multiprocesamiento Alon Alexander, Nander Speerstra, unutbu, Vinzee, Will
143
Mutable vs Inmutable 
(y Hashable) en 
Python
Cilyan
144 Neo4j y Cypher 
usando Py2Neo Wingston Sharon
145 Nodo de lista 
enlazada orvi
146 Objetos de propiedad
Alessandro Trinca Tornidor, Darth Shadow, DhiaTN, J F, 
Jacques de Hooge, Leo, Martijn Pieters, mnoronha, Priya, 
RamenChef, Stephen Leppik
147 Operadores 
booleanos
boboquack, Brett Cannon, Dair, Ffisegydd, John Zwinck, 
Severiano Jaramillo Quintanar, Steven Maude
148 Operadores de 
Bitwise
Abhishek Jain, boboquack, Charles, Gal Dreiman, intboolstring
, JakeD, JNat, Kevin Brown, Matías Brignone, nemesisfixx, 
poke, R Colmenares, Shawn Mehan, Simplans, Thomas Gerot, 
tmr232, Tony Suffolk 66, viveksyngh
149 Operadores 
matemáticos simples
amin, blueenvelope, Bryce Frank, Camsbury, David, 
DeepSpace, Elazar, J F, James, JGreenwell, Jon Ericson, 
Kevin Brown, Lafexlos, matsjoyce, Mechanic, Milo P, MSeifert, 
numbermaniac, sarvajeetsuman, Simplans, techydesigner, 
Tony Suffolk 66, Undo, user2314737, wythagoras, Zenadix
150 Optimización del 
rendimiento A. Ciclet, RamenChef, user2314737
151 os.path Claudiu, Fábio Perez, girish946, Jmills, Szabolcs Dombi, VJ
Magar
152
Pandas Transform: 
Preforma 
operaciones en 
grupos y concatena
Dee
    1064/1068
    1000
los resultados.
153 Patrones de diseño Charul, denvaar, djaszczurowski
154 Perfilado J F, keiv.fly, SashaZd
155 Persistencia Python RamenChef, user2728397
156 pip: PyPI Package 
Manager
Andy, Arpit Solanki, Community, InitializeSahib, JNat, Mahdi, 
Majid, Matt Giltaji, Nathaniel Ford, Rápli András, SerialDev, 
Simplans, Steve Barnes, StuxCrystal, tlo
157 Plantillas en python 4444, Alessandro Trinca Tornidor, Fred Barclay, RamenChef, 
Ricardo, Stephen Leppik
158 Polimorfismo Benedict Bunting, DeepSpace, depperm, Simplans, 
skrrgwasme, Vinzee
159 PostgreSQL Alessandro Trinca Tornidor, RamenChef, Stephen Leppik, 
user2027202827
160 Precedencia del 
operador
HoverHell, JGreenwell, MathSquared, SashaZd, Shreyash S
Sarnayak
161 Procesos e hilos Claudiu, Thomas Gerot
162 Programación 
Funcional en Python Imran Bughio, mvis89, Rednivrug
163
Programación IoT 
con Python y 
Raspberry PI
dhimanta
164 py.test Andy, Claudiu, Ffisegydd, Kinifwyne, Matt Giltaji
165 pyaudio Biswa_9937
166 pygame Anthony Pham, Aryaman Arora, Pavan Nath
167 Pyglet Comrade SparklePony, Stephen Leppik
168 PyInstaller - Distribuir 
código de Python ChaoticTwist, Eric, mnoronha
169 Python Lex-Yacc cʟᴅsᴇᴇᴅ
170
171
Python Requests 
Post
Python y Excel
Ken Y-N, RandomHash
bee-sting, Chinmay Hegde, GiantsLoveDeathMetal, hackvan, 
Majid, talhasch, user2314737, Will
    1065/1068
    1001
172 Recolección de 
basura
bogdanciobanu, Claudiu, Conrad.Dean, Elazar, FazeL, J F, 
James Elderfield, lukess, muddyfish, Sam Whited, SiggyF, 
Stephen Leppik, SuperBiasedMan, Xavier Combelle
173 Reconocimiento 
óptico de caracteres rassar
174 Recursion Bastian, japborst, JGreenwell, Jossie Calderon, mbomb007, 
SashaZd, Tyler Crompton
175 Redes Python atayenel, ChaoticTwist, David, Geeklhem, mattgathu, 
mnoronha, thsecmaniac
176 Reducir APerson, Igor Raush, Martijn Pieters, MSeifert
177
Representaciones de 
cadena de instancias 
de clase: métodos
 str y repr
Alessandro Trinca Tornidor, jedwards, JelmerS, RamenChef, 
Stephen Leppik
178 Sangría Alessandro Trinca Tornidor, depperm, J F, JGreenwell, Matt
Giltaji, Pasha, RamenChef, Stephen Leppik
179 Seguridad y 
criptografía
adeora, ArtOfCode, BSL-5, Kevin Brown, matsjoyce, 
SuperBiasedMan, Thomas Gerot, Wladimir Palant, wrwrwr
180 Serialización de 
datos Devesh Saini, Infinity, rfkortekaas
181 Serialización de 
datos de salmuera J F, Majid, Or East, RahulHP, rfkortekaas, zvone
182 Servidor HTTP de 
Python
Arpit Solanki, J F, jmunsch, Justin Chadwell, Mark, MervS, orvi
, quantummind, Raghav, RamenChef, Sachin Kalkur, Simplans
, techydesigner
183 setup.py Adam Brenecki, amblina, JNat, ravigadila, strpeter, 
user2027202827, Y0da
184
Similitudes en la 
sintaxis, diferencias 
en el significado: 
Python vs. JavaScript
user2683246
185 Sobrecarga
Andy Hayden, Darth Shadow, ericmarkmartin, Ffisegydd, Igor
Raush, Jonas S, jonrsharpe, L3viathan, Majid, RamenChef, 
Simplans, Valentin Lorentz
186 Sockets y cifrado / 
descifrado de Mohammad Julfikar
    1066/1068
    1002
mensajes entre el 
cliente y el servidor
187
Subcomandos CLI 
con salida de ayuda 
precisa
Alessandro Trinca Tornidor, anatoly techtonik, Darth Shadow
188 sys blubberdiblub
189 tempfile 
NamedTemporaryFile
Alessandro Trinca Tornidor, amblina, Kevin Brown, Stephen
Leppik
190 Tipo de sugerencias
alecxe, Annonymous, Antti Haapala, Elazar, Jim Fasarakis
Hilliard, Jonatan, RamenChef, Seth M. Larson, Simplans, 
Stephen Leppik
191 Tipos de datos de 
Python Gavin, lorenzofeliz, Pike D., Rednivrug
Tipos de datos
192 inmutables (int, float,
str, tuple y
Alessandro Trinca Tornidor, FazeL, Ganesh K, RamenChef,
Stephen Leppik
frozensets)
193 tkinter Dartmouth, rlee827, Thomas Gerot, TidB
194
Trabajando alrededor 
del bloqueo global de 
intérpretes (GIL)
Scott Mermelstein
195 Trabajando con 
archivos ZIP Chinmay Hegde, ghostarbeiter, Jeffrey Lin, SuperBiasedMan
196 Trazado con 
matplotlib Arun, user2314737
197 Tupla
Anthony Pham, Antoine Bolvy, BusyAnt, Community, Elazar, 
James, Jim Fasarakis Hilliard, Joab Mendes, Majid, Md.Sifatul
Islam, Mechanic, mezzode, nlsdfnbch, noɥʇʎԀʎzɐɹƆ, Selcuk, 
Simplans, textshell, tobias_k, Tony Suffolk 66, user2314737
198 Unicode wim
199 Unicode y bytes Claudiu, KeyWeeUsr
200 urllib Amitay Stern, ravigadila, sth, Will
201 Usando bucles 
dentro de funciones naren
    1067/1068
    1003
202
Uso del módulo "pip": 
PyPI Package 
Manager
Zydnar
203 Velocidad de Python 
del programa. ADITYA, Antonio, Elodin, Neil A., Vinzee
204 Visualización de 
datos con Python
Aquib Javed Khan, Arun, ChaoticTwist, cledoux, Ffisegydd, 
ifma
205 Web raspado con 
Python
alecxe, Amitay Stern, jmunsch, mrtuovinen, Ni., RamenChef, 
Saiful Azad, Saqib Shamsi, Simplans, Steven Maude, sth, 
sytech, talhasch, Thomas Gerot
206 Websockets 2Cubed, Stephen Leppik, Tyler Gubala
    1068/1068

    Aprende todo sobre Python

    • 2. Descubre como llevar tu carrera de programación al siguiente nivel y conviértete en ese programador que todos quieren ser QUIERO LEERLO HOY MISMO GUIA PARA PROGRAMADORES: Lo que nadie te cuenta ni siquiera tu profesor de programación Descárgalo ahora dando click al siguiente botón
    • 3. Tabla de contenido Acerca de 1 Capítulo1:Empezando conPython Language 2 Observaciones 2 Versiones 3 Python 3.x 3 Python 2.x 3 Examples 4 Empezando 4 Verificar si Python está instalado 4 Hola, MundoenPythonusando IDLE 5 Hola archivo de World Python 5 Ejecutar un shell interactivo de Python 6 Otras conchas enlínea 7 Ejecutar comandos como una cadena 8 Conchas ymas alla 8 Creando variables y asignando valores. 8 Entrada del usuario 13
    • 4. IDLE - GUI de Python 14 Solución de problemas 14 Tipos de datos 15 Tipos incorporados 15 Booleanos 15 Números 16 Instrumentos de cuerda 16 Secuencias y colecciones. 17 Constantes incorporadas 17 Probandoeltipodevariables 18 Convertirentretiposdedatos 19 Tipodecadenaexplícitaenladefiniciónde literales 19
    • 5. Tiposdedatosmutableseinmutables 19 Construido en módulos y funciones 20 Sangría de bloque 24 Espaciosvs.Pestañas 25 Tipos de colección 26 Utilidad de ayuda 31 Creando un modulo 32 Función de cadena - str () y repr () 33 repr () 33 str () 33 Instalación de módulos externos utilizando pip 34 Encontrar/instalarunpaquete 35 Actualización depaquetes instalados 35 Actualización de pip 35 Instalación de Python 2.7.xy 3.x 36 Capítulo 2:* args y ** kwargs 39 Observaciones 39 h11 39 h12 39 h13 39 Examples 40 Usando * args al escribir funciones 40 Usando ** kwargs al escribir funciones 40 Usando * args al llamar a funciones 41 Usando ** kwargs al llamar a funciones 42 Usando * args al llamar a funciones 42 Argumentos solo de palabra clave y requeridos de palabra clave 43 Poblando los valores kwarg con un diccionario 43 ** kwargs y valores por defecto 43 Capítulo 3: Acceso a labasede datos 44 Observaciones 44 Examples 44
    • 6. Accediendo a la base de datos MySQL usando MySQLdb 44 SQLite 45 La sintaxis de SQLite: un análisis en profundidad 46 Empezando 46 h21 46 Atributos importantes y funciones de Connection 47 Funciones importantes del Cursor 47 Tipos de datos SQLite y Python 51 Acceso a la base de datos PostgreSQL usando psycopg2 51 Estableciendo una conexión a la base de datos y creando una tabla. 51 Insertando datos en la tabla: 52 Recuperando datos de la tabla: 52 Base de datos Oracle 52 Conexión 54 Usando sqlalchemy 55 Capítulo4:Accesoalcódigofuenteycódigodebytes dePython 56 Examples 56 Mostrar el bytecode de una función 56 Explorando el código objeto de una función. 56 Mostrar el código fuente de un objeto. 56 Objetos que no están incorporados 56 Objetos definidos interactivamente. 57 Objetos incorporados 57 Capítulo5:Accesodeatributo 59 Sintaxis 59 Examples 59 Acceso a atributos básicos utilizando la notación de puntos 59 Setters, Getters & Properties 59 Capítulo6:agruparpor() 62 Introducción 62 Sintaxis 62 Parámetros 62
    • 7. Observaciones 62 Examples 62 Ejemplo 1 62 Ejemplo 2 63 Ejemplo 3 64 Ejemplo 4 65 Capítulo 7: Alcance variable y vinculante 67 Sintaxis 67 Examples 67 Variables globales 67 Variables locales 68 Variables no locales 69 Ocurrencia vinculante 69 Las funciones omiten el alcance de la clase al buscar nombres 70 El comando del 71 del v 71 del v.name 71 del v[item] 71 del v[a:b] 72 Ámbito local vs global 72 ¿Cuálessonelalcance local yglobal? 72 ¿Qué pasa con los choques de nombre? 73 Funciones dentrode funciones 73 globalvsnonlocal(soloPython3) 74 Capítulo8:Almohada 76 Examples 76 Leer archivo de imagen 76 Convertir archivos a JPEG 76 Capítulo 9: Alternativas para cambiarla declaración de otros idiomas 77 Observaciones 77 Examples 77 Usa lo que el lenguaje ofrece: la construcción if / else. 77
    • 8. Usa un dictado de funciones. 78 Usa la introspección de clase. 78 Usando un administrador de contexto 79 Capítulo 10: Ambiente Virtual Python - virtualenv 81 Introducción 81 Examples 81 Instalación 81 Uso 81 Instala un paquete en tu Virtualenv 82 Otros comandos virtuales útiles 82 Capítulo11:Análisisdeargumentosdelíneadecomandos 83 Introducción 83 Examples 83 Hola mundo en argparse 83 Ejemplo básico con docopt. 84 Estableciendo argumentos mutuamente excluyentes con argparse 84 Usando argumentos de línea de comando con argv 85 Mensaje de error del analizador personalizado con argparse 86 Agrupación conceptual de argumentos con argparse.add_argument_group () 86 Ejemplo avanzado con docopt y docopt_dispatch 88 Capítulo 12: Análisis deHTML 89 Examples 89 Localiza un texto después de un elemento en BeautifulSoup. 89 Usando selectores de CSS en BeautifulSoup 89 PyQuery 90 Capítulo 13: Anti-patrones de Python 91 Examples 91 Con exceso de celo excepto la cláusula 91 Mirando antes de saltar con la función de procesador intensivo 92 Claves del diccionario 92 Capítulo14: Apilar 94 Introducción 94 Sintaxis 94
    • 9. Observaciones 94 Examples 94 Creación de una clase de pila con un objeto de lista 94 Paréntesis de paréntesis 96 Capítulo 15: Árbol de sintaxis abstracta 97 Examples 97 Analizar funciones en un script de python 97 Capítulo 16: Archivos ycarpetas I/ O 99 Introducción 99 Sintaxis 99 Parámetros 99 Observaciones 99 Evitarelinfierno decodificación multiplataforma 99 Examples 100 Modos de archivo 100 Leyendo un archivo línea por línea 102 Obtener el contenido completo de un archivo 103 Escribiendo en un archivo 103 Copiando los contenidos de un archivo a un archivo diferente 104 Compruebe si existe un archivo o ruta 104 Copiar un árbol de directorios 105 Iterar archivos (recursivamente) 105 Leer un archivo entre un rango de líneas. 106 Acceso aleatorio a archivos usando mmap 106 Reemplazo de texto en un archivo 107 Comprobando si un archivo está vacío 107 Capítulo 17: ArcPy 108 Observaciones 108 Examples 108 Impresión del valor de un campo para todas las filas de la clase de entidad en la geodatab 108 createDissolvedGDB para crear un archivo gdb en el área de trabajo 108 Capítulo18: Arrays 109
    • 10. Introducción 109 Parámetros 109 Examples 109 Introducción básica a las matrices 109 Accede a elementos individuales a través de índices. 110 Agregue cualquier valor a la matriz usando el método append () 111 Insertar valor en una matriz usando el método insert () 111 Extiende la matriz de python usando el método extend () 111 Agregue elementos de la lista a la matriz usando el método fromlist () 111 Elimine cualquier elemento del arreglo usando el método remove () 111 Eliminar el último elemento de la matriz utilizando el método pop () 112 Obtenga cualquier elemento a través de su índice usando el método index () 112 Invertir una matriz de python usando el método reverse () 112 Obtener información de búfer de matriz a través del método buffer_info () 112 Compruebe el número de apariciones de un elemento utilizando el método count () 113 Convierte una matriz en una cadena usando el método tostring () 113 Convierta la matriz a una lista de python con los mismos elementos utilizando el método to 113 Agregue una cadena a la matriz de caracteres utilizando el método fromstring () 113 Capítulo 19: Audio 114 Examples 114 Audio con pyglet 114 Trabajando con archivos WAV 114 WinSound 114 ola 114 Convierte cualquier archivo de sonido con python y ffmpeg 115 Tocando los pitidos de Windows 115 Capítulo 20: Aumentar errores / excepciones personalizados 116 Introducción 116 Excepción personalizada 116 Atrapar Excepción personalizada 116 Capítulo 21: Bibliotecade subproceso 118 Sintaxis 118 Parámetros 118
    • 11. Examples 118 Llamando Comandos Externos 118 Más flexibilidad con Popen 119 Lanzarunsubproceso 119 Esperando en unsubproceso para completar 119 Salidadelecturadeunsubproceso 119 Accesointeractivo a subprocesos enejecución. 119 Escribiendo a un subproceso 119 Leyendo un stream desde un subproceso 120 Cómo crear el argumento de la lista de comandos 120 Capítulo 22: Bloques de código, marcos de ejecución y espacios de nombres. 122 Introducción 122 Examples 122 Espacios de nombres de bloque de código 122 Capítulo23: Bucles 124 Introducción 124 Sintaxis 124 Parámetros 124 Examples 124 Iterando sobre listas 124 Para bucles 125 Objetos iterablese iteradores. 126 Romper y continuar en bucles 126 declaracióndebreak 126 continue declaración 127 Bucles anidados 128 Usa el return desde dentro de una función como un break 128 Bucles con una cláusula "else" 129 ¿Por qué uno usaría esta construcción extraña? 130 Iterando sobre los diccionarios 131 Mientras bucle 132
    • 12. La Declaración de Pase 133 Iterando diferentes partes de una lista con diferentes tamaños de paso 133 Iteraciónsobre toda lalista. 134 Iterar sobre la sub-lista 134 El "half loop" do-while 135 Bucle y desembalaje 135 Capítulo24:buscando 137 Observaciones 137 Examples 137 Obtención del índice para cadenas: str.index (), str.rindex () y str.find (), str.rfind () 137 Buscando un elemento 137 Lista 138 Tupla 138 Cuerda 138 Conjunto 138 Dictado 138 Obtención de la lista de índice y las tuplas: list.index (), tuple.index () 138 Buscando clave (s) para un valor en dict 139 Obtención del índice para secuencias ordenadas: bisect.bisect_left () 140 Buscando secuencias anidadas 140 Búsqueda en clases personalizadas: contains y iter 141 Capítulo 25: Características ocultas 143 Examples 143 Sobrecarga del operador 143 Capítulo 26: ChemPy-paquetedepython 145 Introducción 145 Fórmulas de análisis 145 Equilibrio de la estequiometría de una reacción química. 145 Reacciones de equilibrio 145 Equilibrios quimicos 146 Fuerza iónica 146 Cinética química (sistema de ecuaciones diferenciales ordinarias) 146 Capítulo27:Clasesbase abstractas(abc) 148
    • 13. Examples 148 Configuración de la metaclase ABCMeta 148 Por qué / Cómo usar ABCMeta y @abstractmethod 149 Capítulo 28: Clasificación, mínimo y máximo 151 Examples 151 Obteniendo el mínimo o máximo de varios valores. 151 Usando el argumento clave 151 Argumento predeterminado a max, min 151 Caso especial: diccionarios 152 Por valor 152 Obteniendo una secuencia ordenada 153 Mínimo y máximo de una secuencia. 153 Hacer clases personalizables ordenable 154 Extraer N artículos más grandes o N más pequeños de un iterable 156 Capítulo 29: Comentarios y Documentación 158 Sintaxis 158 Observaciones 158 Examples 158 Comentarios de línea única, en línea y multilínea. 158 Accediendo programáticamente a las cadenas de documentación 159 Una función de ejemplo 159 Otra función de ejemplo 159 Ventajas de docstrings sobre comentarios regulares 160 Escribir documentación utilizando cadenas de documentación. 160 Convenciones de sintaxis 160 PEP 257 160 Esfinge 161 Guía de estilo de Google Python 162 Capítulo 30: Comparaciones 163 Sintaxis 163 Parámetros 163 Examples 163
    • 14. Mayor o menor que 163 No igual a 164 Igual a 164 Comparaciones de cadena 165 Estilo 165 Efectos secundarios 165 Comparación por `is` vs` == ` 166 Comparando objetos 167 Common Gotcha: Python no impone la escritura 168 Capítulo 31: Complementos y clases de extensión 169 Examples 169 Mixins 169 Plugins con clases personalizadas 170 Capítulo 32: Comprobando la existencia de ruta y permisos 172 Parámetros 172 Examples 172 Realizar comprobaciones utilizando os.access 172 Capítulo 33:Computación paralela 174 Observaciones 174 Examples 174 Uso del módulo multiprocesamiento para paralelizar tareas. 174 Usando scripts de Padres e Hijos para ejecutar código en paralelo 174 Usando una extensión C para paralelizar tareas 175 Usando el módulo PyPar para paralelizar 175 Capítulo 34: Comunicación Serial Python (pyserial) 177 Sintaxis 177 Parámetros 177 Observaciones 177 Examples 177 Inicializar dispositivo serie 177 Leer del puerto serial 177 Compruebe qué puertos serie están disponibles en su máquina 178
    • 15. Capítulo 35: Concurrencia de Python 179 Observaciones 179 Examples 179 El módulo de enhebrado. 179 El módulo multiprocesamiento. 179 Transferencia de datos entre procesos de multiprocesamiento. 180 Capítulo 36: Condicionales 183 Introducción 183 Sintaxis 183 Examples 183 si, elif, y si no 183 Expresión condicional (o "El operador ternario") 183 Si declaración 184 Otra declaración 184 Expresiones lógicas booleanas 185 Yoperador 185 O operador 185 Evaluación perezosa 185 Pruebas paracondiciones múltiples 186 Valores de verdad 187 Usando la función cmp para obtener el resultado de comparación de dos objetos 187 Evaluación de expresiones condicionales usando listas de comprensión 188 Probar si un objeto es Ninguno y asignarlo 189 Capítulo37:ConectandoPythonaSQLServer 190 Examples 190 Conectar al servidor, crear tabla, consultar datos 190 Capítulo 38: ConexiónseguradeshellenPython 192 Parámetros 192 Examples 192 conexión ssh 192 Capítulo 39: configparser 193
    • 16. Introducción 193 Sintaxis 193 Observaciones 193 Examples 193 Uso básico 193 Creando programáticamente el archivo de configuración. 194 Capítulo40:Conjunto 195 Sintaxis 195 Observaciones 195 Examples 195 Consigue los elementos únicos de una lista. 195 Operaciones en sets 196 Conjuntos versus multisets 197 Establecer operaciones usando métodos e incorporaciones 198 Intersección 198 Unión 198 Diferencia 198 Diferencia simétrica 198 Subconjuntoysuperconjunto 199 Conjuntos desunidos 199 Membresía de prueba 200 Longitud 200 Conjunto de conjuntos 200 Capítulo41:Contando 201 Examples 201 Contando todas las apariciones de todos los elementos en un iterable: colecciones.Contador 201 Obtención del valor más común (-s): collections.Counter.most_common () 201 Contando las ocurrencias de un elemento en una secuencia: list.count () y tuple.count () 202 Contando las ocurrencias de una subcadena en una cadena: str.count () 202 Contando ocurrencias en matriz numpy 202 Capítulo42:Copiandodatos 204
    • 17. Examples 204 Realizando una copia superficial 204 Realizando una copia profunda 204 Realizando una copia superficial de una lista 204 Copiar un diccionario 204 Copiar un conjunto 205 Capítulo43: Cortede listas(seleccióndepartes de listas) 206 Sintaxis 206 Observaciones 206 Examples 206 Usando el tercer argumento del "paso" 206 Seleccionando una lista secundaria de una lista 206 Invertir una lista con rebanar 207 Desplazando una lista usando rebanar 207 Capítulo44:CreandopaquetesdePython 209 Observaciones 209 Examples 209 Introducción 209 Subiendo a PyPI 210 Configurar unarchivo .pypirc 210 Registrarse y subir a testpypi (opcional) 210 Pruebas 211 Registrarse ysubir aPyPI 211 Documentación 211 Readme 212 Licenciamiento 212 Haciendo paquete ejecutable 212 Capítulo 45: Creando unservicio de Windows usando Python 214 Introducción 214 Examples 214 Un script de Python que se puede ejecutar como un servicio 214
    • 18. Ejecutando una aplicación web de Flask como un servicio 215 Capítulo 46: Crear entorno virtual con virtualenvwrapper en windows 217 Examples 217 Entorno virtual con virtualenvwrapper para windows 217 Capítulo 47:ctypes 219 Introducción 219 Examples 219 Uso básico 219 Errores comunes 219 Nocargarunarchivo 219 No acceder auna función 220 Objeto de ctypes básico 220 arrays de ctypes 221 Funciones de envoltura para ctypes. 222 Uso complejo 222 Capítulo48:Datosbinarios 224 Sintaxis 224 Examples 224 Formatear una lista de valores en un objeto byte 224 Desempaquetar un objeto byte de acuerdo con una cadena de formato 224 Embalaje de una estructura 224 Capítulo49:Decoradores 226 Introducción 226 Sintaxis 226 Parámetros 226 Examples 226 Función decoradora 226 Clase de decorador 227 Métodosdedecoración 228 ¡Advertencia! 229 Hacer que un decorador se vea como la función decorada. 229 Comounafunción 229
    • 19. Como una clase 230 Decorador con argumentos (decorador de fábrica). 230 Funciones de decorador 230 Nota IMPORTANTE: 231 Clasesdedecorador 231 Crea una clase de singleton con un decorador. 231 Usando un decorador para cronometrar una función. 232 Capítulo 50: Definiendo funciones con argumentos de lista 233 Examples 233 Función y Llamada 233 Capítulo 51: dejarde lado 234 Introducción 234 Observaciones 234 Advertencia: 234 Restricciones 234 Examples 234 Código de muestra para estantería 235 Para resumir la interfaz (la clave es una cadena, los datos son un objeto arbitrario): 235 Creando un nuevo estante 235 Respóndeme 236 Capítulo52:Depuración 239 Examples 239 El depurador de Python: depuración paso a paso con _pdb_ 239 A través de IPython y ipdb 241 Depurador remoto 241 Capítulo 53:Descomprimir archivos 243 Introducción 243 Examples 243 Usando Python ZipFile.extractall () para descomprimir un archivo ZIP 243 Usando Python TarFile.extractall () para descomprimir un tarball 243 Capítulo54:Descriptor 244 Examples 244
    • 20. Descriptor simple 244 Conversiones bidireccionales 245 Capítulo 55: Despliegue 247 Examples 247 Cargando un paquete Conda 247 Capítulo 56: Diccionario 249 Sintaxis 249 Parámetros 249 Observaciones 249 Examples 249 Accediendo a los valores de un diccionario. 249 El constructor dict () 250 Evitar las excepciones de KeyError 250 Acceso a claves y valores. 251 Introducción al Diccionario 252 creando undict 252 sintaxis literal 252 comprensión de dictado 252 clase incorporada: dict() 252 modificando un dict 253 Diccionario con valores por defecto 253 Creando un diccionario ordenado 254 Desempaquetando diccionarios usando el operador ** 254 Fusionando diccionarios 255 Python 3.5+ 255 Python 3.3+ 255 Python 2.x, 3.x 255 La coma final 256 Todas las combinaciones de valores de diccionario. 256 Iterando sobre un diccionario 256 Creando un diccionario 257 Diccionarios ejemplo 258
    • 21. Capítulo57:DiferenciaentreMóduloyPaquete 259 Observaciones 259 Examples 259 Módulos 259 Paquetes 259 Capítulo 58: Distribución 261 Examples 261 py2app 261 cx_Freeze 262 Capítulo 59: Django 264 Introducción 264 Examples 264 Hola mundo con django 264 Capítulo60:Ejecucióndecódigodinámicocon`exec`y` eval` 266 Sintaxis 266 Parámetros 266 Observaciones 266 Examples 267 Evaluando declaraciones con exec 267 Evaluando una expresión con eval 267 Precompilando una expresión para evaluarla varias veces. 267 Evaluar una expresión con eval utilizando globales personalizados 267 Evaluar una cadena que contiene un literal de Python con ast.literal_eval 268 Código de ejecución proporcionado por un usuario no confiable que utiliza exec, eval o ast 268 Capítulo 61:Eldismódulo 269 Examples 269 Constantes en el módulo dis 269 ¿Qué es el código de bytes de Python? 269 Desmontaje de módulos. 269 Capítulo62:Elintérprete(consoladelíneadecomandos) 271 Examples 271 Obtención de ayuda general 271
    • 22. Refiriéndose a la última expresión. 271 Abriendo la consola de Python 272 La variable PYTHONSTARTUP 272 Argumentos de línea de comando 272 Obteniendo ayuda sobre un objeto 273 Capítulo 63:El módulobase64 275 Introducción 275 Sintaxis 275 Parámetros 275 Observaciones 277 Examples 277 Codificación y decodificación Base64 277 Codificación y decodificación Base32 279 Codificación y decodificación Base16 279 Codificación y decodificación ASCII85 280 Codificación y decodificación Base85 280 Capítulo 64: El módulo de configuración regional 282 Observaciones 282 Examples 282 Formato de moneda Dólares estadounidenses utilizando el módulo de configuración regional 282 Capítulo 65:Elmóduloos 283 Introducción 283 Sintaxis 283 Parámetros 283 Examples 283 Crear un directorio 283 Obtener directorio actual 283 Determinar el nombre del sistema operativo. 283 Eliminar un directorio 284 Seguir un enlace simbólico (POSIX) 284 Cambiar permisos en un archivo 284 makedirs - creación de directorio recursivo 284 Capítulo 66:Empezando conGZip 286
    • 23. Introducción 286 Examples 286 Lee y escribe archivos zip de GNU 286 Capítulo67:Enchufes 287 Introducción 287 Parámetros 287 Examples 287 Envío de datos a través de UDP 287 Recepción de datos a través de UDP 287 Envío de datos a través de TCP 288 Servidor de socket TCP multihilo 289 Raw Sockets en Linux 290 Capítulo68:entorno virtualconvirtualenvwrapper 292 Introducción 292 Examples 292 Crear entorno virtual con virtualenvwrapper 292 Capítulo 69:Entornos virtuales 294 Introducción 294 Observaciones 294 Examples 294 Creando y utilizando un entorno virtual. 294 Instalando laherramienta virtualenv 294 Creando unnuevoentorno virtual. 294 Activando unentorno virtual existente 295 Guardar y restaurar dependencias. 295 Salirdeunentornovirtual. 296 Usando un entorno virtual en un host compartido 296 Entornosvirtualesincorporados 296 Instalación de paquetes en un entorno virtual 297 Creando un entorno virtual para una versión diferente de python 298 Gestionar múltiples entornos virtuales con virtualenvwrapper 298 Instalación 298
    • 24. Uso 299 Directorios de proyectos 299 Descubrir qué entorno virtual está utilizando 300 Especificando la versión específica de Python para usar en el script en Unix / Linux 300 Usando virtualenv con cáscara de pescado 301 Realización de entornos virtuales utilizando Anaconda. 301 Crear un entorno 302 Activa y desactiva tu entorno. 302 Ver una lista de entornos creados. 302 Eliminar un entorno 302 Comprobando si se ejecuta dentro de un entorno virtual 302 Capítulo70:Entrada ysalida básica 304 Examples 304 Usando input () y raw_input () 304 Usando la función de impresión 304 Función para pedir al usuario un número 305 Imprimir una cadena sin una nueva línea al final 305 Leer de stdin 306 Entrada desde un archivo 306 Capítulo 71: Entrada, subconjunto y salida de archivos de datos externos utilizando Pandas 309 Introducción 309 Examples 309 Código básico para importar, subcontratar y escribir archivos de datos externos mediante P 309 Capítulo72:Enumerar 311 Observaciones 311 Examples 311 Creación de una enumeración (Python 2.4 a 3.3) 311 Iteración 311 Capítulo73:Errorescomunes 312 Introducción 312 Examples 312 Cambiando la secuencia sobre la que estás iterando 312 Argumento predeterminado mutable 315
    • 25. Lista de multiplicación y referencias comunes. 316 Identidad entera y de cadena 320 Accediendo a los atributos de int literals. 321 Encadenamiento de u operador 322 sys.argv [0] es el nombre del archivo que se está ejecutando 323 h14 323 Los diccionarios están desordenados. 323 Bloqueo global de intérprete (GIL) y bloqueo de hilos 324 Fugas variables en listas de comprensión y para bucles. 325 Retorno múltiple 326 Teclas JSON pitónicas 326 Capítulo74:EscribiendoaCSVdesdeStringoList 328 Introducción 328 Parámetros 328 Observaciones 328 Examples 328 Ejemplo básico de escritura 328 Anexando una cadena como nueva línea en un archivo CSV 329 Capítulo75:EventosenviadosdePythonServer 330 Introducción 330 Examples 330 Frasco SSE 330 Asyncio SSE 330 Capítulo 76: Examen de launidad 331 Observaciones 331 Examples 331 Pruebas de excepciones 331 Funciones de simulación con unittest.mock.create_autospec 332 Configuración de prueba y desmontaje dentro de un unittest.TestCase 333 Afirmación de excepciones 334 Eligiendo aserciones dentro de unitests 335 Pruebas unitarias con pytest 336
    • 26. Capítulo77:Excepciones 340 Introducción 340 Sintaxis 340 Examples 340 Levantando excepciones 340 Atrapar excepciones 340 Ejecutando código de limpieza con finalmente 341 Re-elevando excepciones 341 Cadena de excepciones con aumento de 342 Jerarquía de excepciones 342 Las excepciones son objetos también 345 Creación de tipos de excepción personalizados 345 No atrapes todo! 346 Atrapando múltiples excepciones 347 Ejemplos prácticos de manejo de excepciones. 347 Entradadelusuario 347 Los diccionarios 348 Más 348 Capítulo 78: Excepciones del Commonwealth 350 Introducción 350 Examples 350 IndentationErrors (o indentation SyntaxErrors) 350 IndentationError/SyntaxError: sangría inesperada 350 Ejemplo 350 IndentationError/SyntaxError: unindent no coincide con ningún nivel de sangría externa 351 Ejemplo 351 Error Tabulación: Se esperaba un bloque tabulado 351 Ejemplo 351 IndentationError: usoincoherente de tabulaciones y espacios en sangría 351 Ejemplo 352 Cómo evitar este error 352 TypeErrors 352
    • 27. TypeError:[definición /método]toma? argumentos posicionales pero? se le dio 352 Ejemplo 352 TypeError: tipo (s) de operando nocompatibles para [operando]: '???' y '???' 353 Ejemplo 353 Error de tecleado: '???' El objeto noes iterable / subscriptible: 353 Ejemplo 353 Errordetecleado:'???' elobjeto noesllamable 354 Ejemplo 354 NameError: name '???' no está definido 354 Simplemente no está definido en ninguna parte en el código 354 Tal vez se define más adelante: 354 O no fue import 355 Los alcances de Python y la Regla LEGB: 355 Otros errores 355 AssertError 355 Teclado interrumpir 356 ZeroDivisionError 356 Error de sintaxis en buen código 357 Capítulo 79:Explotación florestal 358 Examples 358 Introducción al registro de Python 358 Excepciones de registro 359 Capítulo80:Exposiciónción 362 Sintaxis 362 Examples 362 Raíz cuadrada: math.sqrt () y cmath.sqrt 362 Exposiciónción utilizando builtins: ** y pow () 363 Exposiciónción utilizando el módulo matemático: math.pow () 363 Función exponencial: math.exp () y cmath.exp () 364 Función exponencial menos 1: math.expm1 () 364 Métodos mágicos y exponenciales: incorporados, matemáticos y matemáticos. 365 Exponenciación modular: pow () con 3 argumentos. 366
    • 28. Raíces: raíz nth con exponentes fraccionarios 367 Cálculo de grandes raíces enteras 367 Capítulo 81: Expresiones Regulares (Regex) 369 Introducción 369 Sintaxis 369 Examples 369 Coincidiendo con el comienzo de una cadena 369 buscando 371 Agrupamiento 371 Grupos nombrados 372 Grupos no capturadores 372 Escapar de personajes especiales 373 Reemplazo 373 Reemplazo de cuerdas 373 Usandoreferenciasdegrupo 373 Usandounafuncióndereemplazo 374 Encontrar todos los partidos no superpuestos 374 Patrones precompilados 374 Comprobación de caracteres permitidos 375 Dividir una cadena usando expresiones regulares 375 Banderas 376 Bandera de palabras clave 376 Banderas en linea 376 Iterando sobre los partidos usando `re.finditer` 377 Unir una expresión solo en lugares específicos 377 Capítulo 82: Extensiones de escritura 379 Examples 379 Hola mundo con extensión C 379 Pasando un archivo abierto a C Extensions 380 Extensión C usando c ++ y Boost 380 Código C ++ 380
    • 29. Capítulo 83: Fecha yhora 383 Observaciones 383 Examples 383 Análisis de una cadena en un objeto de fecha y hora compatible con la zona horaria 383 Aritmética de fecha simple 383 Uso básico de objetos datetime 384 Iterar sobre fechas 384 Analizar una cadena con un nombre de zona horaria corto en un objeto de fecha y hora con f 385 Construyendo tiempos de datos conscientes de la zona horaria 386 Análisis de fecha y hora difuso (extracción de fecha y hora de un texto) 388 Cambio entre zonas horarias 388 Análisis de una marca de tiempo ISO 8601 arbitraria con bibliotecas mínimas 389 Convertir la marca de tiempo a datetime 389 Restar meses de una fecha con precisión 390 Calcular las diferencias de tiempo 390 Obtener una marca de tiempo ISO 8601 391 Sin zona horaria,con microsegundos. 391 Con zona horaria,con microsegundos. 391 Con zona horaria,sin microsegundos. 391 Capítulo84:Filtrar 392 Sintaxis 392 Parámetros 392 Observaciones 392 Examples 392 Uso básico del filtro. 392 Filtro sin función 393 Filtrar como comprobación de cortocircuito. 393 Función complementaria: filterfalse, ifilterfalse 394 Capítulo 85:Formato de cadena 396 Introducción 396 Sintaxis 396 Observaciones 396
    • 30. Examples 396 Conceptos básicos de formato de cadena 396 Alineación y relleno. 398 Formato literales (f-string) 398 Formato de cadena con fecha y hora 399 Formato utilizando Getitem y Getattr 400 Formato flotante 400 Formato de valores numéricos 401 Formato personalizado para una clase 402 Formateo anidado 403 Acolchado y cuerdas truncantes, combinadas. 403 Marcadores de posición nombrados 404 Usando un diccionario (Python 2.x) 404 Usando un diccionario (Python 3.2+) 404 Sin un diccionario: 404 Capítulo 86:Formatode fecha 405 Examples 405 Tiempo entre dos fechas 405 Analizando la cadena al objeto datetime 405 Salida de objetos de fecha y hora a cadena 405 Capítulo 87:Función demapa 406 Sintaxis 406 Parámetros 406 Observaciones 406 Examples 406 Uso básico de map, itertools.imap y future_builtins.map 406 Mapeando cada valor en una iterable 407 Mapeo de valores de diferentes iterables. 408 Transposición con mapa: uso de "Ninguno" como argumento de función (solo python 2.x) 409 Series y mapeo paralelo 410 Capítulo88:Funciones 413 Introducción 413 Sintaxis 413
    • 31. Parámetros 413 Observaciones 413 Recursos adicionales 414 Examples 414 Definiendo y llamando funciones simples. 414 Devolviendo valores desde funciones 416 Definiendo una función con argumentos. 417 Definiendo una función con argumentos opcionales. 417 Advertencia 418 Definiendo una función con múltiples argumentos. 418 Definiendo una función con un número arbitrario de argumentos. 418 Número arbitrario deargumentos posicionales: 418 Número arbitrario de argumentos de palabras clave 419 Advertencia 420 Nota sobre nombrar 421 Nota sobre la singularidad 421 Nota sobre funciones de anidamiento con argumentos opcionales 421 Definiendo una función con argumentos mutables opcionales. 421 Explicación 422 Solución 422 Funciones Lambda (Inline / Anónimo) 423 Argumento de paso y mutabilidad. 426 Cierre 427 Funciones recursivas 427 Límite de recursión 428 Funciones anidadas 429 Iterable y desempaquetado del diccionario. 429 Forzando el uso de parámetros nombrados 431 Lambda recursiva utilizando variable asignada 431 Descripción del código 432 Capítulo 89:Funciones parciales 433 Introducción 433
    • 32. Sintaxis 433 Parámetros 433 Observaciones 433 Examples 433 Elevar el poder 433 Capítulo90:Generadores 435 Introducción 435 Sintaxis 435 Examples 435 Iteración 435 La siguiente función () 435 Enviando objetos a un generador. 436 Expresiones generadoras 437 Introducción 437 Usando un generador para encontrar los números de Fibonacci 440 Secuencias infinitas 440 Ejemplo clásico - números de Fibonacci 441 Rindiendo todos los valores de otro iterable. 441 Coroutines 442 Rendimiento con recursión: listado recursivo de todos los archivos en un directorio 442 Iterando sobre generadores en paralelo. 443 Código de construcción de lista de refactorización 444 buscando 444 Capítulo91:Gestores de contexto (declaración “con”) 446 Introducción 446 Sintaxis 446 Observaciones 446 Examples 447 Introducción a los gestores de contexto y con la declaración. 447 Asignar a un objetivo 447 Escribiendo tu propio gestor de contexto. 448 Escribiendo tu propio administrador de contexto usando la sintaxis del generador. 449
    • 33. Gestores de contexto multiples 450 Gestionar recursos 450 Capítulo92:Gráficosdetortuga 452 Examples 452 Ninja Twist (Tortuga Gráficos) 452 Capítulo93:hashlib 453 Introducción 453 Examples 453 Hash MD5 de una cadena 453 algoritmo proporcionado por OpenSSL 454 Capítulo 94: Heapq 455 Examples 455 Artículos más grandes y más pequeños en una colección. 455 Artículo más pequeño en una colección. 455 Capítulo95:Herramienta 2to3 457 Sintaxis 457 Parámetros 457 Observaciones 458 Examples 458 Uso básico 458 Unix 458 Windows 458 Unix 459 Windows 459 Capítulo 96: herramienta grafica 460 Introducción 460 Examples 460 PyDotPlus 460 Instalación 460 PyGraphviz 461 Capítulo97:ijson 463 Introducción 463
    • 34. Examples 463 Ejemplo simple 463 Capítulo 98: Implementaciones no oficiales de Python 464 Examples 464 IronPython 464 Hola Mundo 464 enlacesexternos 464 Jython 464 Hola Mundo 465 enlacesexternos 465 Transcrypt 465 Tamañoyvelocidaddelcódigo 465 IntegraciónconHTML 466 IntegraciónconJavaScriptyDOM 466 Integracióncon otras bibliotecas de JavaScript 467 Relación entre Python y código JavaScript 467 enlacesexternos 468 Capítulo 99:Importando modulos 469 Sintaxis 469 Observaciones 469 Examples 469 Importando un modulo 469 Importando nombres específicos desde un módulo 471 Importando todos los nombres de un módulo 471 La variable especial all 472 Importación programática 473 Importar módulos desde una ubicación de sistema de archivos arbitraria. 473 Reglas PEP8 para Importaciones 474 Importando submódulos 474 importar () función 474 Reimportando un módulo 475
    • 35. Python 2 475 Python 3 475 Capítulo100:IncompatibilidadesquesemuevendePython2aPython3 477 Introducción 477 Observaciones 477 Examples 478 Declaración de impresión vs. función de impresión 478 Cuerdas: Bytes contra Unicode 479 División entera 481 Reducir ya no es una función incorporada. 483 Diferencias entre las funciones de rango y rango 484 Compatibilidad 485 Desembalaje Iterables 486 Levantando y manejando excepciones 488 .next () método en los iteradores renombrados 490 Comparación de diferentes tipos 490 Entrada del usuario 491 Cambios en el método del diccionario 492 La sentencia exec es una función en Python 3 493 Error de la función hasattr en Python 2 493 Módulos renombrados 494 Compatibilidad 495 Constantes octales 495 Todas las clases son "clases de nuevo estilo" en Python 3. 495 Se eliminaron los operadores <> y ``, sinónimo de! = Y repr () 496 codificar / decodificar a hex ya no está disponible 497 Función cmp eliminada en Python 3 498 Variables filtradas en la lista de comprensión. 498 mapa() 499 filter (), map () y zip () devuelven iteradores en lugar de secuencias 500 Importaciones absolutas / relativas 501 Más sobre Importaciones Relativas 502 Archivo I / O 503
    • 36. La función round () rompe el empate y devuelve el tipo 503 rotura de corbata redonda () 503 round () tipo de retorno 504 Verdadero, Falso y Ninguno 504 Devolver valor al escribir en un objeto de archivo 505 largo vs. int 505 Valor booleano de clase 506 Capítulo101:Indexaciónycorte 507 Sintaxis 507 Parámetros 507 Observaciones 507 Examples 507 Rebanado basico 507 Hacer una copia superficial de una matriz 508 Invertir un objeto 509 Clases personalizadas de indexación: getitem , setitem y delitem 509 Asignación de rebanada 510 Rebanar objetos 511 Indexación básica 511 Capítulo 102: Interfazdepuertade enlacedeservidorweb(WSGI) 513 Parámetros 513 Examples 513 Objeto de servidor (Método) 513 Capítulo 103:Introducción a RabbitMQ utilizando AMQPStorm 515 Observaciones 515 Examples 515 Cómo consumir mensajes de RabbitMQ 515 Cómo publicar mensajes a RabbitMQ 516 Cómo crear una cola retrasada en RabbitMQ 517 Capítulo104:Iterableseiteradores 519 Examples 519 Iterador vs Iterablevs generador 519 Lo que puede ser iterable 520
    • 37. Iterando sobre todo iterable 520 Verificar solo un elemento en iterable. 521 Extraer valores uno por uno. 521 ¡El iterador no es reentrante! 521 Capítulo 105: kivy - Framework Python multiplataforma para el desarrollo de NUI 522 Introducción 522 Examples 522 Primera aplicación 522 Capítulo 106:Ladeclaracióndepase 525 Sintaxis 525 Observaciones 525 Examples 527 Ignorar una excepción 527 Crear una nueva excepción que puede ser capturada 527 Capítulo107:Lafuncióndeimpresión 528 Examples 528 Fundamentos de impresión 528 Parámetros de impresión 529 Capítulo108:Lavariableespecial name 531 Introducción 531 Observaciones 531 Examples 531 name == ' main ' 531 Situación 1 531 Situación 2 531 function_class_or_module . name 532 Utilizar en el registro 533 Capítulo 109:Las clases 534 Introducción 534 Examples 534 Herencia basica 534 Funcionesincorporadas que funcionanconherencia. 535
    • 38. Variables de clase e instancia 536 Métodos enlazados, no enlazados y estáticos. 537 Clases de estilo nuevo vs. estilo antiguo 539 Valores por defecto para variables de instancia 540 Herencia múltiple 541 Descriptores y búsquedas punteadas 543 Métodos de clase: inicializadores alternos 544 Composición de la clase 545 Parche de mono 546 Listado de todos los miembros de la clase 547 Introducción a las clases 548 Propiedades 550 Clase de singleton 552 Capítulo110:Lectura yEscritura CSV 554 Examples 554 Escribiendo un archivo TSV 554 Pitón 554 Archivodesalida 554 Usando pandas 554 Capítulo 111: Lista 555 Introducción 555 Sintaxis 555 Observaciones 555 Examples 555 Acceso a los valores de la lista 555 Lista de métodos y operadores soportados. 557 Longitud de una lista 562 Iterando sobre una lista 562 Comprobando si un artículo está en una lista 563 Elementos de la lista de inversión 564 Comprobando si la lista está vacía 564 Concatenar y fusionar listas 564
    • 39. Examples 582 Todos y cada uno 565 Eliminar valores duplicados en la lista 566 Acceso a valores en lista anidada 566 Comparacion de listas 568 Inicializando una lista a un número fijo de elementos 568 Capítulo 112: Lista de Comprensiones 570 Introducción 570 Sintaxis 570 Observaciones 570 Examples 570 Lista de comprensiones condicionales 570 Lista de Comprensiones con Bucles Anidados 572 Refactorización de filtro y mapa para enumerar las comprensiones. 573 Refactorización - Referencia rápida 574 Comprensiones de lista anidadas 575 Iterar dos o más listas simultáneamente dentro de la comprensión de la lista 575 Capítulo 113: Lista de desestructuración (también conocido como embalaje y desembalaje) 577 Examples 577 Tarea de destrucción 577 La destrucción como valores. 577 La destrucción como lista 577 Ignorar valores en las tareas de desestructuración. 578 Ignorar listas en tareas de desestructuración. 578 Argumentos de la función de embalaje 578 Empaquetando una lista de argumentos 579 Packing argumentos de palabras clave 579 Desempaquetando argumentos de funciones 581 Capítulo 114:Listar comprensiones 582 Introducción 582 Sintaxis 582 Observaciones 582
    • 40. Examples 604 Lista de Comprensiones 582 más 583 Dobleiteración 584 Mutación in situ y otros efectos secundarios 584 Losespaciosenblancoenlalistadecomprensión 585 Diccionario de Comprensiones 586 Expresiones del generador 587 Casos de uso 589 Establecer Comprensiones 590 Evite operaciones repetitivas y costosas usando cláusula condicional 590 Comprensiones que involucran tuplas 592 Contando Ocurrencias Usando Comprensión 592 Cambio de tipos en una lista 593 Capítulo115:Listasenlazadas 594 Introducción 594 Examples 594 Ejemplo de lista enlazada única 594 Capítulo 116: Llama a Pythondesde C # 598 Introducción 598 Observaciones 598 Examples 599 Script de Python para ser llamado por la aplicación C # 599 Código C # llamando al script Python 600 Capítulo 117: Maldiciones básicas con pitón 602 Observaciones 602 Examples 602 Ejemplo básico de invocación 602 La función de ayuda wrapper (). 602 Capítulo118:ManipulandoXML 604 Observaciones 604
    • 41. Abriendo y leyendo usando un ElementTree 604 Modificar un archivo XML 604 Crear y construir documentos XML 605 Abrir y leer archivos XML grandes utilizando iterparse (análisis incremental) 605 Buscando el XML con XPath 606 Capítulo 119:Matemáticas complejas 608 Sintaxis 608 Examples 608 Aritmética compleja avanzada 608 Aritmética compleja básica 609 Capítulo 120: Matraz 610 Introducción 610 Sintaxis 610 Examples 610 Los basicos 610 URL de enrutamiento 611 Métodos HTTP 611 Archivos y plantillas 612 Jinja Templando 613 El objeto de solicitud 614 Parámetros de URL ..... 614 Cargasde archivos ..... 615 Galletas ....................... 615 Capítulo 121:Matrices multidimensionales 616 Examples ........................ 616 Listas en listas ..................... 616 Listas en listas en listas en.... 617 Capítulo122:Metaclases 618 Introducción 618 Observaciones 618 Examples 618 Metaclases basicas 618
    • 42. Singletons utilizando metaclases 619 Usando una metaclase 620 Sintaxisdemetaclase 620 CompatibilidaddePython2 y3 consix 620 Funcionalidad personalizada con metaclases. 620 Introducción a las metaclases 621 ¿Qué es una metaclase? 621 La metaclase mas simple 621 Una metaclase que hace algo 621 La metaclase por defecto. 622 Capítulo123:MétodoAnulando 624 Examples 624 Método básico anulando 624 Capítulo 124: Métodosde cuerda 625 Sintaxis 625 Observaciones 626 Examples 626 Cambiar la capitalización de una cadena 626 str.casefold() 626 str.upper() 627 str.lower() 627 str.capitalize() 627 str.title() 627 str.swapcase() 627 Uso como métodos de clase str 627 Dividir una cadena basada en un delimitador en una lista de cadenas 628 str.split(sep=None, maxsplit=-1) 628 str.rsplit(sep=None, maxsplit=-1) 629 Reemplace todas las ocurrencias de una subcadena por otra subcadena 629 str.replace(old, new[, count]) : 629 str.format y f-strings: formatea valores en una cadena 630 Contando el número de veces que una subcadena aparece en una cadena 631 str.count(sub[, start[, end]]) 631
    • 43. Prueba los caracteres iniciales y finales de una cadena. 632 str.startswith(prefix[, start[, end]]) 632 str.endswith(prefix[, start[, end]]) 632 Probando de qué está compuesta una cuerda 633 str.isalpha 633 str.isupper , str.islower , str.istitle 633 str.isdecimal , str.isdigit , str.isnumeric 634 str.isalnum 634 str.isspace 635 str.translate: Traducir caracteres en una cadena 635 Eliminar caracteres iniciales / finales no deseados de una cadena 636 str.strip([chars]) 636 str.rstrip([chars]) y str.lstrip([chars]) 636 Comparaciones de cadenas insensibles al caso 637 Unir una lista de cadenas en una cadena 638 Constantes útiles del módulo de cadena 638 string.ascii_letters : 639 string.ascii_lowercase 639 string.ascii_uppercase : 639 string.digits : 639 string.hexdigits : 639 string.octaldigits : 639 string.punctuation : 639 string.whitespace : 640 string.printable : 640 Invertir una cadena 640 Justificar cuerdas 641 Conversión entre str o bytes de datos y caracteres Unicode 641 Cadena contiene 642 Capítulo 125: Métodos definidos por el usuario 644 Examples 644 Creando objetos de método definidos por el usuario 644 Ejemplo de tortuga 645
    • 44. Capítulo126:Mixins 646 Sintaxis 646 Observaciones 646 Examples 646 Mezclar 646 Métodos de anulación en Mixins 647 Capítulo127:Modismos 649 Examples 649 Inicializaciones clave del diccionario 649 Variables de conmutacion 649 Use la prueba de valor de verdad 649 Prueba de " main " para evitar la ejecución inesperada del código 650 Capítulo128:Móduloaleatorio 651 Sintaxis 651 Examples 651 Aleatorio y secuencias: barajar, selección y muestra. 651 barajar() 651 elección() 651 muestra() 651 Creación de enteros y flotadores aleatorios: randint, randrange, random y uniform 652 randint () 652 randrange () 652 aleatorio 653 uniforme 653 Números aleatorios reproducibles: semilla y estado 653 Crear números aleatorios criptográficamente seguros 654 Creando una contraseña de usuario aleatoria 655 Decisión Binaria Aleatoria 656 Capítulo129:Móduloasyncio 657 Examples 657 Sintaxis de Coroutine y Delegación 657 Ejecutores asincronos 658
    • 45. Usando UVLoop 659 Primitiva de sincronización: Evento 659 Concepto 659 Ejemplo 660 Un simple websocket 660 Error común sobre asyncio 661 Capítulo 130: Módulo decola 663 Introducción 663 Examples 663 Ejemplo simple 663 Capítulo 131: Módulo de colecciones 664 Introducción 664 Observaciones 664 Examples 664 colecciones. 664 colecciones.defaultdict 666 colecciones.OrdenedDict 667 colecciones.namedu tupla 668 colecciones.deque 669 colecciones.ChainMap 670 Capítulo132:Módulodefunciones 672 Examples 672 parcial 672 ordenamiento total 672 reducir 673 lru_cache 673 cmp_to_key 674 Capítulo133:Módulodematemáticas 675 Examples 675 Redondeo: redondo, suelo, ceil, trunc 675 ¡Advertencia! 676 Advertencia sobre la división de números negativos en el piso, corte y número entero 676
    • 46. Logaritmos 676 Copiando carteles 677 Trigonometría 677 Cálculo de la longitud de la hipotenusa. 677 Convertir grados a / desde radianes 677 Funciones seno, coseno, tangente e inversa. 677 Seno hiperbólico, coseno y tangente. 678 Constantes 678 Números imaginarios 679 Infinito y NaN ("no es un número") 679 Pow para una exponenciación más rápida 682 Números complejos y el módulo cmath. 682 Capítulo134:Módulodenavegadorweb 686 Introducción 686 Sintaxis 686 Parámetros 686 Observaciones 687 Examples 688 Abrir una URL con el navegador predeterminado 688 Abrir una URL con diferentes navegadores 688 Capítulo 135: Módulo Deque 690 Sintaxis 690 Parámetros 690 Observaciones 690 Examples 690 Uso básico deque 690 límite de tamaño de salida 691 Métodos disponibles en deque. 691 Amplia primera búsqueda 692 Capítulo 136:Módulo Itertools 693 Sintaxis 693 Examples 693 Agrupando elementos de un objeto iterable usando una función 693
    • 47. Toma una rebanada de un generador 694 itertools.product 695 itertools.count 695 itertools.takewhile 696 itertools.dropwhile 697 Zipping dos iteradores hasta que ambos están agotados 698 Método de combinaciones en el módulo Itertools 698 Encadenando múltiples iteradores juntos 699 itertools.repeat 699 Obtener una suma acumulada de números en un iterable 699 Recorre los elementos en un iterador 700 itertools.permutaciones 700 Capítulo 137: Módulo JSON 701 Observaciones 701 Los tipos 701 Valores predeterminados 701 Tipos de serialización: 701 Tipos de serialización: 701 Personalización (des) serialización 702 Publicación por entregas: 702 De serialización: 702 Mayor (des) serialización personalizada: 703 Examples 703 Creando JSON desde el dictado de Python 703 Creando el dictado de Python desde JSON 703 Almacenamiento de datos en un archivo 704 Recuperando datos de un archivo 704 `load` vs` loads`, `dump` vs` dumps` 704 Llamando a `json.tool` desde la línea de comandos a la salida JSON de impresión bonita 705 Formato de salida JSON 706 Configuración de sangría para obtener una salida más bonita 706 Ordenando las teclas alfabéticamente para obtener unresultadoconsistente 706
    • 48. Deshacersedelosespaciosenblancoparaobtener unasalidacompacta 707 JSON que codifica objetos personalizados 707 Capítulo138:Módulooperador 709 Examples 709 Operadores como alternativa a un operador infijo. 709 Methodcaller 709 Itemgetter 709 Capítulo 139: módulo pyautogui 711 Introducción 711 Examples 711 Funciones del mouse 711 Funciones del teclado 711 ScreenShot y reconocimiento de imágenes 711 Capítulo140:MóduloSqlite3 712 Examples 712 Sqlite3 - No requiere proceso de servidor separado. 712 Obtención de los valores de la base de datos y manejo de errores. 712 Capítulo141:Multihilo 714 Introducción 714 Examples 714 Conceptos básicos de multihilo 714 Comunicando entre hilos 715 Creando un grupo de trabajadores 716 Uso avanzado de multihilos 717 Impresora avanzada (logger) 717 Hilo que se puede detener con un bucle de tiempo 718 Capítulo142: Multiprocesamiento 720 Examples 720 Ejecutando dos procesos simples 720 Uso de la piscina y el mapa 721 Capítulo143:MutablevsInmutable(yHashable)enPython 722 Examples 722
    • 49. Mutable vs inmutable 722 Inmutables 722 Ejercicio 723 Mutables 723 Ejercicio 724 Mutables e inmutables como argumentos 724 Ejercicio 725 Capítulo 144: Neo4j yCypher usandoPy2Neo 726 Examples 726 Importación y Autenticación 726 Añadiendo nodos a Neo4j Graph 726 Agregando relaciones a Neo4j Graph 726 Consulta 1: Autocompletar en títulos de noticias 727 Consulta 2: obtener artículos de noticias por ubicación en una fecha en particular 727 Cypher Query Samples 727 Capítulo 145: Nodode lista enlazada 729 Examples 729 Escribe un nodo de lista enlazada simple en python 729 Capítulo146:Objetosdepropiedad 730 Observaciones 730 Examples 730 Usando el decorador @property 730 Usando el decorador de propiedad para las propiedades de lectura-escritura 730 Anulando solo un captador, configurador o un eliminador de un objeto de propiedad 731 Usando propiedades sin decoradores 731 Capítulo 147:Operadores booleanos 734 Examples 734 y 734 o 734 no 735 Evaluación de cortocircuito 735 `and` y` or` no están garantizados para devolver un valor booleano 736
    • 50. Un simple ejemplo 736 Capítulo148:OperadoresdeBitwise 737 Introducción 737 Sintaxis 737 Examples 737 Y a nivel de bit 737 Bitwise o 737 XOR de bitwise (OR exclusivo) 738 Desplazamiento a la izquierda en modo de bits 738 Cambio a la derecha en el modo de bits 739 Bitwise NO 739 Operaciones in situ 741 Capítulo 149: Operadores matemáticos simples 742 Introducción 742 Observaciones 742 Tipos numéricos ysus metaclases. 742 Examples 742 Adición 742 Sustracción 743 Multiplicación 743 División 744 Exponer 746 Funciones especiales 746 Logaritmos 747 Operaciones in situ 747 Funciones trigonométricas 748 Módulo 748 Capítulo 150: Optimizacióndelrendimiento 750 Observaciones 750 Examples 750 Código de perfil 750 Capítulo 151:os.path 753
    • 51. Introducción 753 Sintaxis 753 Examples 753 Unir caminos 753 Camino Absoluto desde el Camino Relativo 753 Manipulación de componentes del camino 754 Obtener el directorio padre 754 Si el camino dado existe. 754 compruebe si la ruta dada es un directorio, archivo, enlace simbólico, punto de montaje, e 754 Capítulo152:Pandas Transform:Preforma operaciones engrupos yconcatenalos resultados. 756 Examples 756 Transformada simple 756 Primero, vamos a crear un marco de datos ficticio 756 Ahora, usaremos la función de transform pandas para contar el número de pedidos por client 756 Múltiples resultados por grupo 757 Usando funciones de transform que devuelvensub-cálculos por grupo. 757 Capítulo153:Patronesdediseño 759 Introducción 759 Examples 759 Patrón de estrategia 759 Introducción a los patrones de diseño y patrón Singleton. 760 Apoderado 762 Capítulo154:Perfilado 765 Examples 765 %% timeit y% timeit en IPython 765 función timeit () 765 línea de comandos de timeit 765 line_profiler en linea de comando 766 Usando cProfile (Perfilador preferido) 766 Capítulo 155:Persistencia Python 768 Sintaxis 768
    • 52. Parámetros 768 Examples 768 Persistencia Python 768 Función de utilidad para guardar y cargar. 769 Capítulo 156:pip:PyPIPackage Manager 770 Introducción 770 Sintaxis 770 Observaciones 770 Examples 771 Instalar paquetes 771 Instalar desde archivos de requisitos 771 Desinstalar paquetes 771 Para listar todos los paquetes instalados usando `pip` 772 Paquetes de actualización 772 Actualizando todos los paquetes desactualizados en Linux 772 Actualizando todos los paquetes desactualizados en Windows 773 Cree un archivo Requirements.txt de todos los paquetes en el sistema 773 Cree un archivo Requirements.txt de paquetes solo en el virtualenv actual 773 Usando una determinada versión de Python con pip 773 Instalación de paquetes aún no en pip como ruedas 774 Nota sobre la instalación de versiones preliminares 776 Nota sobre la instalación de versiones de desarrollo 776 Capítulo157:Plantillasenpython 779 Examples 779 Programa de salida de datos simple usando plantilla 779 Cambiando delimitador 779 Capítulo 158: Polimorfismo 780 Examples 780 Polimorfismo basico 780 Escribiendo pato 782 Capítulo159:PostgreSQL 784 Examples 784
    • 53. Empezando 784 Instalación utilizando pip 784 Uso básico 784 Capítulo160:Precedenciadeloperador 786 Introducción 786 Observaciones 786 Examples 787 Ejemplos simples de precedencia de operadores en python. 787 Capítulo161:Procesosehilos 788 Introducción 788 Examples 788 Bloqueo de intérprete global 788 Corriendo en múltiples hilos 790 Ejecutando en múltiples procesos 790 Compartir el estado entre hilos 791 Estado de intercambio entre procesos 791 Capítulo 162: Programación Funcionalen Python 793 Introducción 793 Examples 793 Función lambda 793 Función de mapa 793 Función de reducción 793 Función de filtro 793 Capítulo163:ProgramaciónIoTconPythonyRaspberryPI 795 Examples 795 Ejemplo - sensor de temperatura 795 Capítulo164:py.test 798 Examples 798 Configurando py.test 798 El código a probar 798 El código de prueba 798 Corriendo la prueba 798
    • 54. Pruebas de falla 799 Introducción a los accesorios de prueba 799 Py.test accesorios para el rescate! 800 Limpieza después de las pruebas. 802 Capítulo165:pyaudio 804 Introducción 804 Observaciones 804 Examples 804 Modo de devolución de llamada de audio I / O 804 Modo de bloqueo de E / S de audio 805 Capítulo 166:pygame 807 Introducción 807 Sintaxis 807 Parámetros 807 Examples 807 Instalando pygame 807 Modulo mezclador de pygame 808 Inicializando 808 Posibles acciones 808 Los canales 808 Capítulo 167: Pyglet 810 Introducción 810 Examples 810 Hola Mundo en Pyglet 810 Instalación de Pyglet 810 Reproducción de sonido en Pyglet 810 Usando Pyglet para OpenGL 810 Dibujar puntos usando Pyglet y OpenGL 811 Capítulo 168: PyInstaller - Distribuir código dePython 812 Sintaxis 812 Observaciones 812 Examples 812 Instalación y configuración 812
    • 55. Usando Pyinstaller 813 Agrupar en una carpeta 813 Ventajas: 813 Desventajas 814 Agrupar en un solo archivo 814 Capítulo169:PythonLex-Yacc 815 Introducción 815 Observaciones 815 Examples 815 Empezando con PLY 815 El "¡Hola mundo!" de PLY - Una calculadora simple 815 Parte 1: Tokenizing entrada con Lex 817 Descompostura 818 h22 819 h23 819 h24 820 h25 820 h26 820 h27 820 h28 820 h29 821 h210 821 h211 821 Parte 2: Análisis de entrada Tokenized con Yacc 821 Descompostura 822 h212 824 Capítulo170:PythonRequestsPost 825 Introducción 825 Examples 825 Post simple 825
    • 56. Formulario de datos codificados 826 Subir archivo 827 Respuestas 827 Autenticación 828 Proxies 829 Capítulo 171:PythonyExcel 830 Examples 830 Ponga los datos de la lista en un archivo de Excel. 830 OpenPyXL 830 Crear gráficos de Excel con xlsxwriter 831 Lee los datos de excel usando el módulo xlrd 833 Formato de archivos de Excel con xlsxwriter 834 Capítulo172:Recoleccióndebasura 836 Observaciones 836 Recolección de basura generacional 836 Examples 838 Recuento de referencias 838 Recolector de basura para ciclos de referencia 839 Efectos del comando del 840 Reutilización de objetos primitivos. 841 Viendo el refcount de un objeto 841 Forzar la desasignación de objetos. 841 Gestionando la recogida de basura. 842 No espere a que la recolección de basura se limpie 843 Capítulo 173: Reconocimiento óptico de caracteres 845 Introducción 845 Examples 845 PyTesseract 845 PyOCR 845 Capítulo174:Recursion 847 Observaciones 847 Examples 847 Suma de números del 1 al n 847
    • 57. El qué, cómo y cuándo de la recursión 847 Exploración de árboles con recursión 851 Incrementando la profundidad máxima de recursión 852 Recursión de cola - Mala práctica 853 Optimización de la recursión de cola a través de la introspección de la pila 853 Capítulo 175: RedesPython 855 Observaciones 855 Examples 855 El ejemplo más simple de cliente / servidor de socket de Python. 855 Creando un servidor HTTP simple 855 Creando un servidor TCP 856 Creando un Servidor UDP 857 Inicie Simple HttpServer en un hilo y abra el navegador 857 Capítulo176:Reducir 859 Sintaxis 859 Parámetros 859 Observaciones 859 Examples 859 Visión general 859 Utilizando reducir 860 Producto acumulativo 861 Variante sin cortocircuito de alguno / todos. 861 Primer elemento verdadero / falso de una secuencia (o último elemento si no hay ninguno) 861 Capítulo 177: Representaciones de cadena de instancias de clase: métodos str y repr_ 862 Observaciones 862 Una nota sobre la implementación de ambos métodos. 862 Notas 862 Examples 863 Motivación 863 El problema 864 La Solución(Parte 1) 864
    • 58. La Solución(Parte 2) 865 Sobre esas funciones duplicadas 867 Resumen 867 Ambos métodos implementados, eval-round-trip style repr () 868 Capítulo 178: Sangría 869 Examples 869 Errores de sangría 869 Ejemplo simple 869 ¿Espacios o pestañas? 870 Cómo se analiza la sangría 870 Capítulo 179: Seguridad y criptografía 872 Introducción 872 Sintaxis 872 Observaciones 872 Examples 872 Cálculo de un resumen del mensaje 872 Algoritmos de hash disponibles 873 Contraseña segura Hashing 873 Hash de archivo 874 Cifrado simétrico utilizando pycrypto 874 Generando firmas RSA usando pycrypto 875 Cifrado RSA asimétrico utilizando pycrypto 876 Capítulo180:Serializacióndedatos 878 Sintaxis 878 Parámetros 878 Observaciones 878 Examples 879 Serialización utilizando JSON 879 Serialización utilizando Pickle 879 Capítulo181:Serializacióndedatosdesalmuera 881 Sintaxis 881 Parámetros 881
    • 59. Observaciones 881 Tipos pickleable 881 pickleyseguridad 881 Examples 882 Usando Pickle para serializar y deserializar un objeto 882 Para serializarelobjeto. 882 Deserializarelobjeto. 882 Usandoobjetosdepickle ybyte 882 Personalizar datos en escabeche 883 Capítulo 182:ServidorHTTPdePython 885 Examples 885 Ejecutando un servidor HTTP simple 885 Archivos de servicio 885 API programática de SimpleHTTPServer 887 Manejo básico de GET, POST, PUT usando BaseHTTPRequestHandler 888 Capítulo183:setup.py 890 Parámetros 890 Observaciones 890 Examples 890 Propósito de setup.py 890 Agregando scripts de línea de comandos a su paquete de Python 891 Usando metadatos de control de fuente en setup.py 892 Añadiendo opciones de instalación 892 Capítulo 184:Similitudes enlasintaxis,diferencias enelsignificado:Pythonvs.JavaSc 894 Introducción 894 Examples 894 `in` con listas 894 Capítulo185:Sobrecarga 895 Examples 895 Métodos de magia / Dunder 895 Contenedor y tipos de secuencia. 896 Tipos callables 897
    • 60. Manejando conductas no implementadas. 897 Sobrecarga del operador 898 Capítulo186:Socketsycifrado/descifradodemensajesentreelclienteyelservidor 901 Introducción 901 Observaciones 901 Examples 904 Implementación del lado del servidor 904 Implementación del lado del cliente 906 Capítulo187:SubcomandosCLIconsalida deayudaprecisa 909 Introducción 909 Observaciones 909 Examples 909 Forma nativa (sin bibliotecas) 909 argparse (formateador de ayuda predeterminado) 910 argparse (formateador de ayuda personalizado) 911 Capítulo 188: sys 913 Introducción 913 Sintaxis 913 Observaciones 913 Examples 913 Argumentos de línea de comando 913 Nombre del script 913 Flujo de error estándar 914 Finalización prematura del proceso y devolución de un código de salida. 914 Capítulo 189:tempfile NamedTemporaryFile 915 Parámetros 915 Examples 915 Cree (y escriba en) un archivo temporal persistente conocido 915 Capítulo190:Tipodesugerencias 917 Sintaxis 917 Observaciones 917 Examples 917
    • 61. Tipos genéricos 917 Añadiendo tipos a una función 917 Miembros de la clase y métodos 919 Variables y atributos 919 NamedTuple 920 Escriba sugerencias para argumentos de palabras clave 920 Capítulo 191:TiposdedatosdePython 921 Introducción 921 Examples 921 Tipo de datos numeros 921 Tipo de datos de cadena 921 Tipo de datos de lista 921 Tipo de datos de la tupla 921 Tipo de datos del diccionario 922 Establecer tipos de datos 922 Capítulo 192: Tipos de datos inmutables (int, float, str, tuple y frozensets) 923 Examples 923 Los caracteres individuales de las cadenas no son asignables 923 Los miembros individuales de Tuple no son asignables 923 Los Frozenset son inmutables y no asignables. 923 Capítulo193:tkinter 924 Introducción 924 Observaciones 924 Examples 924 Una aplicación tkinter mínima 924 Gerentes de geometría 925 Lugar 925 Paquete 926 Cuadrícula 926 Capítulo 194: Trabajando alrededor del bloqueo global de intérpretes (GIL) 928 Observaciones 928 ¿Por qué hay un GIL? 928
    • 62. Detallessobre cómofuncionaelGIL: 928 Beneficiosde la GIL 929 Consecuencias de laGIL 929 Referencias: 929 Examples 930 Multiprocesamiento.Pool 930 CódigodeDavidBeazleyquemostrabaproblemasdesubprocesosde GIL 930 Cython Nogil: 931 CódigodeDavidBeazleyquemostrabaproblemasdesubprocesosde GIL 931 Reescrito usando nogil(SOLOFUNCIONAEN CYTHON): 931 Capítulo195:TrabajandoconarchivosZIP 933 Sintaxis 933 Observaciones 933 Examples 933 Apertura de archivos zip 933 Examinando los contenidos de Zipfile 933 Extraer el contenido del archivo zip a un directorio. 934 Creando nuevos archivos 934 Capítulo 196: Trazado con matplotlib 936 Introducción 936 Examples 936 Una parcela simple en Matplotlib 936 Agregar más características a un gráfico simple: etiquetas de eje, título, marcas de eje, 937 Haciendo múltiples parcelas en la misma figura por superposición similar a MATLAB 938 Realización de varios gráficos en la misma figura utilizando la superposición de gráficos 939 Gráficos con eje X común pero eje Y diferente: usando twinx () 940 Gráficos con eje Y común y eje X diferente usando twiny () 942 Capítulo 197:Tupla 945 Introducción 945 Sintaxis 945 Observaciones 945 Examples 945
    • 63. Tuplas de indexación 945 Las tuplas son inmutables 946 Tuple son elementos sabios hashable y equiparables 946 Tupla 947 Embalaje y desembalaje de tuplas 948 Elementos de inversión 949 Funciones de tupla incorporadas 949 Comparación 949 Longitudde latupla 950 Max deuna tupla 950 Min deuna tupla 950 Convertirunalistaentupla 950 Concatenación de tuplas 950 Capítulo198:Unicode 952 Examples 952 Codificación y decodificación. 952 Capítulo 199: Unicodeybytes 953 Sintaxis 953 Parámetros 953 Examples 953 Lo esencial 953 Unicode a bytes 953 Bytes a Unicode 954 Codificación / decodificación de manejo de errores. 955 Codificación 955 Descodificación 955 Moral 955 Archivo I / O 955 Capítulo200:urllib 957 Examples 957 HTTP GET 957
    • 64. Python 2 957 Python 3 957 POST HTTP 958 Python 2 ................ 958 Python 3 .................. 958 Decodificar bytes recibidos de acuerdo a la codificación del tipo de contenido 958 Capítulo 201: Usando bucles dentro de funciones 960 Introducción ................ 960 Examples .................... 960 Declaración de retorno dentro del bucle en una función 960 Capítulo202:Usodelmódulo"pip":PyPIPackageManager 961 Introducción ................ 961 Sintaxis ....................... 961 Examples .................... 962 Ejemplo de uso de comandos 962 Manejo de la excepción de ImportError 962 Fuerza de instalación ...... 963 Capítulo203:VelocidaddePythondelprograma. 964 Examples .................... 964 Notación ......................... 964 Lista de operaciones ....... 964 Operaciones de deque .... 965 Establecer operaciones .. 966 Notaciones algorítmicas... 966 Capítulo 204: Visualización de datos con Python 968 Examples 968 Matplotlib 968 Seaborn 969 MayaVI 972 Plotly 973 Capítulo205:WebraspadoconPython 976 Introducción 976
    • 65. Observaciones 976 Paquetes de Python útiles para raspado web (orden alfabético) 976 Realización de solicitudes y recogida de datos. 976 requests 976 requests-cache 976 scrapy 976 selenium 976 Análisis de HTML 976 BeautifulSoup 977 lxml 977 Examples 977 Ejemplo básico de uso de solicitudes y lxml para raspar algunos datos 977 Mantenimiento de sesión web-scraping con peticiones. 977 Raspado utilizando el marco de Scrapy 978 Modificar agente de usuario de Scrapy 978 Raspado utilizando BeautifulSoup4 979 Raspado utilizando Selenium WebDriver 979 Descarga de contenido web simple con urllib.request 979 Raspado con rizo 980 Capítulo206:Websockets 981 Examples 981 Eco simple con aiohttp 981 Clase de envoltura con aiohttp 981 Usando Autobahn como una Websocket Factory 982 Creditos 985
    • 66. 1 Acerca de Puedes compartir este PDF con cualquier persona que creas que podría beneficiarse. Es un libro electrónico no oficial y gratuito sobre PYTHON creado con fines educativos. Todo el contenido se extrae de la documentación de Stack Overflow, escrita por muchas personas trabajadoras en Stack Overflow. No está afiliado a Stack Overflow ni al lenguaje oficial de Python. El contenido se publica bajo Creative Commons BY-SA, y la lista de contribuyentes a cada capítulo se proporciona en la sección de créditos al final de este libro. Las imágenes pueden ser propiedad de sus respectivos dueños a menos que se especifique lo contrario. Todas las marcas comerciales y marcas registradas son propiedad de sus respectivos dueños. Usa el contenido presentado en este libro bajo tu propio riesgo; no se garantiza que sea correcto ni exacto.
    • 67. 2 if something: x = 1 else: x = 'this is a string' print(x) 1 + '1' # raises an error 1 + int('1') # results with 2 Capítulo 1: Empezando con Python Language Observaciones Python es un lenguaje de programación muy utilizado. Es: • Alto nivel : Python automatiza las operaciones de bajo nivel, como la administración de memoria. Deja al programador con un poco menos de control, pero tiene muchos beneficios que incluyen la legibilidad del código y expresiones de código mínimas. • Propósito general : Python está diseñado para ser utilizado en todos los contextos y entornos. Un ejemplo de un lenguaje de uso no general es PHP: está diseñado específicamente como un lenguaje de script de desarrollo web del lado del servidor. En contraste, Python puede usarse para el desarrollo web del lado del servidor, pero también para crear aplicaciones de escritorio. • Escrito dinámicamente : cada variable en Python puede hacer referencia a cualquier tipo de datos. Una sola expresión puede evaluar datos de diferentes tipos en diferentes momentos. Debido a eso, el siguiente código es posible: • Se escribe con fuerza : durante la ejecución del programa, no se le permite hacer nada que sea incompatible con el tipo de datos con los que está trabajando. Por ejemplo, no hay conversiones ocultas de cadenas a números; una cadena hecha de dígitos nunca se tratará como un número a menos que la conviertas explícitamente: • Amigable para principiantes :) : la sintaxis y la estructura de Python son muy intuitivas. Es de alto nivel y proporciona construcciones destinadas a permitir la escritura de programas claros tanto a pequeña como a gran escala. Python es compatible con múltiples paradigmas de programación, incluidos la programación orientada a objetos, la imperativa y funcional o los estilos de procedimiento. Tiene una biblioteca estándar grande y completa y muchas bibliotecas de terceros fáciles de instalar. Sus principios de diseño se describen en el Zen de Python . Actualmente, hay dos ramas principales de lanzamiento de Python que tienen algunas diferencias
    • 68. 3 significativas. Python 2.x es la versión heredada, aunque sigue teniendo un uso generalizado. Python 3.x realiza un conjunto de cambios incompatibles con versiones anteriores que tienen como objetivo reducir la duplicación de características. Para obtener ayuda para decidir qué versión es la mejor para usted, consulte este artículo . La documentación oficial de Python también es un recurso completo y útil, que contiene documentación para todas las versiones de Python, así como tutoriales para ayudarlo a comenzar. Existe una implementación oficial del lenguaje suministrado por Python.org, generalmente denominado CPython, y varias implementaciones alternativas del lenguaje en otras plataformas de tiempo de ejecución. Estos incluyen IronPython (que ejecuta Python en la plataforma .NET), Jython (en el tiempo de ejecución de Java) y PyPy (que implementa Python en un subconjunto de sí mismo). Versiones Python 3.x Versión Fecha de lanzamiento [3.7] 2017-05-08 3.6 2016-12-23 3.5 2015-09-13 3.4 2014-03-17 3.3 2012-09-29 3.2 2011-02-20 3.1 2009-06-26 3.0 2008-12-03 Python 2.x Versión Fecha de lanzamiento 2.7 2010-07-03 2.6 2008-10-02 2.5 2006-09-19
    • 69. 4 $ python --version Versión Fecha de lanzamiento 2.4 2004-11-30 2.3 2003-07-29 2.2 2001-12-21 2.1 2001-04-15 2.0 2000-10-16 Examples Empezando Python es un lenguaje de programación de alto nivel ampliamente utilizado para la programación de propósito general, creado por Guido van Rossum y lanzado por primera vez en 1991. Python cuenta con un sistema de tipo dinámico y gestión automática de memoria y soporta múltiples paradigmas de programación, incluyendo imperativo, orientado a objetos. Programación funcional, y estilos procesales. Tiene una biblioteca estándar grande y completa. Dos versiones principales de Python están actualmente en uso activo: • Python 3.x es la versión actual y está en desarrollo activo. • Python 2.x es la versión heredada y solo recibirá actualizaciones de seguridad hasta 2020. No se implementarán nuevas funciones. Tenga en cuenta que muchos proyectos siguen utilizando Python 2, aunque la migración a Python 3 es cada vez más sencilla. Puede descargar e instalar cualquiera de las versiones de Python aquí . Ver Python 3 contra Python 2 para una comparación entre ellos. Además, algunos terceros ofrecen versiones reenvasadas de Python que agregan bibliotecas de uso común y otras características para facilitar la configuración de casos de uso comunes, como matemáticas, análisis de datos o uso científico. Vea la lista en el sitio oficial . Verificar si Python está instalado Para confirmar que Python se instaló correctamente, puede verificarlo ejecutando el siguiente comando en su terminal favorita (si está usando el sistema operativo Windows, debe agregar la ruta de acceso de python a la variable de entorno antes de usarlo en el símbolo del sistema): Python 3.x 3.0 Si tiene Python 3 instalado y es su versión predeterminada (consulte la sección Solución de problemas para obtener más detalles), debería ver algo como esto:
    • 70. 5 $ python --version Python 2.7.13 >>> >>> print("Hello, World") >>> print("Hello, World") Hello, World Python 2.x 2.7 Si tiene instalado Python 2 y es su versión predeterminada (consulte la sección Solución de problemas para obtener más detalles), debería ver algo como esto: Si ha instalado Python 3, pero $ python --version genera una versión de Python 2, también tiene Python 2instalado.Este esa menudo el caso de MacOSy muchas distribuciones de Linux. Use $ python3 en $ python3 lugar para usar explícitamente el intérprete de Python 3. Hola, Mundo en Python usando IDLE IDLE es un editor simple para Python, que viene incluido con Python. Cómo crear el programa Hello, World en IDLE. • Abra IDLE en su sistema de elección. ○ En versiones anteriores de Windows, se puede encontrar en All Programs en el menú de Windows. ○ En Windows 8+, busque IDLE o encuéntrelo en las aplicaciones que están presentes en su sistema. ○ EnsistemasbasadosenUnix (incluyendo Mac),puedeabrirlo desdeel shell escribiendo $ idle python_file.py . • Se abrirá una concha con opciones a lo largo de la parte superior. En la cáscara, hay un indicador de tres corchetes de ángulo recto: Ahora escriba el siguiente código en el indicador: Presiona Enter . Hola archivo de World Python Crea un nuevo archivo hello.py que contenga la siguiente línea: $ python --version Python 3.6.0
    • 71. 6 print('Hello, World') from future import print_function print 'Hello, World' $ python Python 2.7.12 (default, Jun 28 2016, 08:46:01) [GCC 6.1.1 20160602] on linux Type "help", "copyright", "credits" or "license" for more information. >>> print 'Hello, World' Hello, World >>> Python 3.x 3.0 Python 2.x 2.6 Puede usar la función de print Python 3 en Python 2 con la siguiente declaración de import : Python 2 tiene una serie de funcionalidades que pueden importarse opcionalmente desde Python 3 usando el módulo future , como se explica aquí . Python 2.x 2.7 Si usa Python 2, también puede escribir la siguiente línea. Tenga en cuenta que esto no es válido en Python 3 y, por lo tanto, no se recomienda porque reduce la compatibilidad de código entre versiones. En suterminal,navegue al directorio quecontieneel archivohello.py. Escriba python hello.py , luego python hello.py la tecla Intro . Deberías ver Hello, World impreso en la consola. Tambiénpuede sustituir hello.py conla ruta a suarchivo.Por ejemplo, sitiene el archivoensu directorio de inicio y su usuario es "usuario" en Linux, puede escribir python /home/user/hello.py . Ejecutar un shell interactivo de Python Al ejecutar (ejecutar) el comando python en su terminal, se le presenta un shell interactivo de Python.Esto también se conoce como el intérprete de Python o REPL (para 'LeerEvaluar Imprimir Loop'). Si desea ejecutar Python 3 desde su terminal, ejecute el comando python3 . $ python hello.py Hello, World
    • 72. 7 >>> exit() >>> quit() Alternativamente,inicielasolicitudinteractivaycargueelarchivoconpython -i <file.py> . En la línea de comando,ejecute: Hay varias formas de cerrar el shell de Python: o Alternativamente, CTRL + D cerrará el shell y lo pondrá nuevamente en la línea de comando de su terminal. Si desea cancelar un comando que está escribiendo y volver a un indicador de comandos limpio, mientras permanece dentro del intérprete de intérprete, use CTRL + C. Pruebe un shell interactivo de Python en línea . Otras conchas en línea Varios sitios web proporcionan acceso en línea a las conchas de Python. Los depósitos en línea pueden ser útiles para los siguientes propósitos: • Ejecute un pequeño fragmento de código desde una máquina que carece de la instalación de Python (teléfonos inteligentes, tabletas, etc.). • Aprende o enseña Python básico. • Resolver problemas de jueces en línea. Ejemplos: Descargo de responsabilidad: los autores de la documentación no están afiliados a los recursos que se enumeran a continuación. • https://www.python.org/shell/ - El shell de Python en línea alojado en el sitio web oficial de $ python -i hello.py "Hello World" >>> $ python3 Python 3.6.0 (default, Jan 13 2017, 00:00:00) [GCC 6.1.1 20160602] on linux Type "help", "copyright", "credits" or "license" for more information. >>> print('Hello, World') Hello, World >>>
    • 73. 8 $ python -c 'print("Hello, World")' Hello, World Python. • https://ideone.com/ : se utiliza ampliamente en la red para ilustrar el comportamiento del fragmento de código. • https://repl.it/languages/python3 - Compilador en línea, IDE e intérprete en línea potente y simple. Codifique, compile y ejecute el código en Python. • https://www.tutorialspoint.com/execute_python_online.php : shell UNIX con todas las funciones y un explorador de proyectos fácil de usar. • http://rextester.com/l/python3_online_compiler - IDE simple y fácil de usar que muestra el tiempo de ejecución Ejecutar comandos como una cadena Python puede pasar un código arbitrario como una cadena en el shell: Esto puede ser útil cuando se concatenan los resultados de los scripts juntos en el shell. Conchas y mas alla Administración depaquetes:la herramienta recomendadaporPyPAparainstalarpaquetesde Python es PIP . Para instalar, en su línea de comando ejecute pip install <the package name> . Por ejemplo, pip install numpy .(Nota: en Windows debe agregar pip asus variables de entorno PATH. Para evitar esto, use python -m pip install <the package name> ) Shells : hasta ahora, hemos discutido diferentes formas de ejecutar código usando el shell interactivo nativo de Python. Los shells utilizan el poder interpretativo de Python para experimentar con el código en tiempo real. Los shells alternativos incluyen IDLE , una GUI preempaquetada, IPython , conocida por extender la experiencia interactiva, etc. Programas : para el almacenamiento a largo plazo, puede guardar el contenido en archivos .py y editarlos / ejecutarlos como secuencias de comandos o programas con herramientas externas, como shell, IDE (como PyCharm ), cuadernos Jupyter , etc. Los usuarios intermedios pueden usar estas herramientas; sin embargo, los métodos discutidos aquí son suficientes para comenzar. El tutor de Python te permite recorrer el código de Python para que puedas visualizar cómo fluirá el programa, y te ayuda a entender dónde salió mal tu programa. PEP8 define las pautas para formatear el código Python. Formatear bien el código es importante para que pueda leer rápidamente lo que hace el código. Creando variables y asignando valores. Para crear una variable en Python, todo lo que necesita hacer es especificar el nombre de la
    • 74. 9 <variable name> = <value> # Integer a = 2 print(a) # Output: 2 # Integer b = 9223372036854775807 print(b) # Output: 9223372036854775807 # Floating point pi = 3.14 print(pi) # Output: 3.14 # String c = 'A' print(c) #Output: A # String name = 'John Doe' print(name) # Output: John Doe # Boolean q = True print(q) # Output: True # Empty value or null data type x = None print(x) # Output: None 0 = x => Output: SyntaxError: can't assign to literal import keyword print(keyword.kwlist) variable y luego asignarle un valor. Python usa = para asignar valores a las variables. No es necesario declarar una variable por adelantado (o asignarle un tipo de datos), al asignar un valor a una variable, se declara e inicializa la variable con ese valor. No hay forma de declarar una variable sin asignarle un valor inicial. La asignación de variables funciona de izquierda a derecha. Así que lo siguiente te dará un error de sintaxis. No puede utilizar palabras clave de python como un nombre de variable válido. Puedes ver la lista de palabras clave por:
    • 75. 10 x = True # valid _y = True # valid 9x = False # starts with numeral => SyntaxError: invalid syntax $y = False # starts with symbol => SyntaxError: invalid syntax has_0_in_it = "Still Valid" x = 9 y = X*5 =>NameError: name 'X' is not defined a = 2 print(type(a)) # Output: <type 'int'> b = 9223372036854775807 print(type(b)) # Output: <type 'int'> pi = 3.14 print(type(pi)) # Output: <type 'float'> c = 'A' print(type(c)) # Output: <type 'str'> name = 'John Doe' print(type(name)) # Output: <type 'str'> q = True print(type(q)) # Output: <type 'bool'> x = None print(type(x)) # Output: <type 'NoneType'> Reglas para nombrar variables: 1. Los nombres de las variables deben comenzar con una letra o un guión bajo. 2. El resto de su nombre de variable puede consistir en letras, números y guiones bajos. 3. Los nombres son mayúsculas y minúsculas. Aunque no es necesario especificar un tipo de datos al declarar una variable en Python, mientras se asigna el área necesaria en la memoria para la variable, el intérprete de Python selecciona automáticamente el tipo incorporado más adecuado para ella:
    • 76. 11 a_name = an_object # "a_name" is now a name for the reference to the object "an_object" a, b, c = 1, 2, 3 print(a, b, c) # Output: 1 2 3 a, b, c = 1, 2 => Traceback (most recent call last): => File "name.py", line N, in<module> => a, b, c = 1, 2 => ValueError: need more than 2 values to unpack a, b = 1, 2, 3 => Traceback (most recent call last): => File "name.py", line N, in<module> => a, b = 1, 2, 3 => ValueError: too many values to unpack a, b, _ = 1, 2, 3 print(a, b) # Output: 1, 2 a, b, _ = 1,2,3,4 =>Traceback (most recent calllast): =>File "name.py", line N, in <module> =>a, b, _ = 1,2,3,4 =>ValueError: too many values to unpack (expected 3) Ahora que conoce los conceptos básicos de la asignación, dejemos de lado esta sutileza acerca de la asignación en python. Cuando usa = para realizar una operación de asignación, lo que está a la izquierda de = es un nombre para el objeto a la derecha. Finalmente, lo que hace = es asignar la referencia del objeto a la derecha al nombre a la izquierda. Es decir: Entonces, de los muchos ejemplos de asignación anteriores, si seleccionamos pi = 3.14 , pi es un nombre (no el nombre, ya que un objeto puede tener varios nombres) para el objeto 3.14 . Si noentiende algo a continuación, vuelva a estepunto y lea esto nuevamente.Además, puedes echarle un vistazo a esto para una mejor comprensión. Puede asignar múltiples valores a múltiples variables en una línea. Tenga en cuenta que debe haber el mismo número de argumentos en los lados derecho e izquierdo del operador = : El error en el último ejemplo puede obviarse asignando valores restantes a un número igual de variables arbitrarias. Esta variable ficticia puede tener cualquier nombre, pero es convencional usar el subrayado ( _ ) para asignar valores no deseados: Tenga en cuenta que el número de _ y el número de valores restantes deben ser iguales. De lo contrario, se lanzan 'demasiados valores para descomprimir el error' como se indica arriba:
    • 77. 12 a = b = c = 1 print(a, b, c) # Output: 1 1 1 x = y = [7, 8, 9] # x and y refer to the same list object just created, [7, 8, 9] x = [13, 8, 9] # x now refers to a different list object just created, [13, 8, 9] print(y) # y still refers to the list it was first assigned # Output: [7, 8, 9] x = [1, 2, [3, 4, 5], 6, 7] # this is nested list print x[2] # Output: [3, 4, 5] print x[2][1] # Output: 4 También puede asignar un solo valor a varias variables simultáneamente. Cuando se utiliza dicha asignación en cascada, es importante tener en cuenta que las tres variables a , b y c se refieren al mismo objeto en la memoria, un int objeto con el valor de 1. En otras palabras, a , b y c son tres nombres diferentes dado al mismo objeto int.Asignar un objeto diferente a uno de ellos después no cambia los otros, como se esperaba: a = b = c = 1 print(a, b, c) # Output: 1 1 1 b = 2 print(a, b, c) # Output: 1 2 1 # all three names a, b and c refer to same int object with value 1 # b now refers to another int object, one with a value of 2 # so output is as expected. Loanteriortambiénesválidoparalostiposmutables(comolist ,dict,etc.),aligualqueparalos tipos inmutables (como int , string , tuple , etc.): Hasta ahora tan bueno. Las cosas son un poco diferentes cuando se trata de modificar el objeto (en contraste con asignar el nombre a un objeto diferente, como hicimos anteriormente) cuando la asignación en cascada se usa para tipos mutables. Echa un vistazo a continuación, y lo verás de primera mano: x = y = [7, 8, 9] [7, 8, 9] x[0] = 13 names, x in this case print(y) # Output: [13, 8, 9] # x and y are two different names for the same list object just created, # we are updating the value of the list [7, 8, 9] through one of its # printing the value of the list using its other name # hence, naturally the change is reflected Las listas anidadas también son válidas en python. Esto significa que una lista puede contener otra lista como un elemento. Por último, las variables en Python no tienen que ser del mismo tipo de las que se definieron por primera vez; simplemente puede usar = para asignar un nuevo valor a una variable, incluso si ese valor es de un tipo diferente.
    • 78. 13 name = raw_input("What is your name? ") # Out: What is your name? _ name = input("What is your name? ") # Out: What is your name? _ name = input("What is your name? ") # Out: What is your name? name = input("What is your name? ") # Out: What is your name? Bob print(name) # Out: Bob Si esto te molesta, piensa en el hecho de que lo que está a la izquierda de = es solo un nombre para un objeto. En primer lugar se llama a la int objeto con valor de 2 a , a continuación, cambia de opinión y decide dar el nombre a a una string objeto, que tiene un valor 'Valor nuevo'. Simple, ¿verdad? Entrada del usuario Entrada interactiva Para obtener información del usuario, use la función de input ( nota : en Python 2.x, la función se llama raw_input en raw_input lugar, aunque Python 2.x tiene su propia versión de input que es completamente diferente): Python 2.x 2.3 Observación de seguridad No use input() en Python2: el texto ingresado se evaluará como si fuera una expresión de Python (equivalente a eval(input()) en Python3), que podría convertirse fácilmente en una vulnerabilidad. Consulte este artículo para obtener más información sobre los riesgos de usar esta función. Python 3.x 3.0 El resto de este ejemplo utilizará la sintaxis de Python 3. La función toma un argumento de cadena, que lo muestra como una solicitud y devuelve una cadena. El código anterior proporciona un aviso, esperando que el usuario ingrese. Si el usuario escribe "Bob" y pulsa enter, el name la variable se asignará a la cadena "Bob" : a = 2 print(a) # Output: 2 a = "New value" print(a) # Output: New value
    • 79. 14 x = input("Write a number:") # Out: Write a number: 10 x / 2 #Out: TypeError: unsupported operand type(s)for/: 'str' and 'int' float(x) / 2 # Out: 5.0 Tengaen cuenta quela input siempre es de tipo str ,loque esimportantesi desea queel usuario ingresenúmeros.Porlotanto,necesitaconvertirelstrantesdeintentarusarlocomounnúmero: NB:serecomiendautilizarlosbloquesdetry/exceptparadetectarexcepcionescuandosetrata de entradas de usuario .Por ejemplo, si su código quiere convertir un raw_inputen un int , y lo que el usuario escribe es inasible, genera un ValueError . IDLE - GUI de Python IDLE es un entorno integrado de desarrollo y aprendizaje de Python y es una alternativa a la línea de comandos. Como su nombre puede implicar, IDLE es muy útil para desarrollar un nuevo código o aprender Python. En Windows, esto viene con el intérprete de Python, pero en otros sistemas operativos puede que necesite instalarlo a través de su administrador de paquetes. Los principales propósitos de IDLE son: • Editor de texto de múltiples ventanas con resaltado de sintaxis, autocompletado y sangría inteligente • Python shell con resaltado de sintaxis • Depurador integrado con pasos, puntos de interrupción persistentes y visibilidad de la pila de llamadas • Sangría automática (útil para los principiantes que aprenden sobre la sangría de Python) • Guardando el programa Python como archivos .py, ejecútelos y edítelos más tarde en cualquiera de ellos usando IDLE. En IDLE, presione F5 o run Python Shell para iniciar un intérprete. Usar IDLE puede ser una mejor experienciadeaprendizajeparalos nuevos usuarios porqueel códigoseinterpreta a medidaque el usuario escribe. Tenga en cuenta que hay muchas alternativas, vea, por ejemplo, esta discusión o esta lista . Solución de problemas • Windows SiestásenWindows,elcomandopredeterminadoespython .Sirecibeunerror "'python' is not recognized" Python "'python' is not recognized" , la causa más probable es que la ubicacióndePythonnoseencuentreenla PATH entorno PATH susistema.Sepuedeacceder aestohaciendoclicconelbotónderechoen'MiPC'yseleccionando'Propiedades'o navegandoa'Sistema' a través de'Panel de control'.Hagaclicen'Configuración avanzada delsistema'yluegoen'Variablesdeentorno...'.EditelavariablePATHparaincluirel
    • 80. 15 x or y # if x is False then y otherwise x x and y # if x is False then x otherwise y not x # if x is True then False, otherwise True directorio de su instalación de Python, así como la carpeta Script (generalmente C:\Python27;C:\Python27\Scripts ). Esto requiere privilegios administrativos y puede requerir un reinicio. Cuando se usan varias versiones de Python en la misma máquina, una posible solución es cambiar el nombre de uno de los archivos python.exe . Por ejemplo, nombrar una versión python27.exe haría que python27 convierta en el comando de Python para esa versión. También puedeusar elLanzadordePythonparaWindows, que estádisponiblea travésdel instaladoryvienepordefecto.LepermiteseleccionarlaversióndePythonparaejecutar usando py -[xy] lugar de python[xy] . Puede usarla última versión de Python 2 ejecutando scripts con py -2 y la última versión de Python 3 ejecutando scripts con py -3 . • Debian / Ubuntu / MacOS Esta sección asume que la ubicación del ejecutable de python se ha agregado a la PATH entorno PATH . Si estás en Debian / Ubuntu / MacOS, abre el terminal y escribe python para Python 2.xo python3 para Python 3.x. Escriba which python para ver qué intérprete de Python se utilizará. • Arco de linux El Python predeterminado en Arch Linux (y sus descendientes) es Python 3, así que usa python o python3 para Python python2 para Python 2.x. • Otros sistemas Python 3a veces está vinculado a python lugarde python3 .Para usarPython 2 en estos sistemas donde está instalado, puede usar python2 . Tipos de datos Tipos incorporados Booleanos bool : Un valor booleano de True o False . Las operaciones lógicas como and , or , not se pueden realizar en valores booleanos. EnPython2.xyenPython 3.x,un booleano estambiénunint .Eltipoboolesuna subclasedel tipo int y True y False son sus únicas instancias:
    • 81. 16 True + False == 1 # 1 + 0 == 1 True * True == 1 # 1 * 1 == 1 a = 2 b = 100 c = 123456789 d = 38563846326424324 a = 2.0 b = 100.e0 c = 123456789.e1 a = 2 + 1j b = 100 + 10j Si se usan valores booleanos en operaciones aritméticas, sus valores enteros ( 1 y 0 para True y False ) se usarán para devolver un resultado entero: Números • int : número entero Los enteros en Python son de tamaños arbitrarios. Nota: en versiones anteriores de Python, había un tipo long disponible y esto era distinto de int . Los dos se han unificado. • float : número de punto flotante; La precisión depende de la implementación y la arquitectura del sistema, para CPython el tipo de datos float corresponde a un C doble. • complex : números complejos Los operadores < , <= , > y >= generarán una excepción TypeError cuando cualquier operando sea un número complejo. Instrumentos de cuerda Python 3.x 3.0 • str:unacadenadeUnicode.Eltipode'hello' • bytes: una cadena de bytes .El tipo de b'hello' Python 2.x 2.7 issubclass(bool, int) # True isinstance(True, bool) # True isinstance(False, bool) # True
    • 82. 17 a = reversed('hello') a = (1, 2, 3) b = ('a', 1, 'python', (1, 2)) b[2] = 'something else' # returns a TypeError a = [1, 2, 3] b = ['a', 1, 'python', (1, 2), [1, 2]] b[2] = 'something else' # allowed a = {1, 2, 'a'} a = {1: 'one', 2: 'two'} b = {'a': [1, 2, 3], 'b': 'a string'} • str : una cadena de bytes . El tipo de 'hello' • bytes : sinónimo de str • unicode : una cadena de Unicode . El tipo de u'hello' Secuencias y colecciones. Python diferencia entre secuencias ordenadas y colecciones no ordenadas (como set y dict ). • Las cadenas ( str , bytes , unicode ) sonsecuencias. • reversed : un orden invertido de str con funciónreversed • tuple : una colección ordenada de n valores de cualquier tipo ( n >= 0 ). Soporta indexación; inmutable; hashable si todos sus miembros son hashable • list : una colección ordenada de n valores ( n >= 0) No hashable; mudable. • set : Una colección desordenada de valores únicos. Los artículos deben ser hashable . • dict : una colección desordenada de pares clave-valor únicos; Las claves deben ser hashable . Unobjetoeshashablesitieneunvalorhashquenuncacambiadurantesuvidaútil (necesitaun hash () )ypuedecompararseconotrosobjetos(necesitaun eq () ). Los objetos hashable que comparan la igualdad deben tener el mismo valor hash. Constantes incorporadas
    • 83. 18 a = None # No value will be assigned. Any valid datatype can be assigned later a = '123' print(type(a)) # Out: <class 'str'> b = 123 print(type(b)) # Out: <class 'int'> i = 7 if isinstance(i, int): i += 1 elif isinstance(i, str): i = int(i) i += 1 Junto con los tipos de datos incorporados, hay una pequeña cantidad de constantes incorporadas en el espacio de nombres integrado: • True : El valor verdadero del tipo incorporado bool • False : el valor falso del tipo incorporado bool • None : un objeto singleton utilizado para indicar que un valor está ausente. • Ellipsis o ...: se utiliza en Python3 + en cualquier lugar y uso limitado en Python2.7 + como parte de la notación de matriz. numpy paquetes numpy y relacionados usan esto como una referencia 'incluir todo' en los arreglos. • NotImplemented : un singleton utilizado para indicar a Python que un método especial no es compatible con los argumentos específicos, y Python probará alternativas si están disponibles. Python 3.x 3.0 None no tiene ningún orden natural. El uso de operadores de comparación de pedidos ( < , <= , >= , > ) ya no es compatible y generará un TypeError . Python 2.x 2.7 None siempre es menor que cualquier número ( None < -32 evalúa como True ). Probando el tipo de variables En Python, podemos verificar el tipo de datos de un objeto usando el type función incorporada. En declaraciones condicionales es posible probar el tipo de datos con isinstance . Sin embargo, generalmente no se recomienda confiar en el tipo de variable. Para obtenerinformación sobrelas diferenciasentre type()y isinstance()lea: Diferencias entre isinstance y type enPython Para probar si algo es de NoneType :
    • 84. 19 a = '123' b = int(a) a = '123.456' b = float(a) c = int(a) # ValueError: invalid literal for int() with base 10: '123.456' d = int(b) # 123 a = 'hello' list(a) # ['h', 'e', 'l', 'l', 'o'] set(a) # {'o', 'e', 'l', 'h'} tuple(a) # ('h', 'e', 'l', 'l', 'o') # foo # bar # foo\nbar raw = r'foo\nbar' # foo\nbar normal = 'foo\nbar' escaped = 'foo\\nbar' Convertir entre tipos de datos Puede realizar la conversión explícita de tipos de datos. Por ejemplo, '123' es de tipo str y se puede convertir en entero usando la función int . La conversión de una cadena flotante como '123.456' se puede hacer usando la función float . También puedes convertir secuencias o tipos de colección. Tipo de cadena explícita en la definición de literales Con las etiquetas de una letra justo delante de las comillas, puede indicar qué tipo de cadena desea definir. • b'foo bar' : bytes resultados en Python 3, str en Python2 • u'foo bar' : results str en Python 3, unicode en Python2 • 'foo bar' : resultados str • r'foo bar':resultados llamados cadenas enbruto,dondenoesnecesarioescapar caracteres especiales, todo setoma literalmente a medida que se escribe x = None if x is None: print('Not a surprise, I just defined x as None.')
    • 85. 20 def f(m): m.append(3) # adds a number to the list. This is a mutation. x = [1, 2] f(x) x == [1, 2] # False now, since an item was added to the list def bar(): x = (1, 2) g(x) x == (1, 2) # Will always be True, since no function can change the object (1, 2) >>> pow(2,3) #8 Tipos de datos mutables e inmutables Un objeto se llama mutable si se puede cambiar. Por ejemplo, cuando pasa una lista a alguna función, la lista se puede cambiar: Un objeto se llama inmutable si no se puede cambiar de ninguna manera. Por ejemplo, los enteros son inmutables, ya que no hay forma de cambiarlos: Tenga en cuenta que las variables en sí mismas son mutables, por lo que podemos reasignar la variable x , pero esto no cambia el objeto al que x había apuntado anteriormente. Solo hizo que x apunte a un nuevo objeto. Los tipos de datos cuyas instancias son mutables se denominan tipos de datos mutables , y de manera similar para los objetos y tipos de datos inmutables. Ejemplos de tipos de datos inmutables: • int , long , float , complex • str • bytes • tuple • frozenset Ejemplos de tipos de datos mutables: • bytearray • list • set • dict Construido en módulos y funciones Un módulo es un archivo que contiene definiciones y declaraciones de Python. La función es un fragmento de código que ejecuta alguna lógica. Para verificar la función incorporada en python podemos usar dir(). Si se llama sin un
    • 86. 21 argumento, devuelve los nombres en el alcance actual. De lo contrario, devuelve una lista alfabética de nombres que comprenden (algunos de) el atributo del objeto dado y de los atributos a los que se puede acceder. >>> dir( builtins ) [ 'ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', ' debug ',
    • 87. 22 ' doc ', ' import ', ' name ', ' package', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct',
    • 88. 23 >>> help(max) Help on built-in function max in module builtin : max(...) max(iterable[, key=func]) -> value max(a, b, c, ...[, key=func]) -> value With a single iterable argument, return its largest item. With two or more arguments, return the largest argument. >>> import math >>> math.sqrt(16) # 4.0 >>> import math >>> dir(math) [' doc ', ' name ', ' package ', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', Para conocer la funcionalidad de cualquier función, podemos utilizar la help incorporada de la función. Los módulos incorporados contienen funcionalidades adicionales. Por ejemplo, para obtener la raíz cuadrada de un número, necesitamos incluir math módulo math . Para conocer todas las funciones de un módulo, podemos asignar la lista de funciones a una variable y luego imprimir la variable. 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip' ]
    • 89. 24 >>> math. doc 'This module is always available. It provides access to the\nmathematical functions defined by the Cstandard.' """This is the module docstring.""" def sayHello(): """This is the function docstring.""" return 'Hello World' >>> import helloWorld >>> helloWorld. doc 'This is the module docstring.' >>> helloWorld.sayHello. doc 'This is the function docstring.' >>> class MyClassObject(object): ... pass ... >>> dir(MyClassObject) [' class ', ' delattr ', ' dict ', ' doc ', ' format ', ' getattribute ', ' hash ', ' init ', ' module ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' setattr ', ' sizeof ', ' str ', ' subclasshook ', ' weakref '] >>> str(123) # "123" Parece que doc es útil para proporcionar alguna documentación en, digamos, funciones Además de las funciones, la documentación también se puede proporcionar en módulos. Entonces, si tienes un archivo llamado helloWorld.py como este: Puedes acceder a sus documentos como este: • Para cualquier tipo definido por el usuario, sus atributos, los atributos de su clase y recursivamente los atributos de las clases base de su clase se pueden recuperar usando dir () Cualquier tipo de datos se puede convertir simplemente a cadena usando una función incorporada llamada str .Esta función se llama de forma predeterminada cuando se pasa un tipo de datos para print Sangría de bloque Python utiliza la sangría para definir el control y las construcciones de bucle. Esto contribuye a la legibilidad de Python, sin embargo, requiere que el programador preste mucha atención al uso del espacio en blanco. Por lo tanto, la mala calibración del editor podría resultar en un código que se 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
    • 90. 25 def my_function(): # This is a function definition. Note the colon (:) a = 2 # This line belongs to the function because it's indented return a # This line also belongs to the same function print(my_function()) # This line is OUTSIDE the functionblock if a > b: print(a) else: print(b) if x > y: y = x print(y) # IndentationError: unexpected indent if x > y: while y != z: y -= 1 # SyntaxError: invalid syntax def will_be_implemented_later(): pass comporta de manera inesperada. Python usa el símbolo de dos puntos ( : ) y sangría para mostrar dónde bloques de código empiezan y terminan (Si viene de otro idioma, no confunda esto con alguna manera estar relacionado con el operador ternario ).Es decir,los bloques enPython, tales como funciones, bucles,cláusulas ifyotras construcciones,notienenidentificadores finales.Todoslosbloques comienzan con dos puntos y luego contienen las líneas sangradas debajo de él. Por ejemplo: o if a > b: print(a) else: print(b) # If block starts here # This is part of the if block # else must be at the same level as if # This line is part of the else block Los bloques que contienen exactamente una instrucción de una sola línea se pueden colocar en la misma línea, aunque esta forma generalmente no se considera un buen estilo: Intentar hacer esto con más de una sola declaración no funcionará: Un bloque vacío causa un IndentationError . Use pass (un comando que no hace nada) cuando tiene un bloque sin contenido: Espacios vs. Pestañas En resumen: siempre usa 4 espacios para la sangría. El uso exclusivo de pestañas es posible, pero PEP 8 , la guía de estilo para el código Python, indica que se prefieren los espacios. Python 3.x 3.0
    • 91. 26 int_list = [1, 2, 3] string_list = ['abc', 'defghi'] Python3nopermitemezclar elusodetabulacionesyespaciosparalasangría.Entalcaso,se genera un error en tiempo de compilación: Inconsistent use of tabs and spaces in indentation y el programa no se ejecutará. Python 2.x 2.7 Python 2 permite mezclar tabulaciones y espacios en sangría; Esto es fuertemente desalentado. El carácter de la pestaña completa la sangría anterior para ser un múltiplo de 8 espacios . Como es común que los editores estén configurados para mostrar pestañas como múltiplos de 4 espacios, esto puede causar errores sutiles. Citando el PEP 8 : Cuandoseinvocaal intérpretedelíneadecomandosdePython2conlaopción -t, emite advertencias sobre el código que mezcla de forma ilegal las pestañas y los espacios.Al usar -tt estas advertencias se convierten en errores.Estas opciones son muy recomendables! Muchos editores tienen configuración de "pestañas a espacios". Al configurar el editor, uno debe diferenciar entre el carácter de la pestaña ('\ t') y la tecla Tab . • El carácter de la pestaña debe configurarse para mostrar 8 espacios, para que coincida con la semántica del idioma, al menos en los casos en que es posible una sangría (accidental). Los editores también pueden convertir automáticamente el carácter de tabulación a espacios. • Sin embargo, puede ser útil configurar el editor para que al presionar la tecla Tab , se inserten 4 espacios, en lugar de insertar un carácter de pestaña. El código fuente de Python escrito con una combinación de tabulaciones y espacios, o con un número no estándar de espacios de sangría se puede hacer compatible con pep8 usando autopep8 . (Una alternativa menos poderosa viene con la mayoría de las instalaciones de Python: reindent.py ) Tipos de colección Hayvarios tiposdecoleccionesenPython.Mientrasquelostiposcomointystrtienenunsolo valor, los tipos de colección tienen múltiplesvalores. Liza El tipo de list es probablemente el tipo de colección más utilizado en Python. A pesar de su nombre, una lista es más como una matriz en otros idiomas, principalmente JavaScript. En Python, una lista es simplemente una colección ordenada de valores válidos de Python. Se puede crear una lista encerrando valores, separados por comas, entre corchetes: Una lista puede estar vacía:
    • 92. 27 mixed_list = [1, 'abc', True, 2.34, None] nested_list = [['a', 'b', 'c'], [1, 2, 3]] names = ['Alice', 'Bob', 'Craig', 'Diana', 'Eric'] print(names[0]) # Alice print(names[2]) # Craig print(names[-1]) # Eric print(names[-4]) # Bob names[0] = 'Ann' print(names) # Outputs ['Ann', 'Bob', 'Craig', 'Diana', 'Eric'] names.insert(1, "Nikki") print(names) # Outputs ['Alice', 'Nikki', 'Bob', 'Craig', 'Diana', 'Eric', 'Sia'] names.remove("Bob") Los elementos de una lista no están restringidos a un solo tipo de datos, lo que tiene sentido dado que Python es un lenguaje dinámico: Una lista puede contener otra lista como su elemento: Se puede acceder a los elementos de una lista a través de un índice o representación numérica de su posición. Las listas en Python tienen índice cero, lo que significa que el primer elemento de la lista está en el índice 0, el segundo elemento está en el índice 1 y así sucesivamente: Los índices también pueden ser negativos, lo que significa contar desde el final de la lista ( -1 es el índice del último elemento). Entonces, usando la lista del ejemplo anterior: Las listas son mutables, por lo que puede cambiar los valores en una lista: Además, es posible agregar y / o eliminar elementos de una lista: Agregar objeto al final de la lista con L.append(object) , devuelve None . Agregue un nuevo elemento a la lista en un índice específico. L.insert(index, object) Elimine la primera aparición de un valor con L.remove(value) , devuelve None names = ['Alice', 'Bob', 'Craig', 'Diana', 'Eric'] names.append("Sia") print(names) # Outputs ['Alice', 'Bob', 'Craig', 'Diana', 'Eric', 'Sia'] empty_list = []
    • 93. 28 name.index("Alice") 0 len(names) 6 a = [1, 1, 1, 2, 3, 4] a.count(1) 3 a.reverse() [4, 3, 2, 1, 1, 1] # or a[::-1] [4, 3, 2, 1, 1, 1] names.pop() # Outputs 'Sia' for element in my_list: print (element) ip_address = ('10.20.30.40', 8080) Obtenga el índice en la lista del primer elemento cuyo valor es x. Se mostrará un error si no hay tal elemento. Cuenta la longitud de la lista cuenta la ocurrencia de cualquier artículo en la lista Revertir la lista Elimine y devuelva el elemento en el índice (predeterminado al último elemento) con L.pop([index]) , devuelve el elemento Puede iterar sobre los elementos de la lista como a continuación: Tuplas Una tuple es similar a una lista, excepto que es de longitud fija e inmutable. Por lo tanto, los valores de la tupla no se pueden cambiar ni los valores se pueden agregar o quitar de la tupla. Las tuplas se usan comúnmente para pequeñas colecciones de valores que no será necesario cambiar, como una dirección IPyunpuerto. Las tuplas se representan conparéntesis enlugar de corchetes: Las mismas reglas de indexación para las listas también se aplican a las tuplas. Las tuplas también se pueden anidar y los valores pueden ser válidos para cualquier Python válido. print(names) # Outputs ['Alice', 'Nikki', 'Craig', 'Diana', 'Eric', 'Sia']
    • 94. 29 one_member_tuple = ('Only member',) one_member_tuple = 'Only member', # No brackets one_member_tuple = tuple(['Only member']) state_capitals = { 'Arkansas': 'Little Rock', 'Colorado': 'Denver', 'California': 'Sacramento', 'Georgia': 'Atlanta' } ca_capital = state_capitals['California'] for k in state_capitals.keys(): print('{} is the capital of {}'.format(state_capitals[k], k)) first_names = {'Adam', 'Beth', 'Charlie'} Una tupla con un solo miembro debe definirse (tenga en cuenta la coma) de esta manera: o o simplemente usando la sintaxis de la tuple Los diccionarios Un dictionary en Python es una colección de pares clave-valor. El diccionario está rodeado de llaves. Cada par está separado por una coma y la clave y el valor están separados por dos puntos. Aquí hay un ejemplo: Para obtener un valor, consúltelo por su clave: También puede obtener todas las claves en un diccionario y luego repetirlas: Los diccionarios se parecen mucho a la sintaxis JSON. El módulo json nativo en la biblioteca estándar de Python se puede usar para convertir entre JSON y diccionarios. conjunto Un setes una colección de elementos sin repeticiones y sin orden de inserción pero ordenado. Se usan en situaciones en las que solo es importante que algunas cosas se agrupen y no en qué ordenseincluyeron.Paragruposgrandesde datos,es mucho más rápidoverificar si unelemento está o no en un set que hacer lo mismo para una list. Definirunsetesmuysimilaradefinirundictionary: Opuedesconstruir unset usandounalistexistente:
    • 95. 30 if name in first_names: print(name) >>> state_capitals = { 'Arkansas': 'Little Rock', 'Colorado': 'Denver', 'California': 'Sacramento', 'Georgia': 'Atlanta' } >>> state_capitals['Alabama'] Traceback (most recent call last): File "<ipython-input-61-236329695e6f>", line 1, in <module> state_capitals['Alabama'] KeyError: 'Alabama' >>> from collections import defaultdict >>> state_capitals = defaultdict(lambda: 'Boston') >>> state_capitals['Arkansas'] = 'Little Rock' >>> state_capitals['California'] = 'Sacramento' Verifique la membresía del set usando in : Puede iterar sobre un set exactamente como una lista, pero recuerde: los valores estarán en un orden arbitrario, definido por la implementación. sentencia por defecto Un defaultdict es un diccionario con un valor por defecto para las llaves, por lo que las claves para el que ha sido definida explícitamente ningún valor se puede acceder sin errores. defaultdict es especialmente útil cuando los valores del diccionario son colecciones (listas, dicts, etc.) en el sentido de que no es necesario inicializar cada vez que se usa una nueva clave. Undefaultdict nuncagenerará unKeyError.Cualquier clavequeno existaobtiene el valor predeterminado devuelto. Por ejemplo, considere el siguiente diccionario Si intentamos acceder a una clave que no existe, Python nos devuelve un error de la siguiente manera Probemos con un defaultdict . Se puede encontrar en el módulo de colecciones. Lo que hicimos aquí es establecer un valor predeterminado ( Boston ) en caso de que la clave de asignación no exista. Ahora rellena el dict como antes: my_list = [1,2,3] my_set = set(my_list)
    • 96. 31 >>> state_capitals['Alabama'] 'Boston' >>> state_capitals['Arkansas'] 'Little Rock' >>> help() >>> help(help) help> help Thisis a wrapper around pydoc.help that provides a helpful message when 'help' is typed at the Python interactive prompt. Calling help() at the Python prompt starts an interactive help session. Calling help(thing) prints help for the python object 'thing'. Methods defined here: call (self, *args, **kwds) repr (self) ---------------------------------------------------------------------- Data descriptors defined here: dict | Define the builtin'help'. | | | | | | | | | | | | | | | | | Help on _Helper in module _sitebuiltins object: class _Helper(builtins.object) Si intentamos acceder al dict con una clave que no existe, Python nos devolverá el valor predeterminado, es decir, Boston y devuelve los valores creados para la clave existente al igual que un dictionary normal Utilidad de ayuda Python tiene varias funciones integradas en el intérprete. Si desea obtener información sobre palabras clave, funciones incorporadas, módulos o temas, abra una consola de Python e ingrese: Recibirá información ingresando palabras clave directamente: o dentro de la utilidad: que mostrará una explicación: = 'Denver' >>> state_capitals['Georgia'] = 'Atlanta' >>> state_capitals['Colorado']
    • 97. 32 help(pymysql.connections) >>> help(math) >>> import math >>> help(math) $ python >>> import hello >>> hello.say_hello() => "Hello!" # greet.py import hello hello.say_hello() También puedes solicitar subclases de módulos: Puede usar la ayuda para acceder a las cadenas de documentación de los diferentes módulos que ha importado, por ejemplo, intente lo siguiente: y obtendrás un error Y ahora obtendrá una lista de los métodos disponibles en el módulo, pero solo DESPUÉS de haberlo importado. Cerrar el ayudante con quit Creando un modulo Un módulo es un archivo importable que contiene definiciones y declaraciones. Se puede crear un módulo creando un archivo .py . Las funciones en un módulo se pueden utilizar importando el módulo. Para los módulos que haya creado, deberán estar en el mismo directorio que el archivo en el que los está importando. (Sin embargo, también puede colocarlos en el directorio lib de Python con los módulos pre-incluidos, pero debe evitarse si es posible). Los módulos pueden ser importados por otros módulos. # hello.py def say_hello(): print("Hello!") weakref list of weak references to the object (if defined) | dictionary for instance variables (if defined) | | |
    • 98. 33 # greet.py from hello import say_hello say_hello() # greet.py import hello as ai ai.say_hello() # run_hello.py if name == ' main ': from hello import say_hello say_hello() $ python run_hello.py => "Hello!" Se pueden importar funciones específicas de un módulo. Los módulos pueden ser alias. Un módulo puede ser un script ejecutable independiente. ¡Ejecutarlo! Siel módulo estádentro de un directorio y necesita serdetectado por python,el directorio debe contener un archivo llamado init .py . Función de cadena - str () y repr () Hay dos funciones que se pueden usar para obtener una representación legible de un objeto. repr(x)llamaax. repr ():unarepresentacióndex. evalgeneral, evalconvertiráelresultado de esta función al objetooriginal. str(x)llamaax. str ():unacadenalegibleporhumanosquedescribeelobjeto.Estopuede ocultar algunos detalles técnicos. repr () Paramuchos tipos,esta funciónintentadevolverunacadenaqueproduciríaunobjetoconel mismo valor cuando se pasa a eval() . De lo contrario, la representación es una cadena encerrada entre paréntesis angulares que contiene el nombre del tipo del objeto junto con información adicional. Esto a menudo incluye el nombre y la dirección del objeto. str () Para las cadenas, esto devuelve la cadena en sí. La diferencia entre esto y repr(object) es que str(object) no siempre intenta devolver una cadena que sea aceptable para eval() . Más bien, su
    • 99. 34 s = """w'o"w""" repr(s) # Output: '\'w\\\'o"w\'' str(s) # Output: 'w\'o"w' eval(str(s)) == s # Gives a SyntaxError eval(repr(s)) == s # Output: True import datetime today = datetime.datetime.now() str(today) # Output: '2016-09-15 06:58:46.915000' repr(today) # Output: 'datetime.datetime(2016, 9, 15, 6, 58, 46, 915000)' class Represent(object): def init (self, x, y): self.x, self.y = x, y def repr (self): return "Represent(x={},y=\"{}\")".format(self.x, self.y) def str (self): return "Representing x as {} and y as {}".format(self.x, self.y) r = Represent(1, "Hopper") print(r) # prints str print(r. repr ) # prints repr : '<bound methodRepresent. repr of Represent(x=1,y="Hopper")>' rep = r. repr () # sets the execution of repr to a new variable print(rep) # prints 'Represent(x=1,y="Hopper")' r2 = eval(rep) # evaluates rep print(r2) # prints str from new object print(r2 == r) # prints 'False' because they are different objects objetivoesdevolverunacadena imprimible o "legiblepara humanos".Si no seda ningún argumento, esto devuelve la cadena vacía, ''. Ejemplo 1: Ejemplo 2: Al escribir una clase, puede anular estos métodos para hacer lo que quiera: Usando la clase anterior podemos ver los resultados: Instalación de módulos externos utilizando pip pip es tu amigo cuando necesitas instalar cualquier paquete de la gran cantidad de opciones disponibles en el índice del paquete python (PyPI). pip ya está instalado si estás usando Python 2> = 2.7.9 o Python 3> = 3.4 descargado desde python.org. Para computadoras que ejecutan Linux u otro * nix con un administrador de paquetes nativo, pip debe instalarse manualmente. En instancias con Python 2 y Python 3 instalados, pip menudo se refiere a Python 2 y pip3 a Python 3. El uso de pip solo instalará paquetes para Python 2 y pip3 solo instalará paquetes para
    • 100. 35 $ pip search <query> # Searches for packages whose name or summary contains <query> $ pip install '[package_name]>=x.x.x' # minimum version of the package $ pip install [package_name]==x.x.x # specific version of the package $ pip install [package_name] # latest version of the package $ pip --proxy http://<server address>:<port> install $ pip list --outdated $ pip install [package_name] --upgrade Python 3. Encontrar / instalar un paquete La búsqueda de un paquete es tan simple como escribir Instalar un paquete es tan simple como escribirlo (en un terminal / símbolo del sistema, no en el intérprete de Python) donde xxx es el número de versión del paquete que desea instalar. Cuando su servidor está detrás de proxy, puede instalar el paquete usando el siguiente comando: Actualización de paquetes instalados Cuando aparecen nuevas versiones de paquetes instalados, no se instalan automáticamente en su sistema. Para obtener una descripción general de cuáles de sus paquetes instalados están desactualizados, ejecute: Para actualizar el uso de un paquete específico Actualizar todos los paquetes obsoletos no es una funcionalidad estándar de pip . Actualización de pip Puede actualizar su instalación pip existente usando los siguientes comandos • En Linux o macOS X:
    • 101. 36 py -m pip install -U pip python -m pip install -U pip C:\Python27\ python --version Es posible que necesite usar sudo con pip en algunos sistemas Linux • En Windows: o Para más información sobre pip, lea aquí . Instalación de Python 2.7.xy 3.x Nota : las siguientes instrucciones están escritas para Python 2.7 (a menos que se especifique): las instrucciones para Python 3.x son similares. VENTANAS Primero, descargue la última versión de Python 2.7 del sitio web oficial ( https://www.python.org/downloads/) . La versión se proporciona como un paquete MSI. Para instalarlo manualmente, simplemente haga doble clic en el archivo. Por defecto, Python se instala en un directorio: Advertencia: la instalación no modifica automáticamente la variable de entorno PATH. Suponiendo que su instalación de Python está en C: \ Python27, agregue esto a su PATH: Ahora para comprobar si la instalación de Python es válida, escriba en cmd: Python 2.xy 3.x lado a lado Para instalar y usar Python 2.xy 3.x lado a lado en una máquina con Windows: 1. Instale Python 2.x usando el instalador MSI. • Asegúrese de que Python esté instalado para todos los usuarios. • Opcional:agreguePython a PATH para hacer quePython 2.xse puedallamardesdela línea de comandos usando python . C:\Python27\;C:\Python27\Scripts\ $ pip install -U pip
    • 102. 37 P:\>py -3 Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> C:\>py -2 Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> C:\>py -3 -m pip -V pip 9.0.1 from C:\Python36\lib\site-packages (python 3.6) C:\>py -2 -m pip -V pip 9.0.1 from C:\Python27\lib\site-packages (python 2.7) wget --no-check-certificate https://www.python.org/ftp/python/2.7.X/Python-2.7.X.tgz tar -xzf Python-2.7.X.tgz cd Python-2.7.X ./configure make sudo make install python --version 2. Instala Python 3.x usando su respectivo instalador. • Una vez más, asegúrese de que Python esté instalado para todos los usuarios. • Opcional: agregue Python a PATH para que Python 3.x se pueda llamar desde la línea de comandos usando python . Esto puede anular la configuración de Python 2.x PATH , porlo tanto, vuelva a verificar su PATH y asegúrese de que esté configurado según sus preferencias. • Asegúrate de instalar el py launcher para todos los usuarios. Python 3 instalará el iniciador de Python que se puede usar para lanzar Python 2.xy Python 3.x indistintamente desde la línea de comandos: Para usar la versión correspondiente de pip para una versión específica de Python, use: LINUX Las últimas versiones de CentOS, Fedora, Redhat Enterprise (RHEL) y Ubuntu vienen con Python 2.7. Para instalar Python 2.7 en linux manualmente, simplemente haga lo siguiente en la terminal: También agregue la rutadel nuevo python en lavariable de entornoPATH.Si el nuevo python está en /root/python-2.7.X , ejecute export PATH = $PATH:/root/python-2.7.X Ahora para comprobar si la instalación de Python es válida, escriba en el terminal: Ubuntu (desde la fuente)
    • 103. 38 sudo apt install build-essential checkinstall sudo apt install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tar.xz tar xvf Python-3.6.1.tar.xz cd Python-3.6.1/ ./configure --enable-optimizations sudo make altinstall /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" brew install python Si necesita Python 3.6, puede instalarlo desde la fuente como se muestra a continuación (Ubuntu y 17.04 tienen la versión 3.6 en el repositorio universal). Deben seguirse los siguientes pasos para Ubuntu 16.04 y versiones inferiores: Mac OS Mientras hablamos, macOS viene instalado con Python 2.7.10, pero esta versión está desactualizada y ligeramente modificada de Python regular. La versión de Python que se incluye con OS X es excelente para el aprendizaje, pero no es buena para el desarrollo. La versión enviada con OS X puede estar desactualizada de la versión oficial actual de Python, que se considera la versión de producción estable. ( fuente ) Instalar Homebrew : Instala Python 2.7: Para Python 3.x, use el comando brew install python3 en brew install python3 lugar.
    • 104. 39 def func(*args, **kwargs): print(args) print(kwargs) def func(*a, **b): print(a) print(b) def func(*args1, *args2): # File "<stdin>", line 1 # def test(*args1, *args2): # ^ # SyntaxError: invalid syntax def test(**kwargs1, **kwargs2): # File "<stdin>", line 1 # def test(**kwargs1, **kwargs2): # ^ # SyntaxError: invalid syntax def func(a, b, *args, x, y): print(a, b, args, x, y) func(1, 2, 3, 4, x=5, y=6) #>>> 1, 2, (3, 4), 5, 6 def func(a, b, *, x, y): Capítulo 2: * args y ** kwargs Observaciones Hay algunas cosas a tener en cuenta: 1. Los nombres args y kwargs se usan por convención, no forman parte de la especificación del lenguaje. Por lo tanto, estos sonequivalentes: 2. No puede tener más de un args o más de un parámetro de kwargs (sin embargo, no son necesarios) 3. Si algún argumento posicional sigue a *args , son argumentos de palabra clave que solo se pueden pasar por nombre. Se puede usar una sola estrella en lugar de *args para forzar que los valores sean argumentos de palabras clave sin proporcionar una lista de parámetros variadic. Las listas de parámetros de palabras clave solo están disponibles en Python 3.
    • 105. 40 def test(**kwargs, *args): # File "<stdin>", line 1 # def test(**kwargs, *args): # ^ # SyntaxError: invalid syntax def print_args(farg, *args): print("formal arg: %s" % farg) for arg in args: print("another positional arg: %s" % arg) print_args(1, "two", 3) def print_kwargs(**kwargs): print(kwargs) print_kwargs(a="two", b=3) # prints: "{a: "two", b=3}" 4. **kwargs deben estar en último lugar en la lista de parámetros. Examples Usando * args al escribir funciones Puede usar la estrella * al escribir una función para recopilar todos los argumentos posicionales (es decir, sin nombre) en una tupla: Método de llamada: En esa llamada, farg se asignará como siempre, y los otros dos se introducirán en la tupla de args, en el orden en que se recibieron. Usando ** kwargs al escribir funciones Puede definir una función que tome un número arbitrario de argumentos de palabra clave (nombrados) usando la estrella doble ** antes del nombre de un parámetro: Al llamar al método, Python construirá un diccionario de todos los argumentos de palabras clave y lo pondrá a disposición en el cuerpo de la función: Tenga en cuenta que el parámetro ** kwargs en la definición de la función siempre debe ser el último parámetro, y solo coincidirá con los argumentos que se pasaron después de los anteriores. print(a, b, x, y) func(1, 2, x=5, y=6) #>>> 1, 2, 5, 6
    • 106. 41 def print_kwargs(**kwargs): for key in kwargs: print("key = {0}, value = {1}".format(key, kwargs[key])) print_kwargs(a = "two", b = 1) key = a, value = "two" key = b, value = 1 class A(object): def init (self, b, c): self.y = b self.z = c class B(A): def init (self, a, *args, **kwargs): super(B, self). init (*args, **kwargs) self.x = a b = B(1, 2, 3) # 1 # 2 # 3 Dentro del cuerpo de la función, los kwargs se manipulan de la misma manera que un diccionario; para acceder a elementos individuales en kwargs , solo tienes que recorrerlos como lo harías con un diccionario normal: Ahora, al llamar a print_kwargs(a="two", b=1) muestra el siguiente resultado: Usando * args al llamar a funciones Un caso de uso común para *args en una definición de función es delegar el procesamiento a una función envuelta o heredada. Un ejemplo típico podría estar en el método init una clase Aquí,el a parámetro es procesado porlaclase niño después de todos los otros argumentos (posicionales y de palabras clave) son pasados a - y procesados por -la clase base. Por ejemplo: Lo que sucede aquí es que la función de clase B init ve los argumentos 1, 2, 3 . Sabe que necesita tomar un argumento posicional ( a ), porlo que toma el primer argumento pasado en ( 1 ), por lo que en el alcance de la función a == 1. Acontinuación,vequenecesitatomarunnúmeroarbitrariodeargumentosposicionales(*args), porlo que toma el resto de los argumentos posicionales pasados en ( 1, 2 ) y los mete en *args. Ahora (en el ámbito de la función) args == [2, 3] . def example(a, **kw): print kw example(a=2, b=3, c=4) # => {'b': 3, 'c': 4}
    • 107. 42 def test_func(arg1, arg2, arg3): # Usual function with three arguments print("arg1: %s" % arg1) print("arg2: %s" % arg2) print("arg3: %s" % arg3) # Note that dictionaries are unordered, so we can switch arg2 and arg3. Only the names matter. kwargs = {"arg3": 3, "arg2": "two"} # Bind the first argument (ie. arg1) to 1, and use the kwargs dictionary to bind the others test_var_args_call(1, **kwargs) def print_args(arg1, arg2): print(str(arg1) + str(arg2)) a = [1,2] b = tuple([3,4]) print_args(*a) # 12 print_args(*b) # 34 a = [1,3,5,7,9] b = [2,4,6,8,10] zipped = zip(a,b) # [(1,2), (3,4), (5,6), (7,8), (9,10)] zip(*zipped) Luego, llama a la función init clase A con *args . Python ve el * delante de args y "desempaqueta"lalistaenargumentos.En esteejemplo, cuandolaclase B's init llamadas de función de clase A ' s init función, será pasado los argumentos 2, 3 (es decir, A(2, 3)). Finalmente, establece su propia propiedad x en el primer argumento posicional a , que es igual a 1 . Usando ** kwargs al llamar a funciones Puede usar un diccionario para asignar valores a los parámetros de la función; usando los parámetros nombre como claves en el diccionario y el valor de estos argumentos enlazados a cada clave: Usando * args al llamar a funciones El efecto de usar el operador * en un argumento al llamar a una función es el de desempaquetar la lista o un argumento de tupla Tenga en cuenta que la longitud del argumento destacado debe ser igual al número de argumentos de la función. Un lenguaje común en Python es usar el operador de desempaquetado * con la función zip para revertir sus efectos:
    • 108. 43 def print_args(arg1, *args, keyword_required, keyword_only=True): print("first positional arg: {}".format(arg1)) for arg in args: print("another positional arg: {}".format(arg)) print("keyword_required value: {}".format(keyword_required)) print("keyword_only value: {}".format(keyword_only)) print(1, 2, 3, 4) # TypeError: print_args() missing 1 required keyword-only argument: 'keyword_required' print(1, 2, 3, keyword_required=4) def foobar(foo=None, bar=None): return "{}{}".format(foo, bar) values = {"foo": "foo", "bar": "bar"} foobar(**values) # "foobar" def fun(**kwargs): print kwargs.get('value', 0) fun() # print 0 fun(value=1) # print 1 Argumentos solo de palabra clave y requeridos de palabra clave Python 3 le permite definir argumentos de función que solo pueden asignarse por palabra clave, incluso sin valores predeterminados. Esto se hace usando star * para consumir parámetros posicionales adicionales sin configurar los parámetros de palabras clave. Todos los argumentos después del * son argumentos de palabra clave solamente (es decir, no posicionales). Tenga en cuenta que si los argumentos de solo palabras clave no tienen un valor predeterminado, todavía son necesarios al llamar a la función. # first positional arg: 1 # another positional arg: 2 # another positional arg: 3 # keyword_required value: 4 # keyword_only value: True Poblando los valores kwarg con un diccionario ** kwargs y valores por defecto Para usar los valores por defecto con ** kwargs # (1,3,5,7,9), (2,4,6,8,10)
    • 109. 44 Capítulo 3: Acceso a la base de datos Observaciones Python puede manejar muchos tipos diferentes de bases de datos. Para cada uno de estos tipos existe una API diferente. Así que fomente la similitud entre esas diferentes API, se haintroducido PEP 249. Esta API se ha definido para fomentar la similitud entre los módulos de Python que se utilizan para acceder a las bases de datos. Al hacer esto, esperamos lograr una consistencia que conduzca a módulos más fáciles de entender, código que generalmente es más portátil en las bases de datos y un mayor alcance de la conectividad de base de datos de Python. PEP-249 Examples Accediendo a la base de datos MySQL usando MySQLdb Lo primero que debe hacer es crear una conexión a la base de datos utilizando el método de conexión. Después de eso, necesitará un cursor que operará con esa conexión. Utilice el método de ejecución del cursor para interactuar con la base de datos y, de vez en cuando, confirme los cambios utilizando el método de confirmación del objeto de conexión. Una vez hecho todo, no olvides cerrar el cursor y la conexión. Aquí hay una clase Dbconnect con todo lo que necesitas. Interactuar con la base de datos es simple. Después de crear el objeto, simplemente use el método de ejecución. import MySQLdb class Dbconnect(object): def init (self): self.dbconection = MySQLdb.connect(host='host_example', port=int('port_example'), user='user_example', passwd='pass_example', db='schema_example') self.dbcursor = self.dbconection.cursor() def commit_db(self): self.dbconection.commit() def close_db(self): self.dbcursor.close() self.dbconection.close()
    • 110. 45 db = Dbconnect() db.callproc('stored_procedure_name', [parameters] ) results = db.dbcursor.fetchall() for individual_row in results: first_field = individual_row[0] for individual_row in db.dbcursor: first_field = individual_row[0] db.commit_db() db.close_db() import sqlite3 conn = sqlite3.connect("users.db") c = conn.cursor() c.execute("CREATE TABLE user (name text, age integer)") c.execute("INSERTINTOuser VALUES('UserA',42)") c.execute("INSERTINTOuser VALUES('UserB',43)") conn.commit() c.execute("SELECT* FROMuser") print(c.fetchall()) conn.close() Si desea llamar a un procedimiento almacenado, use la siguiente sintaxis. Tenga en cuenta que la lista de parámetros es opcional. Una vez que se realiza la consulta, puede acceder a los resultados de varias maneras. El objeto del cursor es un generador que puede obtener todos los resultados o ser enlazado. Si quieres un loop usando directamente el generador: Si desea confirmar los cambios en la base de datos: Si quieres cerrar el cursor y la conexión: SQLite SQLite es una base de datos ligera, basada en disco. Dado que no requiere un servidor de base de datos separado, a menudo se usa para hacer prototipos o para aplicaciones pequeñas que a menudo usan un solo usuario o un usuario en un momento dado. db = Dbconnect() db.dbcursor.execute('SELECT * FROM %s' % 'table_example')
    • 111. 46 [(u'User A', 42), (u'User B', 43)] >>> import sqlite3 >>> conn = sqlite3.connect('users.db') >>> conn = sqlite3.connect(':memory:') c = conn.cursor() # Create table c.execute('''CREATETABLE stocks (date text, trans text, symbol text, qty real, price real)''') # Insert a row of data c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") # Save (commit) the changes conn.commit() # We can also close the connection if we are done with it. # Just be sure any changes have been committed or they will be lost. conn.close() El código anterior se conecta a la base de datos almacenada en el archivo llamado users.db , creando primero el archivo si aún no existe. Puede interactuar con la base de datos a través de sentencias de SQL. El resultado de este ejemplo debe ser: La sintaxis de SQLite: un análisis en profundidad Empezando 1. Importar el módulo sqlite usando 2. Para usar el módulo, primero debe crear un objeto de conexión que represente la base de datos. Aquí los datos se almacenarán en el archivo example.db: Alternativamente, también puede proporcionar el nombre especial :memory: para crear una base de datos temporal en la RAM, de la siguiente manera: 3. Una vez que tenga una Connection , puede crear un objeto Cursor y llamar a su método execute() para ejecutar comandos SQL:
    • 112. 47 def dict_factory(cursor, row): d = {} fori,colinenumerate(cursor.description): d[col[0]] = row[i] return d conn = sqlite3.connect(":memory:") conn.row_factory = dict_factory Atributos importantes y funciones de Connection 1. isolation_level Es un atributo utilizado para obtener o establecer el nivel de aislamiento actual. Ninguno para el modo de confirmación automática o uno de DEFERRED , IMMEDIATE o EXCLUSIVE . 2. cursor El objeto del cursor se utiliza para ejecutar comandos y consultas SQL. 3. commit() Confirma la transacción actual. 4. rollback() Deshace los cambios realizados desde la llamada anterior a commit() 5. close() Cierra la conexión de la base de datos. No llama a commit() automáticamente. Si se llama a close() sin llamar primero a commit() (suponiendo que no esté en modo de commit() automática), se perderán todos los cambios realizados. 6. total_changes Un atributo que registra el número total de filas modificadas, eliminadas o insertadas desde que se abrió la base de datos. 7. execute , executemany y executescript Estas funciones se realizan de la misma manera que las del objeto cursor. Este es un atajo ya que llamar a estas funciones a través del objeto de conexión da como resultado la creación de un objeto de cursor intermedio y llama al método correspondiente del objeto de cursor 8. row_factory Puede cambiar este atributo a un llamable que acepte el cursor y la fila original como una tupla y devolverá la fila del resultado real. Funciones importantes del Cursor 1. execute(sql[, parameters])
    • 113. 48 import sqlite3 conn = sqlite3.connect(":memory:") cur = conn.cursor() cur.execute("create table people (name, age)") who = "Sophia" age = 37 # This is the qmark style: cur.execute("insert into people values (?, ?)", (who, age)) # And this is the named style: cur.execute("select * from people where name=:who and age=:age", {"who": who, "age": age}) # the keys correspond to the placeholdersin SQL print(cur.fetchone()) L = [(1, 'abcd', 'dfj', 300), #A list oftuplesto be inserted into the database (2, 'cfgd', 'dyfj', 400), (3, 'sdd', 'dfjh', 300.50)] conn = sqlite3.connect("test1.db") conn.execute("create table if not exists book (id int, name text, author text, price real)") conn.executemany("insert into book values (?, ?, ?, ?)", L) for row in conn.execute("select * from book"): print(row) import sqlite3 class IterChars: def init (self): self.count = ord('a') def iter (self): Ejecuta unasolasentenciaSQL.LadeclaraciónSQLpuede estarparametrizada (es decir, marcadores de posiciónenlugarde literales deSQL).El módulosqlite3 admite dos tipos de marcadores de posición:¿signos de interrogación ? ("Estilo de qmark") y marcadores de posición con :name ("estilo con nombre"). Cuidado: no utilice %s para insertar cadenas en los comandos SQL, ya que puede hacer que su programa sea vulnerable a un ataque de inyección de SQL (consulte Inyección de SQL ). 2. executemany(sql, seq_of_parameters) Ejecuta un comando SQL contra todas las secuencias de parámetros o asignaciones encontradas en la secuencia sql. El módulo sqlite3 también permite usar un iterador para producir parámetros en lugar de una secuencia. También puede pasar objetos de iterador como un parámetro a muchos, y la función se repetirá sobre cada tupla de valores que devuelve el iterador. El iterador debe devolver una tupla de valores.
    • 114. 49 import sqlite3 conn = sqlite3.connect(":memory:") cur = conn.cursor() cur.executescript(""" create table person( firstname, lastname, age ); create table book( title, author, published ); insert into book(title, author, published) values ( 'Dirk Gently''s Holistic Detective Agency', 'Douglas Adams', 1987 ); """) 3. executescript(sql_script) Este es un método de conveniencia no estándar para ejecutar varias declaraciones SQL a la vez. Primero emite una instrucción COMMIT , luego ejecuta el script SQL que obtiene como parámetro. sql_script puede ser una instancia de str o bytes . El siguiente conjunto de funciones se usa junto con las SELECT en SQL. Para recuperar datos después de ejecutar una instrucción SELECT , puede tratar el cursor como un iterador, llamar al método fetchone() del cursor para recuperar una sola fila coincidente, o llamar a fetchall() para obtener una lista de las filas correspondientes. Ejemplo de la forma iterador: return (chr(self.count - 1),) conn = sqlite3.connect("abc.db") cur = conn.cursor() cur.execute("create table characters(c)") theIter = IterChars() cur.executemany("insert into characters(c) values (?)", theIter) rows = cur.execute("select c from characters") for row in rows: print(row[0]), # (use next(self) for Python 2) return self def next (self): if self.count > ord('z'): raise StopIteration self.count += 1
    • 115. 50 cur.execute('SELECT * FROM stocks ORDER BY price') i = cur.fetchone() while(i): print(i) i = cur.fetchone() # Output: # ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) # ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) # ('2006-04-06', 'SELL', 'IBM', 500, 53.0) # ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) cur.execute('SELECT * FROM stocks ORDER BY price') print(cur.fetchmany(2)) # Output: # [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM', 1000, 45.0)] cur.execute('SELECT * FROM stocks ORDER BY price') print(cur.fetchall()) 4. fetchone() Obtiene la siguiente fila de un conjunto de resultados de consulta, devolviendo una secuencia única o Ninguno cuando no hay más datos disponibles. 5. fetchmany(size=cursor.arraysize) Obtiene el siguiente conjunto de filas de un resultado de consulta (especificado por tamaño), devolviendo una lista. Si se omite el tamaño, fetchmany devuelve una sola fila. Se devuelve una lista vacía cuando no hay más filas disponibles. 6. fetchall() Obtiene todas las filas (restantes) de un resultado de consulta, devolviendo una lista. import sqlite3 stocks = [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM', 1000, 45.0), ('2006-04-06', 'SELL', 'IBM', 500, 53.0), ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)] conn = sqlite3.connect(":memory:") conn.execute("create table stocks (date text, buysell text, symb text, amount int, price real)") conn.executemany("insert into stocks values (?, ?, ?, ?, ?)", stocks) cur = conn.cursor() for row in cur.execute('SELECT * FROM stocks ORDER BY price'): print(row) # Output: # ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) # ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) # ('2006-04-06', 'SELL', 'IBM', 500, 53.0) # ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)
    • 116. 51 import psycopg2 # Establish a connection to the database. # Replace parameter values with database credentials. conn = psycopg2.connect(database="testpython", user="postgres", host="localhost", password="abc123", port="5432") # Create a cursor. The cursor allows you to execute database queries. cur = conn.cursor() # Create a table. Initialise the table name, the column names and data type. cur.execute("""CREATE TABLE FRUITS ( id INT, fruit_name TEXT, color TEXT, price REAL )""") conn.commit() conn.close() Tipos de datos SQLite y Python SQLite admite de forma nativa los siguientes tipos: NULL, INTEGER, REAL, TEXT, BLOB. Así es como se convierten los tipos de datos al pasar de SQL a Python o viceversa. None <-> NULL int <-> INTEGER/INT float <-> REAL/FLOAT str <-> TEXT/VARCHAR(n) bytes <-> BLOB Acceso a la base de datos PostgreSQL usando psycopg2 psycopg2 es el adaptador de base de datos PostgreSQL más popular que es ligero y eficiente. Es la implementación actual del adaptador PostgreSQL. Sus características principales son la implementación completa de la especificación Python DB API 2.0 y la seguridad de subprocesos (varios subprocesos pueden compartir la misma conexión) Estableciendo una conexión a la base de datos y creando una tabla. # Output: # [('2006-01-05', 'BUY', 'RHAT', 100, 35.14), ('2006-03-28', 'BUY', 'IBM', 1000, 45.0), ('2006-04-06', 'SELL', 'IBM', 500, 53.0), ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0)]
    • 117. 52 # After creating the table as shown above, insert values into it. cur.execute("""INSERT INTO FRUITS (id, fruit_name, color, price) VALUES (1, 'Apples', 'green', 1.00)""") cur.execute("""INSERT INTO FRUITS (id, fruit_name, color, price) VALUES (1, 'Bananas', 'yellow', 0.80)""") # Set up a query and execute it cur.execute("""SELECT id, fruit_name, color, price FROM fruits""") # Fetch the data rows = cur.fetchall() # Do stuff with the data for row in rows: print "ID = {} ".format(row[0]) print"FRUITNAME={}".format(row[1]) print("COLOR = {}".format(row[2])) print("PRICE = {}".format(row[3])) ID = 1 NAME = Apples COLOR = green PRICE = 1.0 ID = 2 NAME = Bananas COLOR = yellow PRICE = 0.8 Insertando datos en la tabla: Recuperando datos de la tabla: La salida de lo anterior sería: Y así, ahí tienes, ¡ahora sabes la mitad de todo lo que necesitas saber sobre psycopg2 ! :) Base de datos Oracle Pre-requisitos: • Paquete cx_Oracle - Vea aquí para todas las versiones • Cliente instantáneo de Oracle - Para Windows x64 , Linux x64 Preparar: • Instala el paquete cx_Oracle como: sudo rpm -i <YOUR_PACKAGE_FILENAME>
    • 118. 53 ORACLE_HOME=<PATH_TO_INSTANTCLIENT> PATH=$ORACLE_HOME:$PATH LD_LIBRARY_PATH=<PATH_TO_INSTANTCLIENT>:$LD_LIBRARY_PATH import cx_Oracle class OraExec(object): _db_connection = None _db_cur = None def init (self): self._db_connection = cx_Oracle.connect('<USERNAME>/<PASSWORD>@<HOSTNAME>:<PORT>/<SERVICE_NAME>') self._db_cur = self._db_connection.cursor() ver = con.version.split(".") print ver _db_cur.execute("select * from employees order by emp_id") for result in _db_cur: print result _db_cur.execute("insert into employees(emp_id, title, dept, grade) values (31, 'MTS', 'ENGINEERING', 7) _db_connection.commit() • Extraiga el cliente instantáneo de Oracle y establezca las variables de entorno como: Creando una conexión: Obtener la versión de la base de datos: Salida de muestra: ['12', '1', '0', '2', '0'] Ejecutar consulta: SELECCIONAR La salida será en tuplas de Python: (10, 'SYSADMIN', 'IT-INFRA', 7) (23, 'HR ASSOCIATE', 'RECURSOS HUMANOS', 6) Ejecutar consulta: INSERTAR Cuando realiza operaciones de inserción / actualización / eliminación en una base de datos Oracle, los cambios solo están disponibles dentro de su sesión hasta commit se emita la commit . Cuando los datos actualizados se confirman en la base de datos, están disponibles para otros usuarios y sesiones. Ejecutar consulta: INSERTAR utilizando variables Bind Referencia
    • 119. 54 rows = [ (1, "First" ), (2,"Second"), (3, "Third" ) ] _db_cur.bindarraysize = 3 _db_cur.setinputsizes(int, 10) _db_cur.executemany("insert into mytab(id, data) values (:1, :2)", rows) _db_connection.commit() _db_connection.close() import MyDBAPI con = MyDBAPI.connect(*database_dependent_args) con.close() con.commit() Las variables de vinculación le permiten volver a ejecutar sentencias con nuevos valores, sin la sobrecarga de volver a analizar la sentencia. Las variables de enlace mejoran la reutilización del código y pueden reducir el riesgo de ataques de inyección de SQL. Conexión cercana: El método close () cierra la conexión. Cualquier conexión no cerrada explícitamente se liberará automáticamente cuando finalice el script. Conexión Creando una conexión Según PEP 249, la conexión a una base de datos debe establecerse mediante un constructor connect() , que devuelve un objeto Connection . Los argumentos para este constructor son dependientes de la base de datos. Consulte los temas específicos de la base de datos para los argumentos relevantes. Este objeto de conexión tiene cuatro métodos: 1: cerrar Cierralaconexión al instante.Tenga en cuentaquela conexiónse cierraautomáticamente sise llama al método Connection. del . Todas las transacciones pendientes se revertirán implícitamente. 2: cometer Se compromete cualquier transacción pendiente a la base de datos. 3: retroceso
    • 120. 55 cur = con.cursor() from sqlalchemy import create_engine from sqlalchemy.engine.url import URL url = URL(drivername='mysql', username='user', password='passwd', host='host', database='db') engine = create_engine(url) # sqlalchemy engine import pandas as pd con = engine.connect() dataframe = pd.read_sql(sql=query, con=con) Retrocede al inicio de cualquier transacción pendiente. En otras palabras: esto cancela cualquier transacción no confirmada a la base de datos. 4: cursor Devuelve un objeto Cursor . Esto se utiliza para hacer transacciones en la base de datos. Usando sqlalchemy Para usar sqlalchemy para la base de datos: Ahora se puede usar este motor: por ejemplo, con pandas para obtener marcos de datos directamente desde mysql con.rollback()
    • 121. 56 import dis def fib(n): if n <= 2: return 1 return fib(n-1) + fib(n-2) # Display the disassembled bytecode of the function. dis.dis(fib) def fib(n): if n <= 2: return 1 return fib(n-1) + fib(n-2) dir(fib. code ) def fib(n): if n <= 2: return 1 return fib(n-1) + fib(n-2) dir(fib. code ) Capítulo 4: Acceso al código fuente y código de bytes de Python Examples Mostrar el bytecode de una función El intérprete de Python compila el código a bytecode antes de ejecutarlo en la máquina virtual de Python (consulte también ¿Qué es el bytecode de python?) . Aquí es cómo ver el código de bytes de una función de Python La función dis.dis en el módulo dis devolverá un bytecode descompilado de la función que se le pasó. Explorando el código objeto de una función. CPython permite el acceso al objeto de código para un objeto de función. El objeto code contiene el bytecode en bruto ( co_code ) de la función, así como otra información como constantes y nombres de variables. Mostrar el código fuente de un objeto. Objetos que no están incorporados Para imprimir el código fuente de un objeto Python use inspect . Tenga en cuenta que esto no funcionará para los objetos incorporados ni para los objetos definidos de forma interactiva. Para estos necesitarás otros métodos explicados más adelante.
    • 122. 57 return self.randrange(a, b+1) def randint(self, a, b): """Return random integer in range [a, b], including both end points. """ # # # # # import random import inspect print(inspect.getsource(random.randint)) # Output: print(inspect.getdoc(random.randint)) # Output: # Return random integer in range [a, b], including both end points. print(inspect.getfile(random.randint)) # c:\Python35\lib\random.py print(random.randint. code .co_filename) # equivalent to the above # c:\Python35\lib\random.py # define a new function in the interactive shell def add(a, b): return a + b print(add. code .co_filename) # Output: <stdin> import dill print dill.source.getsource(add) # def add(a, b): return a + b print(inspect.getsource(sorted)) # raises a TypeError type(sorted) # <class 'builtin_function_or_method'> Aquí le mostramos cómo imprimir el código fuente del método randint desde el módulo random : Para simplemente imprimir la cadena de documentación Imprima la ruta completa del archivo donde se define el método random.randint : Objetos definidos interactivamente. Siunobjetoestádefinidodeformainteractiva,inspect nopuedeproporcionarelcódigofuente, pero puede usar dill.source.getsource en dill.source.getsource lugar Objetos incorporados El código fuente de las funciones incorporadas de Python está escrito en c y solo se puede acceder a él consultando el código fuente de Python (alojado en Mercurial o descargable desde https://www.python.org/downloads/source/) .
    • 123. 58
    • 124. 59 class Book: def init (self, title, author): self.title = title self.author = author book1 = Book(title="Right Ho, Jeeves", author="P.G. Wodehouse") >>> book1.title 'P.G. Wodehouse' >>> book1.series Traceback (most recent call last): File "<stdin>", line 1, in<module> AttributeError: 'Book' object has no attribute 'series' class Book: def init (self, title, author): self.title = title self.author = author Capítulo 5: Acceso de atributo Sintaxis • x.title # Accesses the title attribute using the dot notation • x.title = "Hello World" # Sets the property of the title attribute using the dot notation • @property # Used as a decorator before the getter method for properties • @title.setter # Used as a decorator before the setter method for properties Examples Acceso a atributos básicos utilizando la notación de puntos Tomemos una clase de muestra. En Python, puede acceder al título del atributo de la clase usando la notación de puntos. Si un atributo no existe, Python lanza un error: Setters, Getters & Properties Por el bien de la encapsulación de datos, a veces desea tener un atributo cuyo valor proviene de otros atributos o, en general, qué valor se computará en el momento. La forma estándar de lidiar con esta situación es crear un método, llamado getter o setter. En el ejemplo anterior, es fácil ver qué sucede si creamos un nuevo libro que contiene un título y un autor. Si todos los libros que vamos a agregar a nuestra biblioteca tienen autores y títulos, podemos omitir a los captadores y definidores y usar la notación de puntos. Sin embargo,
    • 125. 60 class P: def init (self,title,author): self.title = title self.setAuthor(author) def get_author(self): return self.author def set_author(self, author): if not author: self.author = "Unknown" else: self.author = author >>> book = Book(title="Ancient Manuscript", author="Some Guy") >>> book.author = "" #Cos Some Guy didn't write this one! class Book: def init (self, title, author): self.title = title self.author = author @property def author(self): return self. author @author.setter def author(self, author): if not author: self.author = "Unknown" else: self.author = author supongamos que tenemos algunos libros que no tienen un autor y queremos que el autor sea "Desconocido". O si tienen varios autores y planeamos devolver una lista de autores. En este caso, podemos crear un getter y un setter para el atributo de autor . Este esquema no es recomendable. Una razón es que hay un problema: supongamos que hemos diseñado nuestra clase con el atributo público y sin métodos. La gente ya lo ha usado mucho y ha escrito un código como este: Ahora tenemos un problema. ¡Porque el autor no es un atributo! Python ofrece una solución a este problema llamado propiedades. Un método para obtener propiedades está decorado con la propiedad @ antes de su encabezado. El método que queremos que funcione como configurador está decorado con @ attributeName.setter anterior. Teniendo esto en cuenta, ahora tenemos nuestra nueva clase actualizada. Tenga en cuenta que normalmente Python no le permite tener varios métodos con el mismo nombre y diferente número de parámetros. Sin embargo, en este caso Python lo permite debido a los decoradores utilizados.
    • 126. 61 >>> book = Book(title="Ancient Manuscript", author="Some Guy") >>> book.author = "" #Cos Some Guy didn't write this one! >>> book.author Unknown Si probamos el código:
    • 127. 62 s = 'AAAABBBCCDAABBB' s = 'AAAABBBCCDAABBB' s_dict = {} for i in s: if i not in s_dict.keys(): Capítulo 6: agrupar por() Introducción En Python, el método itertools.groupby() permite a los desarrolladores agrupar los valores de una clase iterable basándose en una propiedad específica en otro conjunto de valoresiterables. Sintaxis • itertools.groupby (iterable, key = None o alguna función) Parámetros Parámetro Detalles iterable Cualquier pitón iterable llave Función (criterios) sobre la cual agrupar lo iterable. Observaciones groupby () es complicado pero una regla general a tener en cuenta al usarlo es la siguiente: Ordene siempre los elementos que desea agrupar con la misma clave que desea utilizar para agrupar Se recomienda que el lector revise la documentación aquí y vea cómo se explica utilizando una definición de clase. Examples Ejemplo 1 Di que tienes la cuerda y te gustaría dividirlo para que todas las 'A' estén en una lista y así con todas las 'B' y 'C', etc. Podrías hacer algo como esto
    • 128. 63 {'A': ['A', 'A', 'A', 'A', 'A', 'A'], 'B': ['B', 'B', 'B', 'B', 'B', 'B'], 'C': ['C', 'C'], 'D': ['D']} # note that we get a {key : value} pair for iterating over the items just like in python dictionary from itertools import groupby s ='AAAABBBCCDAABBB' c = groupby(s) dic = {} for k, v in c: dic[k] = list(v) dic {'A': ['A', 'A'], 'B': ['B', 'B', 'B'], 'C': ['C', 'C'], 'D': ['D']} c = groupby(sorted(s)) dic = {} for k, v in c: dic[k] = list(v) dic {'A': ['A', 'A', 'A', 'A', 'A', 'A'], 'B': ['B', 'B', 'B', 'B', 'B', 'B'], 'C': ['C', 'C'], 'D': ['D']} Resultados en Pero para un conjunto de datos de gran tamaño, estaría acumulando estos elementos en la memoria. Aquí es donde entra groupby () Podríamos obtener el mismo resultado de una manera más eficiente haciendo lo siguiente Resultados en Observe que el número de 'A's en el resultado cuando usamos group by es menor que el número real de' A's en la cadena original. Podemos evitar esa pérdida de información ordenando los elementos en s antes de pasarlos a c como se muestra a continuación Resultados en Ahora tenemos todas nuestras 'A's. Ejemplo 2 s_dict[i] = [i] else: s_dict[i].append(i) s_dict
    • 129. 64 c = groupby(['goat', 'dog', 'cow', 1, 1, 2, 3, 11, 10, ('persons', 'man', 'woman')]) dic = {} for k, v in c: dic[k] = list(v) dic {1: [1, 1], 2: [2], 3: [3], ('persons', 'man', 'woman'): [('persons', 'man', 'woman')], 'cow': ['cow'], 'dog': ['dog'], 10: [10], 11: [11], 'goat': ['goat']} list_things = ['goat', 'dog', 'donkey', 'mulato', 'cow', 'cat', ('persons', 'man', 'woman'), \ 'wombat', 'mongoose', 'malloo', 'camel'] c = groupby(list_things, key=lambda x: x[0]) dic = {} for k, v in c: dic[k] = list(v) dic {'c': ['camel'], 'd': ['dog', 'donkey'], 'g': ['goat'], 'm': ['mongoose', 'malloo'], 'persons': [('persons', 'man', 'woman')], 'w': ['wombat']} list_things = ['goat', 'dog', 'donkey', 'mulato', 'cow', 'cat', ('persons', 'man', 'woman'), \ 'wombat', 'mongoose', 'malloo', 'camel'] sorted_list = sorted(list_things, key = lambda x: x[0]) print(sorted_list) print() Este ejemplo ilustra cómo se elige la clave predeterminada si no especificamos ninguna Resultados en Observe aquí que la tupla en su conjunto cuenta como una clave en esta lista Ejemplo 3 Note en este ejemplo que mulato y camello no aparecen en nuestro resultado. Sólo se muestra el último elemento con la clave especificada. El último resultado para c en realidad borra dos resultados anteriores. Pero mira la nueva versión donde tengo los datos ordenados primero en la misma clave. Resultados en Versión ordenada
    • 130. 65 ['cow', 'cat', 'camel', 'dog', 'donkey', 'goat', 'mulato', 'mongoose', 'malloo', ('persons', 'man', 'woman'), 'wombat'] {'c': ['cow', 'cat', 'camel'], 'd': ['dog', 'donkey'], 'g': ['goat'], 'm': ['mulato', 'mongoose', 'malloo'], 'persons': [('persons', 'man', 'woman')], 'w': ['wombat']} things = [("animal", "bear"), ("animal", "duck"), ("plant", "cactus"), ("vehicle", "harley"), \ ("vehicle", "speed boat"), ("vehicle", "school bus")] dic = {} f = lambda x: x[0] for key, group in groupby(sorted(things, key=f), f): dic[key] = list(group) dic {'animal': [('animal', 'bear'), ('animal', 'duck')], 'plant': [('plant', 'cactus')], 'vehicle': [('vehicle', 'harley'), ('vehicle', 'speed boat'), ('vehicle', 'school bus')]} things = [["animal", "bear"], ["animal", "duck"], ["vehicle", "harley"], ["plant", "cactus"], \ ["vehicle", "speed boat"], ["vehicle", "school bus"]] dic = {} f = lambda x: x[0] for key, group in groupby(sorted(things, key=f), f): dic[key] = list(group) dic Resultados en Ejemplo 4 En este ejemplo, vemos lo que sucede cuando usamos diferentes tipos de iterable. Resultados en Este ejemplo a continuación es esencialmente el mismo que el de arriba. La única diferencia es que he cambiado todas las tuplas a listas. Resultados c = groupby(sorted_list, key=lambda x: x[0]) dic = {} for k, v in c: dic[k] = list(v) dic
    • 131. 66 {'animal': [['animal', 'bear'], ['animal', 'duck']], 'plant': [['plant', 'cactus']], 'vehicle': [['vehicle', 'harley'], ['vehicle', 'speed boat'], ['vehicle', 'school bus']]}
    • 132. 67 read_x_local_fail() # UnboundLocalError: local variable 'x' referenced before assignment def read_x_local_fail(): if False: x = 'Hey' # x appears in an assignment, therefore it's local print(x) # will look for the _local_ z, which is not assigned, and will not be found read_y() # prints Hey def read_y(): y = 'Hey' # y appears in an assignment, therefore it's local print(y) # will find the local y read_y() #NameError: global name 'y' is not defined def read_y(): print(y) # here y is just referenced, therefore assumed global read_x() # prints Hi x = 'Hi' def read_x(): print(x) # x is just referenced, therefore assumed global Capítulo 7: Alcance variable y vinculante Sintaxis • global a, b, c • no local a, b • x = algo # se une a x • (x, y) = algo # une x y y • x + = algo # se une a x. Del mismo modo para todos los demás "op =" • del x # se une a x • para x en algo: # se une a x • con algo como x: # une x • excepto Excepción como ex: # binds ex inside block Examples Variables globales En Python, las variables dentro de las funciones se consideran locales si y solo si aparecen en el lado izquierdo de una instrucción de asignación, o alguna otra ocurrencia de enlace; de lo contrario, tal enlace se busca en las funciones adjuntas, hasta el alcance global. Esto es cierto incluso si la instrucción de asignación nunca se ejecuta. Normalmente, una asignación dentro de un ámbito sombreará las variables externas del mismo nombre:
    • 133. 68 x = 'Hi' def change_global_x(): global x x = 'Bye' print(x) change_global_x() # prints Bye print(x) # prints Bye def foo(): a = 5 print(a) # ok print(a) # NameError: name 'a' is not defined def foo(): if True: a = 5 Declarar un nombre global significa que, para el resto del alcance, cualquier asignación al nombre ocurrirá en el nivel superior del módulo: La palabra clave global significa que las asignaciones se realizarán en el nivel superior del módulo, no en el nivel superior del programa. Otros módulos seguirán necesitando el acceso puntual habitual a las variables dentro del módulo. Para resumir: para saber si una variable x es local a una función, debe leer la función completa : 1. Si has encontrado global x , entonces x es una variable global 2. Si ha encontrado nonlocal x , entonces x pertenece a una función que lo encierra, y no es local ni global 3. Si ha encontrado x = 5 o for x in range(3) o algún otro enlace, entonces x es una variable local 4. De lo contrario, x pertenece a algún ámbito adjunto (ámbito de función, ámbito global o elementos incorporados) Variables locales Si un nombre está enlazado dentro de una función, por defecto es accesible solo dentro de la función: Las construcciones de flujo de control no tienen impacto en el alcance (con la excepción de except ), pero el acceso a la variable que aún no se asignó es un error: x = 'Hi' def change_local_x(): x = 'Bye' print(x) change_local_x() # prints Bye print(x) # prints Hi
    • 134. 69 def counter(): num = 0 def incrementer(): num += 1 return num return incrementer def counter(): num = 0 def incrementer(): nonlocal num num += 1 return num return incrementer c = counter() c() # = 1 c() # = 2 c() # = 3 Lasoperacionesdeenlacecomunes sonasignaciones, for bucles yasignacionesaumentadas, como a += 5 Variables no locales Python 3.x 3.0 Python 3 agregó una nueva palabra clave llamada no local . La palabra clave no local agrega una anulación de ámbito al ámbito interno. Puedes leer todo sobre esto en PEP 3104 . Esto se ilustra mejor con un par de ejemplos de código. Uno de los ejemplos más comunes es crear una función que puede incrementar: Si intenta ejecutar este código, recibirá un UnboundLocalError porque se hace referencia a la variable num antes de que se asigne en la función más interna. Añadamos nonlocal a la mezcla: Básicamente, nonlocal le permitirá asignar variables en un ámbito externo, pero no global. Porlo tanto, no puede usar el modo no nonlocal en nuestra función de counter porque entonces intentaría asignarlo a un alcance global. SyntaxError y obtendrá rápidamente un SyntaxError . En su lugar, debe utilizar nonlocal en una función anidada. (Tenga en cuenta que la funcionalidad que se presenta aquí se implementa mejor utilizando generadores). Ocurrencia vinculante print(a) # ok b = 3 def bar(): ifFalse: b = 5 print(b) # UnboundLocalError: local variable 'b' referenced before assignment
    • 135. 70 a = 'global' class Fred: a = 'class' # class scope b = (a for i in range(10)) # function scope c = [a for i in range(10)] # function scope d = a # classscope e = lambda: a # function scope f = lambda a=a: a # default argument uses class scope @staticmethod # or @classmethod, or regular instance method def g(): # function scope return a print(Fred.a) # class print(next(Fred.b)) # global print(Fred.c[0]) # class in Python 2, global in Python 3 print(Fred.d) # class print(Fred.e()) # global print(Fred.f()) # class print(Fred.g()) # global Cada una de las afirmaciones anteriores es una ocurrencia de enlace : x se une al objeto denotado por 5 . Si esta declaración aparece dentro de una función, entonces x será función local de forma predeterminada. Consulte la sección "Sintaxis" para obtener una lista de declaraciones vinculantes. Las funciones omiten el alcance de la clase al buscar nombres Las clases tienen un alcance local durante la definición, pero las funciones dentro de la clase no usan ese alcance cuando buscan nombres. Debido a que las lambdas son funciones, y las comprensiones se implementan utilizando el alcance de la función, esto puede llevar a un comportamiento sorprendente. Losusuarios quenoesténfamiliarizadoscon elfuncionamientodeeste ámbitopueden esperar que b , c y e impriman la class . Desde PEP 227 : Los nombres en el alcance de la clase no son accesibles. Los nombres se resuelven en el ámbito de la función de cierre más interno. Si una definición de clase se produce en una cadena de ámbitos anidados, el proceso de resolución omite las definiciones de clase. De la documentación de Python sobre denominación y encuadernación : El alcance de los nombres definidos en un bloque de clase se limita al bloque de clase; no se extiende a los bloques de código de los métodos; esto incluye x = 5 x += 7 for x in iterable: pass
    • 136. 71 class A: a = 42 b = list(a + i for i in range(10)) x = 5 print(x) # out: 5 del x print(x) # NameError: name 'f' is not defined class A: pass a = A() a.x = 7 print(a.x) # out: 7 del a.x print(a.x) # error: AttributeError: 'A' object has no attribute 'x' comprensiones y expresiones generadoras, ya que se implementan utilizando un ámbito de función. Esto significa que lo siguiente fallará: Este ejemplo utiliza referencias de esta respuesta de Martijn Pieters, que contiene un análisis más profundo de este comportamiento. El comando del Este comando tiene varias formas relacionadas pero distintas. del v Si v es una variable, el comando del v elimina la variable de su alcance. Porejemplo: Tenga en cuenta que del es una ocurrencia de enlace , lo que significa que a menos que se establezca explícitamente lo contrario (utilizando nonlocal o global ), del v hará que v local al alcance actual. Si pretende eliminar v en un ámbito externo, use nonlocal v o global v en el mismo ámbito de la declaración del v . En todo lo siguiente, la intención de un comando es un comportamiento predeterminado, pero el idioma no lo impone. Una clase puede estar escrita de una manera que invalida esta intención. del v.name Este comando activa una llamada a v. delattr (name) . La intención es hacer que el name del atributo no esté disponible. Por ejemplo: del v[item] Este comando activa una llamada a v. delitem (item) .
    • 137. 72 x = {'a': 1, 'b': 2} del x['a'] print(x) # out: {'b': 2} print(x['a']) # error: KeyError: 'a' x = [0, 1, 2, 3, 4] del x[1:3] print(x) # out: [0, 3, 4] foo = 1 # global def func(): bar = 2 # local print(foo) # prints variable foo from global scope print(bar) # prints variable bar from local scope foo = 1 def func(): bar = 2 print(globals().keys()) # prints all variable names in global scope print(locals().keys()) # prints all variable names in local scope La intención es que el item no pertenezca a la asignación implementada por el objeto v .Por ejemplo: del v[a:b] Esto realmente llama v. delslice (a, b) . La intención es similar a la descrita anteriormente, pero con cortes: rangos de elementos en lugar de un solo elemento. Por ejemplo: Véase también Recolección de basura # El comando del . Ámbito local vs global ¿Cuáles son el alcance local y global? Todos los variabes de Python a los que se puede acceder en algún punto del código se encuentran en el ámbito local o global . La explicación es que el alcance local incluye todas las variables definidas en la función actual y el alcance global incluye variables definidas fuera de la función actual. Uno puede inspeccionar qué variables están en qué alcance. Las funciones integradas locals() y globals() devuelven todos los ámbitos como diccionarios.
    • 138. 73 foo = 1 def func(): foo = 2 # creates a new variable foo in local scope, global foo is not affected print(foo) # prints 2 # global variable foo still exists, unchanged: print(globals()['foo']) # prints 1 print(locals()['foo']) # prints 2 foo = 1 def func(): global foo foo = 2 # this modifies the global foo, rather than creating a local variable foo = 1 def func(): # This function has a local variable foo, because it is defined down below. # So, foo is local from this point. Global foo is hidden. print(foo) # raises UnboundLocalError, because local foo is not yet initialized foo = 7 print(foo) foo = 1 def func(): # In this function, foo is a global variable from the begining foo = 7 # global foo is modified print(foo) # 7 print(globals()['foo']) # 7 global foo # this could be anywhere within the function print(foo) # 7 ¿Qué pasa con los choques de nombre? Para modificar una variable global, use la palabra clave global : El alcance se define para todo el cuerpo de la función! Lo que significa es que una variable nunca será global para la mitad de la función y local después, o viceversa. Asimismo, el opuesto: Funciones dentro de funciones
    • 139. 74 foo = 1 def f1(): bar = 1 def f2(): baz = 2 # here, foo is a global variable, baz is a local variable # bar is not in either scope print(locals().keys()) # ['baz'] print('bar' in locals())# False print('bar' in globals()) # False def f3(): baz = 3 print(bar) # bar from f1 is referenced so it enters local scope of f3 (closure) print(locals().keys()) # ['bar', 'baz'] print('bar' in locals()) # True print('bar' in globals()) # False def f4(): bar = 4 # a new local bar which hides bar from local scope of f1 baz = 4 print(bar) print(locals().keys()) # ['bar', 'baz'] print('bar' in locals()) # True print('bar' in globals()) # False foo = 0 # global foo def f1(): foo = 1 # a new foo local in f1 def f2(): foo = 2 # a new foo local in f2 def f3(): foo = 3 # a new foo local in f3 print(foo) # 3 foo = 30 # modifies local foo in f3 only def f4(): global foo print(foo) # 0 foo = 100 # modifies global foo Puede haber muchos niveles de funciones anidadas dentro de las funciones, pero dentro de una función solo hay un ámbito local para esa función y el ámbito global. No hay ámbitos intermedios. global vs nonlocal (solo Python 3) Estas dos palabras clave se utilizan para obtener acceso de escritura a variables que no son locales a las funciones actuales. La palabra clave global declara que un nombre debe tratarse como una variable global.
    • 140. 75 def f1(): def f2(): foo = 2 # a new foo local in f2 def f3(): nonlocal foo # foo from f2, which is the nearest enclosing scope print(foo) # 2 foo = 20 # modifies foo from f2! Por otro lado, nonlocal (consulte Variables no locales ), disponible en Python 3, toma una variable local de un ámbito de inclusión en el ámbito local de la función actual. De la documentación de Python en nonlocal : La declaración no local hace que los identificadores enumerados se refieran a variables previamente vinculadas en el ámbito envolvente más cercano, excluyendo las globales. Python 3.x 3.0
    • 141. 76 from PIL import Image im = Image.open("Image.bmp") from future import print_function import os, sys from PIL import Image for infile in sys.argv[1:]: f, e = os.path.splitext(infile) outfile = f + ".jpg" if infile != outfile: try: Image.open(infile).save(outfile) except IOError: print("cannot convert", infile) Capítulo 8: Almohada Examples Leer archivo de imagen Convertir archivos a JPEG
    • 142. 77 def switch(value): if value == 1: return "one" if value == 2: return "two" if value == 42: return "the answer to the question about life, the universe and everything" raise Exception("No case found!") >>> switch(1) one >>> switch(2) two >>> switch(3) … Exception: No case found! >>> switch(42) the answer to the question about life the universe and everything Capítulo 9: Alternativas para cambiar la declaración de otros idiomas Observaciones No hay ninguna instrucción de cambio en python como opción de diseño de idioma. Ha habido un PEP ( PEP-3103 ) que cubre el tema que ha sido rechazado. Puede encontrar muchas listas de recetas sobre cómo hacer sus propias declaraciones de cambio en python, y aquí estoy tratando de sugerir las opciones más sensatas. Aquí hay algunos lugares para comprobar: • http://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python • http://code.activestate.com/recipes/269708-some-python-style-switches/ • http://code.activestate.com/recipes/410692-readable-switch-construction-without-lambdasor-di/ • ... Examples Usa lo que el lenguaje ofrece: la construcción if / else. Bueno,siquieresunconstructodeswitch /case,laformamásdirectadehacerloesusarelviejoy bueno if / else construye: Puede parecer redundante, y no siempre bonito, pero esa es, con diferencia, la forma más eficiente de hacerlo, y hace el trabajo:
    • 143. 78 switch = { 1: lambda: 'one', 2: lambda: 'two', 42: lambda: 'the answer of life the universe and everything', } def default_case(): raise Exception('No case found!') >>> switch.get(1, default_case)() one >>> switch.get(2, default_case)() two >>> switch.get(3, default_case)() … Exception: No case found! >>> switch.get(42, default_case)() the answer of life the universe and everything def run_switch(value): return switch.get(value, default_case)() >>> run_switch(1) one class SwitchBase: def switch(self, case): m = getattr(self, 'case_{}'.format(case), None) if not m: return self.default return m Usa un dictado de funciones. Otra forma directa de hacerlo es crear un diccionario de funciones: a continuación, agrega una función predeterminada: yutilizael método get del diccionario para obtenerla función dado el valor para verificarlo y ejecutarlo. Si el valor no existe en el diccionario, entonces se ejecuta default_case . También puedes hacer un poco de azúcar sintáctico para que el interruptor se vea mejor: Usa la introspección de clase. Puedes usar una clase para imitar la estructura del conmutador / caso. Lo siguiente es usar la introspección de una clase (usar la función getattr() que resuelve una cadena en un método enlazado en una instancia) para resolver la parte del "caso". Luego,esemétododeintrospecciónse call método call para sobrecargar al operador () .
    • 144. 79 class CustomSwitcher: def case_1(self): return 'one' def case_2(self): return 'two' def case_42(self): return 'the answer of life, the universe and everything!' def default(self): raise Exception('Not a case!') >>> switch = CustomSwitcher() >>>print(switch(1)) one >>> print(switch(2)) two >>> print(switch(3)) … Exception: Not a case! >>> print(switch(42)) the answer of life, the universe and everything! class Switch: def init (self, value): self._val = value def enter (self): return self def exit (self, type, value, traceback): return False # Allows traceback to occur def call (self, cond, *mconds): return self._val in (cond,)+mconds def run_switch(value): with Switch(value) as case: Luego, para que se vea mejor, subclasificamos la clase SwitchBase (pero podría hacerse en una clase), y ahí definimos todos los case como métodos: así que finalmente podemos usarlo: Usando un administrador de contexto Otra forma, que es muy legible y elegante, pero mucho menos eficiente que una estructura if / else, es construir una clase como la siguiente, que leerá y almacenará el valor para comparar, exponerse dentro del contexto como un reclamo que devolverá verdadero si coincide con el valor almacenado: luego, definir los casos es casi una coincidencia con el constructo de switch / case real (expuesto dentro de una función a continuación, para que sea más fácil presumir): call = switch
    • 145. 80 >>> run_switch(1) one >>> run_switch(2) two >>> run_switch(3) … Exception: Not a case! >>> run_switch(42) the answer to the question about life, the universe and everything Entonces la ejecución sería: Nota Bene : • Esta solución se ofrece como el módulo de conmutación disponible en pypi . if case(1): return 'one' if case(2): return 'two' if case(3): return 'the answer to the question about life, the universe and everything' # default raise Exception('Not a case!')
    • 146. 81 pip install virtualenv apt-get install python-virtualenv $ cd test_proj $ virtualenv test_proj $ source test_project/bin/activate $ deactivate Capítulo 10: Ambiente Virtual Python - virtualenv Introducción Un entorno virtual ("virtualenv") es una herramienta para crear entornos aislados de Python. Mantiene las dependencias requeridas por los diferentes proyectos en lugares separados, mediante la creación de env de Python virtual para ellos. Resuelve el "proyecto A depende de la versión 2.xxx pero, el proyecto B necesita 2.xxx" dilema, y mantiene el directorio de paquetes de sitio global limpio y manejable. "virtualenv" crea una carpeta que contiene todas las librerías y contenedores necesarios para usar los paquetes que un proyecto de Python necesitaría. Examples Instalación Instale virtualenv a través de pip / (apt-get): O Nota: En caso de que tengas problemas con los permisos, usa sudo. Uso Crear entorno virtual: Para comenzar a utilizar el entorno virtual, debe activarse: Para salir de su virtualenv simplemente escriba "desactivar":
    • 147. 82 $ source test_project/bin/activate $ pip install flask Instala un paquete en tu Virtualenv Si observa el directorio bin en su virtualenv, verá que easy_install se ha modificado para poner huevos y paquetes en el directorio depaquetes de sitio virtualenv. Para instalar una aplicación en su entorno virtual: En este momento, no tiene que usar sudo ya que todos los archivos se instalarán en el directorio local de virtualenv site-packages. Esto fue creado como su propia cuenta de usuario. Otros comandos virtuales útiles lsvirtualenv : Listar todos los entornos. cdvirtualenv : navegue en el directorio del entorno virtual actualmente activado, para que pueda navegar por sus paquetes de sitios, por ejemplo. cdsitepackages : como el anterior, pero directamente en el directorio de paquetes de sitio. lssitepackages : muestra los contenidos del directorio site-packages.
    • 148. 83 import argparse parser = argparse.ArgumentParser() parser.add_argument('name', help='name of user' ) parser.add_argument('-g', '--greeting', default='Hello', help='optional alternate greeting' ) args = parser.parse_args() print("{greeting}, {name}!".format( greeting=args.greeting, name=args.name) ) -g GREETING, --greeting GREETING optional alternate greeting show this help message and exit optional arguments: -h, --help $ python hello.py --help usage: hello.py [-h] [-g GREETING] name positional arguments: name name of user Capítulo 11: Análisis de argumentos de línea de comandos Introducción La mayoría de las herramientas de línea de comandos se basan en argumentos pasados al programa en su ejecución. En lugar de solicitar una entrada, estos programas esperan que se establezcan datos o indicadores específicos (que se convierten en valores booleanos). Esto permite que tanto el usuario como otros programas ejecuten el archivo Python pasándole los datos a medida que se inician. Esta sección explica y demuestra la implementación y el uso de los argumentos de la línea de comandos en Python. Examples Hola mundo en argparse El siguiente programa dice hola al usuario. Toma un argumento posicional, el nombre del usuario, y también se le puede decir el saludo.
    • 149. 84 if name == " main ": args= docopt( doc ) import pprint; pprint.pprint(args) from docopt import docopt Print all the things. Get more bees into the path. Options: -a -b """ """ Usage: script_name.py [-a][-b] <path> $ python script_name.py Usage: script_name.py [-a] [-b] <path> $ python script_name.py something {'-a': False, '-b': False, '<path>': 'something'} $ python script_name.py something -a {'-a': True, '-b': False, '<path>': 'something'} $ python script_name.py -b something -a {'-a': True, '-b':True, '<path>': 'something'} import argparse Para más detalles por favor lea la documentación argparse . Ejemplo básico con docopt. docopt convierte el argumento de la línea de comando analizando en su cabeza. En lugar de analizar los argumentos, simplemente escriba la cadena de uso para su programa, y docopt analiza la cadena de uso y la utiliza para extraer los argumentos de la línea de comandos. Ejecuciones de muestra: Estableciendo argumentos mutuamente excluyentes con argparse Siquieresquedoso másargumentos seanmutuamenteexcluyentes.Puedeutilizarlafunción argparse.ArgumentParser.add_mutually_exclusive_group() . En el siguiente ejemplo, pueden existir foo o bar, pero no ambos al mismotiempo. $ python hello.py world Hello, world! $ python hello.py John -g Howdy Howdy, John!
    • 150. 85 # cli.py import sys print(sys.argv) $ python cli.py => ['cli.py'] $ python cli.py fizz => ['cli.py', 'fizz'] $ python cli.py fizz buzz => ['cli.py', 'fizz', 'buzz'] import getpass import sys words = sys.argv[1:] sentence = " ".join(words) print("[%s] %s" % (getpass.getuser(), sentence)) Si intenta ejecutar el script especificando los argumentos --foo y --bar , el script se quejará con el mensaje a continuación. error: argument -b/--bar: not allowed with argument -f/--foo Usando argumentos de línea de comando con argv Cada vez que se invoca un script de Python desde la línea de comandos, el usuario puede proporcionar argumentos de línea de comandos adicionales que se pasarán al script. Estos argumentos estarán disponibles para el programador de la variable del sistema sys.argv ( "argv" es un nombre tradicional utilizado en la mayoría de los lenguajes de programación, y significa "arg ument v ector"). Por convención, el primer elemento de la lista sys.argv es el nombre de la secuencia de comandos de Python, mientras que el resto de los elementos son los tokens que el usuariopasa al invocar la secuencia de comandos. Aquí hay otro ejemplo de cómo usar argv . Primero eliminamos el elemento inicial de sys.argv porque contiene el nombre del script. Luego combinamos el resto de los argumentos en una sola oración,y finalmenteimprimimosesaoración antesdel nombredel usuarioquehainiciado sesión (para que emule un programa de chat). El algoritmo comúnmente utilizado cuando se analiza "manualmente" un número de argumentos no posicionales es iterar sobre la lista sys.argv . Una forma es repasar la lista y resaltar cada elemento de la misma: parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group() group.add_argument("-f", "--foo") group.add_argument("-b", "--bar") args = parser.parse_args() print "foo = ", args.foo print "bar = ", args.bar
    • 151. 86 import argparse parser = argparse.ArgumentParser() parser.add_argument("-f", "--foo") parser.add_argument("-b", "--bar") args = parser.parse_args() if args.foo and args.bar is None: parser.error("--foo requires --bar. You did not specify bar.") print "foo =", args.foo print "bar =", args.bar usage: sample.py [-h] [-f FOO] [-b BAR] sample.py: error: --foo requires --bar. You did not specify bar. import argparse Mensaje de error del analizador personalizado con argparse Puede crear mensajes deerror del analizadorde acuerdo con las necesidades de su script.Esto es a través de la función argparse.ArgumentParser.error . El siguiente ejemplo muestra la secuencia de comandosimprimiendo unusoyunmensaje de error astderr cuandose --foo pero no --bar . Asumiendoqueelnombredesuscriptessample.py,yejecutamos: python sample.py --foo ds_in_fridge El guión se quejará con lo siguiente: Agrupación conceptual de argumentos con argparse.add_argument_group () Cuandocrea un argparseArgumentParser() yejecuta su programa con'-h',recibe un mensajede uso automático que explica con qué argumentos puede ejecutar su software. De forma predeterminada, los argumentos posicionales y los argumentos condicionales están separados en doscategorías, porejemplo, aquíhay un pequeñoscript (example.py) y el resultado cuando ejecuta python example.py -h . # reverse and copy sys.argv argv = reversed(sys.argv) # extract the first element arg = argv.pop() # stop iterating when there's no more args to pop() while len(argv) > 0: if arg in ('-f', '--foo'): print('seen foo!') elif arg in ('-b', '--bar'): print('seen bar!') elif arg in ('-a', '--with-arg'): arg = arg.pop() print('seen value: {}'.format(arg)) # get the next value arg = argv.pop()
    • 152. 87 usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT] [--foo_this FOO_THIS] [--foo_that FOO_THAT] name Simple example positional arguments: name Who to greet optional arguments: -h, --help show this help message and exit --bar_this BAR_THIS --bar_that BAR_THAT --foo_this FOO_THIS --foo_that FOO_THAT import argparse parser = argparse.ArgumentParser(description='Simple example') parser.add_argument('name', help='Who to greet', default='World') # Create two argument groups foo_group = parser.add_argument_group(title='Foo options') bar_group = parser.add_argument_group(title='Bar options') # Add arguments to those groups foo_group.add_argument('--bar_this') foo_group.add_argument('--bar_that') bar_group.add_argument('--foo_this') bar_group.add_argument('--foo_that') args = parser.parse_args() show this help message and exit optional arguments: -h, --help usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT] [--foo_this FOO_THIS] [--foo_thatFOO_THAT] name Simple example positional arguments: name Who to greet Hay algunas situaciones en las que desea separar sus argumentos en secciones conceptuales adicionales para ayudar a su usuario. Por ejemplo, es posible que desee tener todas las opciones de entrada en un grupo y todas las opciones de formato de salida en otro. El ejemplo anterior se puede ajustar para separar los --foo_* de los --bar_* así. Que produce esta salida cuando se ejecuta python example.py -h : parser = argparse.ArgumentParser(description='Simple example') parser.add_argument('name', help='Who to greet', default='World') parser.add_argument('--bar_this') parser.add_argument('--bar_that') parser.add_argument('--foo_this') parser.add_argument('--foo_that') args = parser.parse_args()
    • 153. 88 """Run something in development or production mode. Usage: run.py --development <host> <port> run.py --production <host> <port> run.py items add <item> run.py items delete <item> """ from docopt_dispatch import dispatch @dispatch.on('--development') def development(host, port, **kwargs): print('in *development* mode') @dispatch.on('--production') def development(host, port, **kwargs): print('in *production* mode') @dispatch.on('items', 'add') def items_add(item, **kwargs): print('adding item...') @dispatch.on('items', 'delete') def items_delete(item, **kwargs): print('deleting item...') if name == ' main': dispatch( doc ) Ejemplo avanzado con docopt y docopt_dispatch Al igual que con docopt, con [docopt_dispatch] creas tu --help en la variable doc de tu módulo de punto de entrada. Allí, se llama dispatch con la cadena doc como argumento, para que pueda ejecutar el analizador sobre él. Una vez hecho esto, en lugar de manejar manualmente los argumentos (que por lo general terminan en una estructura ciclomática alta de / else), lo dejas para enviar, dando solo la forma en que quieres manejar el conjunto de argumentos. Esto es para lo que es el decorador dispatch.on : le da el argumento o la secuencia de argumentos que deberían desencadenar la función, y esa función se ejecutará con los valores coincidentes como parámetros. Foo options: --bar_this BAR_THIS --bar_that BAR_THAT Bar options: --foo_this FOO_THIS --foo_that FOO_THAT
    • 154. 89 <div> <label>Name:</label> John Smith </div> from bs4 import BeautifulSoup data = """ <div> <label>Name:</label> John Smith </div> """ soup = BeautifulSoup(data, "html.parser") label = soup.find("label", text="Name:") print(label.next_sibling.strip()) from bs4 import BeautifulSoup data = """ <ul> <li class="item">item1</li> <li class="item">item2</li> <li class="item">item3</li> </ul> """ Capítulo 12: Análisis de HTML Examples Localiza un texto después de un elemento en BeautifulSoup. Imagina que tienes el siguiente HTML: Y necesitas ubicar el texto "John Smith" después del elemento de label . En este caso, puede ubicar el elemento de label por texto y luego usar la propiedad .next_sibling : Imprime John Smith . Usando selectores de CSS en BeautifulSoup BeautifulSoup tiene un soporte limitado para los selectores de CSS , pero cubre los más utilizados. Use el método select() para encontrar múltiples elementos y select_one() para encontrar un solo elemento. Ejemplo básico:
    • 155. 90 item1 item2 item3 from pyquery import PyQuery html = """ <h1>Sales</h1> <table id="table"> <tr> <td>Lorem</td> <td>46</td> </tr> <tr> <td>Ipsum</td> <td>12</td> </tr> <tr> <td>Dolor</td> <td>27</td> </tr> <tr> <td>Sit</td> <td>90</td> </tr> </table> """ doc = PyQuery(html) title = doc('h1').text() print title table_data = [] rows = doc('#table > tr') for row in rows: name = PyQuery(row).find('td').eq(0).text() value = PyQuery(row).find('td').eq(1).text() print "%s\t %s" % (name, value) Huellas dactilares: PyQuery pyquery es una biblioteca tipo jquery para python. Tiene muy buen soporte para selectores css. soup = BeautifulSoup(data, "html.parser") for item in soup.select("li.item"): print(item.get_text())
    • 156. 91 try: res = get_result() res = res[0] log('got result: %r' % res) except: if not res: res = '' print('got exception') import traceback try: res = get_result() except Exception: log_exception(traceback.format_exc()) raise try: res = res[0] except IndexError: res = '' log('got result: %r' % res) Capítulo 13: Anti-patrones de Python Examples Con exceso de celo excepto la cláusula Las excepciones son poderosas, pero una sola cláusula exagerada puede quitarlo todo en una sola línea. Este ejemplo demuestra 3 síntomas del antipattern: 1. El tipo de excepción except sin excepción (línea 5) detectará incluso las excepciones correctas, incluido KeyboardInterrupt . Eso evitará que el programa salga en algunos casos. 2. El bloque de excepción novuelve a generar el error, lo que significa que no podremos saber si la excepción provino de get_result o porque res era una listavacía. 3. Lopeordetodo,sinospreocupabaqueelresultadoestuvieravacío,hemoscausadoalgo mucho peor. Si get_result falla, la res permanecerá completamente sin configurar, y la referencia a la resen el bloque de excepción, generará NameError, NameErrorcompletamente el error original. Siempre piensa en el tipo de excepción que estás tratando de manejar. Dale una lectura a la página de excepciones y comprueba qué excepciones básicas existen. Aquí hay una versión fija del ejemplo anterior: Capturamos excepciones más específicas, volviendo a subir cuando sea necesario. Unas líneas más, pero infinitamente más correctas.
    • 157. 92 def intensive_f(value): # int -> Optional[int] # complex, and time-consuming code if process_has_failed: return None return integer_output x = 5 ifintensive_f(x)isnot None: print(intensive_f(x) /2) else: print(x, "could not be processed") print(x) x = 5 result = intensive_f(x) if result is not None: print(result / 2) else: print(x, "could not be processed") x = 5 try: print(intensive_f(x) / 2) except TypeError: # The exception raised if None + 1 is attempted print(x, "could not be processed") Mirando antes de saltar con la función de procesador intensivo Un programa puede fácilmente perder tiempo llamando a una función intensiva en el procesador varias veces. Por ejemplo, tome una función que se parece a esto: devuelve un entero si el value entrada puede producir uno, de lo contrario, None : Y podría ser utilizado de la siguiente manera: Si bien esto funcionará, tiene el problema de llamar intensive_f , que duplica el tiempo de ejecución del código. Una mejor solución sería obtener el valor de retorno de la función de antemano. Sin embargo, una forma más clara y posiblemente más pirónica es usar excepciones, por ejemplo: Aquí no se necesita una variable temporal. Puede ser a menudo preferible utilizar una assert declaración, y para coger el AssertionError lugar. Claves del diccionario Un ejemplo común de dónde se puede encontrar esto es acceder a las claves del diccionario. Por ejemplo comparar:
    • 158. 93 bird_speeds = get_very_long_dictionary() try: speed = bird_speeds["european swallow"] except KeyError: speed = input("What is the air-speed velocity of an unladen swallow?") print(speed) con: El primer ejemplo tiene que mirar el diccionario dos veces, y como este es un diccionario largo, puede llevar mucho tiempo hacerlo cada vez. El segundo solo requiere una búsqueda en el diccionario y, por lo tanto, ahorra mucho tiempo de procesador. Una alternativa a esto es usar dict.get(key, default), sin embargo, muchas circunstancias pueden requerir operaciones más complejas en el caso de que la clave no esté presente bird_speeds = get_very_long_dictionary() if "european swallow" in bird_speeds: speed = bird_speeds["european swallow"] else: speed = input("What is the air-speed velocity of an unladen swallow?") print(speed)
    • 159. 94 Capítulo 14: Apilar Introducción Una pila es un contenedor de objetos que se insertan y eliminan de acuerdo con el principio de último en entrar, primero en salir (LIFO). En las pilas de pushdown solo se permiten dos operaciones: empujar el elemento en la pila y sacar el elemento de la pila . Una pila es una estructura de datos de acceso limitado: los elementos se pueden agregar y eliminar de la pila solo en la parte superior . Aquí hay una definición estructural de una pila: una pila está vacía o consiste en una parte superior y el resto que es una pila. Sintaxis • stack = [] # Crea la pila • stack.append (objeto) # Agregar objeto a la parte superior de la pila • stack.pop () -> object # Devuelve el objeto más superior de la pila y también lo elimina • list [-1] -> object # Mira el objeto más superior sin quitarlo Observaciones De Wikipedia : En informática, una pila es un tipo de datos abstracto que sirve como una colección de elementos, con dos operaciones principales: push , que agrega un elemento a la colección, y pop , que elimina el elemento agregado más reciente que aún no se eliminó. Debido a la forma en que se accede a sus elementos, las pilas son también conocidos como último en entrar, primero en salir (LIFO) apila. En Python se pueden usar listas como pilas con append() como push y pop() como operaciones emergentes. Ambas operaciones se ejecutan en tiempo constante O (1). La estructura de datos deque de Python también se puede utilizar como una pila.En comparación con las listas, los deque permiten operaciones de inserción y pop con una complejidad de tiempo constante desde ambos extremos. Examples Creación de una clase de pila con un objeto de lista Usandounobjetodelist,puedecrearunapilagenéricacompletamentefuncionalconmétodos auxiliares, como mirar y comprobar si la pila está vacía.Echa un vistazo a los documentos oficiales de Python para utilizar la list como Stack aquí.
    • 160. 95 stack = Stack() print('Current stack:', stack.fullStack()) print('Stack empty?:', stack.isEmpty()) print('Pushing integer 1') stack.push(1) print('Pushing string "Told you, I am generic stack!"') stack.push('Told you, I am generic stack!') print('Pushing integer 3') stack.push(3) print('Current stack:', stack.fullStack()) print('Popped item:', stack.pop()) print('Current stack:', stack.fullStack()) print('Stack empty?:', stack.isEmpty()) Current stack: [] Stack empty?: True Pushing integer 1 Pushing string "Told you, I am generic stack!" Pushing integer 3 Currentstack: [1, 'Told you,I am generic stack!', 3] Popped item: 3 Current stack: [1, 'Told you, I am generic stack!'] Stack empty?: False Un ejemplo de ejecución: Salida: #define a stack class class Stack: def init (self): self.items = [] #method to check the stack is empty or not def isEmpty(self): return self.items == [] #method for pushing an item def push(self, item): self.items.append(item) #method for popping an item def pop(self): return self.items.pop() #check what item is on top of the stack without removing it def peek(self): return self.items[-1] #method to get the size def size(self): return len(self.items) #to view the entire stack def fullStack(self): return self.items
    • 161. 96 def checkParenth(str): stack = Stack() pushChars, popChars = "<({[", ">)}]" for c in str: if c in pushChars: stack.push(c) elif c in popChars: if stack.isEmpty(): return False else: stackTop = stack.pop() # Checks to see whether the opening bracket matches the closing one balancingBracket = pushChars[popChars.index(c)] if stackTop != balancingBracket: return False else: return False return not stack.isEmpty() Paréntesis de paréntesis Las pilas se utilizan a menudo para el análisis. Una tarea de análisis simple es verificar si una cadena de paréntesis coincide. Porejemplo,lacadena([])coincide,porqueloscorchetesexterioreinteriorformanpares.()<>) nocoincide,porqueelúltimo)notienepareja.([)]tampococoincide,porquelosparesdeben estar completamente dentro o fuera deotrospares.
    • 162. 97 Capítulo 15: Árbol de sintaxis abstracta Examples Analizar funciones en un script de python Esto analiza un script de Python y, para cada función definida, informa el número de línea donde comenzó la función, donde termina la firma, donde termina la cadena de documentos y donde termina la definición de la función. #!/usr/local/bin/python3 import ast import sys """ The datawe collect. Each key is a function name; each value is a dict with keys: firstline, sigend, docend, and lastline and values of line numbers where that happens. """ functions = {} def process(functions): """ Handle the function data stored in functions. """ for funcname,data in functions.items(): print("function:",funcname) print("\tstarts at line:",data['firstline']) print("\tsignature ends at line:",data['sigend']) if ( data['sigend'] < data['docend'] ): print("\tdocstring ends at line:",data['docend']) else: print("\tno docstring") print("\tfunction ends at line:",data['lastline']) print() class FuncLister(ast.NodeVisitor): def visit_FunctionDef(self, node): """ Recursively visit all functions, determining where each function starts, where its signature ends, where the docstring ends, and where the function ends. """ functions[node.name] = {'firstline':node.lineno} sigend = max(node.lineno,lastline(node.args)) functions[node.name]['sigend'] = sigend docstring = ast.get_docstring(node) docstringlength = len(docstring.split('\n')) if docstring else -1 functions[node.name]['docend'] = sigend+docstringlength functions[node.name]['lastline'] = lastline(node) self.generic_visit(node) def lastline(node): """ Recursively find the last line of a node """ return max( [ node.lineno if hasattr(node,'lineno') else -1 , ] +[lastline(child) for child in ast.iter_child_nodes(node)] ) def readin(pythonfilename): """ Read the file name and store the function data into functions. """ with open(pythonfilename) as f: code = f.read()
    • 163. 98 FuncLister().visit(ast.parse(code)) def analyze(file,process): """ Read the file and process the function data. """ readin(file) process(functions) if name == ' main ': if len(sys.argv)>1: for file in sys.argv[1:]: analyze(file,process) else: analyze(sys.argv[0],process)
    • 164. 99 import sys sys.getdefaultencoding() Capítulo 16: Archivos y carpetas I / O Introducción Cuando se trata de almacenar, leer o comunicar datos, trabajar con los archivos de un sistema operativo es tanto necesario como fácil con Python. A diferencia de otros idiomas en los que la entrada y salida de archivos requiere objetos complejos de lectura y escritura, Python simplifica el proceso, ya que solo necesita comandos para abrir, leer / escribir y cerrar el archivo. Este tema explica cómo Python puede interactuar con archivos en el sistema operativo. Sintaxis • file_object = open (filename [, access_mode] [, buffering]) Parámetros Parámetro Detalles nombre del archivo la ruta a su archivo o, si el archivo está en el directorio de trabajo, el nombre de archivo de su archivo modo de acceso un valor de cadena que determina cómo se abre el archivo amortiguación un valor entero utilizado para el búfer de línea opcional Observaciones Evitar el infierno de codificación multiplataforma Cuando se utiliza el open() incorporado de Python, es una buena práctica pasar siempre el argumento de encoding , si pretende que su código se ejecute en varias plataformas. El motivo de esto es que la codificación predeterminada de un sistema difiere de una plataforma a otra. Si bien los sistemas linux sí usan utf-8 como predeterminado, esto no es necesariamente cierto para MAC y Windows. Para verificar la codificación predeterminada de un sistema, intente esto:
    • 165. 100 withopen('somefile.txt', 'r', encoding='UTF-8') asf: for line in f: print(line) de cualquier intérprete de python. Por lo tanto, es aconsejable siempre sepcificar una codificación, para asegurarse de que las cadenas con las que está trabajando estén codificadas como lo que cree que son, lo que garantiza la compatibilidad entre plataformas. Examples Modos de archivo Hay diferentes modos con los que puede abrir un archivo, especificados por el parámetro de mode . Éstos incluyen: • 'r'-mododelectura.Elvalorpordefecto.Lepermitesololeerelarchivo,nomodificarlo.Al usar este modo el archivo debe existir. • 'w' - modo de escritura. Creará un nuevo archivo si no existe, de lo contrario borrará el archivo y le permitirá escribir en él. • 'a'-mododeañadir.Escribirálosdatosalfinaldelarchivo.Noborraelarchivo,yelarchivo debe existir para este modo. • 'rb'-mododelectura enbinario.Estoessimilararexceptoquelalecturasefuerzaen modo binario. Esta es también una opción por defecto. • 'r+'-mododelecturamásmododeescrituraalmismotiempo.Estolepermiteleery escribir en archivos al mismo tiempo sin tener que usar r y w . • 'rb+'-mododelecturayescritura enbinario. Lomismo quer+ exceptoquelosdatosestán en binario • 'wb' - modo de escritura en binario. Lo mismo que w excepto que los datos están en binario. • 'w+' - modo de escritura y lectura. Exactamente igual que r+ pero si el archivo no existe, se crea uno nuevo. De lo contrario, el archivo se sobrescribe. • 'wb+' - modo de escritura y lectura en modo binario. Lo mismo que w+ pero los datos están en binario. • 'ab'- añadiendo en modo binario. Similar a a excepto que los datos están en binario. • 'a+' - modo de añadir y leer. Similar a w+ ya que creará un nuevo archivo si el archivo no existe. De lo contrario, el puntero del archivo se encuentra al final del archivo, si existe. • 'ab+' - modo de añadir y leer en binario. Lo mismo que a+ excepto que los datos están en
    • 166. 101 with open(filename, 'r') asf: f.read() with open(filename, 'w') as f: f.write(filedata) with open(filename, 'a') as f: f.write('\n' + newdata) binario. r r + w w + una a + Leer ✔ ✔ ✘ ✔ ✘ ✔ Escribir ✘ ✔ ✔ ✔ ✔ ✔ Crea archivo ✘ ✘ ✔ ✔ ✔ ✔ Borrar archivo ✘ ✘ ✔ ✔ ✘ ✘ Posición inicial comienzo comienzo comienzo comienzo Fin Fin Python 3 agregó un nuevo modo para la exclusive creation para que no truncas o sobrescribas accidentalmente un archivo existente. • 'x'-abiertoparacreaciónexclusiva,generaráFileExistsError sielarchivoyaexiste • 'xb'- abierto para el modo de escritura de creación exclusiva en binario. Lo mismo que x excepto que los datos están en binario. • 'x+'-mododelecturayescritura.Similara w+ yaquecrearáunnuevo archivosielarchivo no existe. De lo contrario, se levantará FileExistsError. • 'xb+'-mododeescrituraylectura.Exactamentelomismoquex+ perolosdatos son binarios. X x + Leer ✘ ✔ Escribir ✔ ✔ Crea archivo ✔ ✔ Borrar archivo ✘ ✘ Posición inicial comienzo comienzo Permita que uno escriba su código de archivo abierto de una manera más pitónica: Python 3.x 3.3
    • 167. 102 import os.path if os.path.isfile(fname): with open("fname", "w") as fout: # Work with your open file else: # Your error handling goes here with open('myfile.txt', 'r') as fp: for line in fp: print(line) with open('myfile.txt', 'r') as fp: while True: cur_line = fp.readline() # If the result is an empty string if cur_line == '': # We have reached the end of the file break print(cur_line) with open("myfile.txt", "r") as fp: lines = fp.readlines() for i in range(len(lines)): print("Line " + str(i) + ": " + line) En Python 2 habrías hecho algo como Python 2.x 2.0 Leyendo un archivo línea por línea La forma más sencilla de iterar sobre un archivo línea por línea: readline() permite un control más granular sobre la iteración línea por línea. El siguiente ejemplo es equivalente al de arriba: Usar el iterador de bucle for y readline () juntos se considera una mala práctica. Más comúnmente, el método readlines() se usa para almacenar una colección iterable de las líneas del archivo: Esto imprimiría lo siguiente: Línea 0: hola Línea 1: mundo try: with open("fname", "r") as fout: # Work with your open file except FileExistsError: # Your error handling goes here
    • 168. 103 with open('myfile.txt') as in_file: content = in_file.read() print(content) in_file = open('myfile.txt', 'r') content = in_file.read() print(content) in_file.close() in_file = open('myfile.txt', 'r') raise Exception("oops") in_file.close() # This will never be called with open('myfile.txt', 'w') as f: f.write("Line 1") f.write("Line 2") f.write("Line 3") f.write("Line 4") with open('myfile.txt', 'w') as f: f.write("Line 1\n") f.write("Line 2\n") f.write("Line 3\n") f.write("Line 4\n") Obtener el contenido completo de un archivo El método preferido para el archivo i / o es usarla palabra clave with . Esto asegurará que el identificador de archivo se cierre una vez que se haya completado la lectura o escritura. o,para manejar el cierre del archivo de forma manual, se puede renunciar with y simplemente llamar a close a sí mismo: Tenga en cuenta que sin utilizar una instrucción with , puede mantener el archivo abierto por accidente en caso de que surja una excepción inesperada: Escribiendo en un archivo Si abres myfile.txt , verás que su contenido es: Línea 1Línea 2Línea 3Línea 4 Python no agrega automáticamente saltos de línea, debe hacerlo manualmente: Línea 1 Línea 2 Línea 3 Linea 4
    • 169. 104 outfile = open('fred.txt', 'w') s = "I'm Not Dead Yet!" print s # writes to stdout print >> outfile, s # writes to outfile with open('my_file.txt', 'w', encoding='utf-8') as f: f.write('utf-8 text') with open('fred.txt', 'w') as outfile: s = "I'm Not Dead Yet!" print(s) # writes to stdout print(s, file = outfile) # writes to outfile #Note: it is possible to specify the file parameter AND write to the screen #by making sure file ends up with a None value either directly or via a variable myfile = None print(s, file = myfile) # writes to stdout print(s, file = None) # writes to stdout with open(input_file, 'r') asin_file, open(output_file, 'w') as out_file: for line in in_file: out_file.write(line) import shutil shutil.copyfile(src, dst) No use os.linesep como terminador de línea al escribir archivos abiertos en modo de texto (el valor predeterminado); use \n lugar. Si desea especificar una codificación, simplemente agregue el parámetro de encoding a la función de open : También es posible utilizar la declaración de impresión para escribir en un archivo. La mecánica es diferente en Python 2 vs Python 3, pero el concepto es el mismo en que puedes tomar la salida que habría ido a la pantalla y enviarla a un archivo. Python 3.x 3.0 En Python 2 habrías hecho algo como Python 2.x 2.0 A diferencia de usar la función de escritura, la función de impresión agrega automáticamente saltos de línea. Copiando los contenidos de un archivo a un archivo diferente • Usando el módulo de shutil: Compruebe si existe un archivo o ruta
    • 170. 105 import errno try: with open(path) as f: # File exists except IOError as e: # Raise the exception if it is not ENOENT (No such file or directory) if e.errno != errno.ENOENT: raise # No such file or directory import os os.path.isfile('/path/to/some/file.txt') import pathlib path = pathlib.Path('/path/to/some/file.txt') if path.is_file(): ... import os path = "/home/myFiles/directory1" if os.path.exists(path): ## Do stuff import shutil source='//192.168.1.2/Daily Reports' destination='D:\\Reports\\Today' shutil.copytree(source, destination) Emplea el estilo de codificación EAFP e try abrirlo. Esto también evitará condiciones de carrera si otro proceso eliminó el archivo entre la verificación y cuando se utiliza. Esta condición de carrera podría ocurrir en los siguientes casos: • Usando el módulo os : Python 3.x 3.4 • Utilizando pathlib : Para verificar si existe una ruta determinada o no, puede seguir el procedimiento anterior de EAFP o verificar explícitamente la ruta: Copiar un árbol de directorios El directorio de destino no debe existir ya. Iterar archivos (recursivamente) Para iterar todos los archivos, incluidos los subdirectorios, use os.walk:
    • 171. 106 for entry in os.scandir(path): if not entry.name.startswith('.') and entry.is_file(): print(entry.name) import mmap with open('filename.ext', 'r') as fd: # 0: map the whole file mm = mmap.mmap(fd.fileno(), 0) # print characters at indices 5 through 10 root_dir puede ser "." para comenzar desde el directorio actual, o cualquier otra ruta desde la que comenzar. Python 3.x 3.5 Si también desea obtener información sobre el archivo, puede usar el método más eficiente os.scandir así: Leer un archivo entre un rango de líneas. Supongamosquedeseaiterarsoloentrealgunaslíneasespecíficasdeunarchivo Puedes hacer uso de itertools para eso. Esto leerá las líneas 13 a 20, ya que la indexación de Python comienza desde 0. Por lo tanto, la línea número 1 se indexa como 0 Como también puede leer algunas líneas adicionales haciendo uso de la next() palabra clave next() aquí. Y cuando esté utilizando el objeto de archivo como un iterable, no use la instrucción readline() aquí ya que las dos técnicas para atravesar un archivo no deben mezclarse Acceso aleatorio a archivos usando mmap El uso del módulo mmap permite al usuario acceder aleatoriamente a las ubicaciones de un archivo asignando el archivo a la memoria. Esta es una alternativa al uso de operaciones de archivos normales. import itertools with open('myfile.txt', 'r') as f: for line in itertools.islice(f, 12, 30): # do something here import os for root, folders, files in os.walk(root_dir): for filename in files: print root, filename
    • 172. 107 import fileinput replacements = {'Search1': 'Replace1', 'Search2': 'Replace2'} for line in fileinput.input('filename.txt', inplace=True): for search_for in replacements: replace_with = replacements[search_for] line = line.replace(search_for, replace_with) print(line, end='') >>> import os >>> os.stat(path_to_file).st_size == 0 >>> import os >>> os.path.getsize(path_to_file) > 0 import os def is_empty_file(fpath): return os.path.isfile(fpath) and os.path.getsize(fpath) > 0 Reemplazo de texto en un archivo Comprobando si un archivo está vacío o Sin embargo, ambos lanzarán una excepción si el archivo no existe. Para evitar tener que atrapar tal error, haga esto: que devolverá un valor bool . print mm[5:10] # print the line starting from mm's current position print mm.readline() # write a character to the 5th index mm[5] = 'a' # return mm's position to the beginning of the file mm.seek(0) # close the mmap object mm.close()
    • 173. 108 with arcpy.da.SearchCursor(r"C:\Temp\Test.gdb\TestFC",["TestField"]) as cursor: for row in cursor: print row[0] def createDissolvedGDB(workspace, gdbName): gdb_name = workspace + "/" + gdbName + ".gdb" if(arcpy.Exists(gdb_name): arcpy.Delete_management(gdb_name) arcpy.CreateFileGDB_management(workspace, gdbName, "") else: arcpy.CreateFileGDB_management(workspace, gdbName, "") return gdb_name Capítulo 17: ArcPy Observaciones Este ejemplo utiliza un cursor de búsqueda del módulo de acceso a datos (da) de ArcPy. No confunda la sintaxis de arcpy.da.SearchCursor con la arcpy.SearchCursor () anterior y más lenta. El módulo de acceso a datos (arcpy.da) solo ha estado disponible desde ArcGIS 10.1 para escritorio. Examples Impresión del valor de un campo para todas las filas de la clase de entidad en la geodatabase de archivos usando el cursor de búsqueda Para imprimir un campo de prueba (TestField) desde una clase de entidad de prueba (TestFC) en una geodatabase de archivos de prueba (Test.gdb) ubicada en una carpeta temporal (C: \ Temp): createDissolvedGDB para crear un archivo gdb en el área de trabajo
    • 174. 109 Capítulo 18: Arrays Introducción Las "matrices" en Python no son las matrices en lenguajes de programación convencionales como C y Java, sino que están más cerca de las listas. Una lista puede ser una colección de elementos homogéneos o heterogéneos, y puede contener ints, cadenas u otras listas. Parámetros Parámetro Detalles b Representa un entero con signo de tamaño 1 byte B Representa un entero sin signo de tamaño 1 byte c Representa el carácter de 1 byte de tamaño. u Representa caracteres unicode de tamaño 2 bytes. h Representa un entero con signo de tamaño 2 bytes H Representa un entero sin signo de tamaño 2 bytes i Representa un entero con signo de tamaño 2 bytes I Representa un entero sin signo de tamaño 2 bytes w Representa caracteres unicode de tamaño 4 bytes. l Representa un entero con signo de tamaño 4 bytes L Representa un entero sin signo de tamaño 4 bytes f Representa punto flotante de tamaño 4 bytes. d Representa punto flotante de tamaño 8 bytes. Examples Introducción básica a las matrices Una matriz es una estructura de datos que almacena valores del mismo tipo de datos. En Python, esta es la principal diferencia entre matrices y listas. Mientras que las listas de python pueden contener valores correspondientes a diferentes tipos de
    • 175. https://riptutorial.com/es/home 110 from array import * arrayIdentifierName = array(typecode, [Initializers]) my_array = array('i',[1,2,3,4]) from array import * my_array =array('i', [1,2,3,4,5]) for i in my_array: print(i) # 1 # 2 # 3 # 4 # 5 my_array = array('i', [1,2,3,4,5]) print(my_array[1]) # 2 datos, las matrices en python solo pueden contener valores correspondientes al mismo tipo de datos. En este tutorial, entenderemos las matrices de Python con algunos ejemplos. Si eres nuevo en Python, comienza con el artículo de Introducción a Python. Para usar arrays en lenguaje python, necesita importar el módulo de array estándar.Esto se debe a que la matriz no es un tipo de datos fundamental como cadenas, números enteros, etc.Aquí se explica cómo puede importar array módulo de array en Python: Una vez que haya importado el módulo de array , puede declarar una matriz. Así es como lo haces: En ladeclaración anterior, arrayIdentifierName eselnombredelamatriz, typecode permitea pythonsabereltipodematrizylosInitializerssonlosvaloresconlosqueseinicializalamatriz. Los códigos de tipo son los códigos que se utilizan para definir el tipo de valores de matriz o el tipo de matriz. La tabla en la sección de parámetros muestra los valores posibles que puede usar al declarar una matriz y su tipo. Aquí hay un ejemplo del mundo real de declaración de matriz de python: Enelejemploanterior,elcódigodecódigoutilizadoesi.Estecódigodecódigorepresentaun entero con signo cuyo tamaño es de 2 bytes. Aquí hay un ejemplo simple de una matriz que contiene 5 enteros Accede a elementos individuales a través de índices. Se puede acceder a elementos individuales a través de índices. Las matrices de Python están indexadas a cero. Aquí hay un ejemplo :
    • 176. 111 my_array = array('i', [1,2,3,4,5]) my_array.append(6) # array('i', [1, 2, 3, 4, 5, 6]) my_array = array('i', [1,2,3,4,5]) my_array.insert(0,0) #array('i', [0, 1, 2, 3, 4, 5]) my_array = array('i', [1,2,3,4,5]) my_extnd_array = array('i', [7,8,9,10]) my_array.extend(my_extnd_array) # array('i', [1, 2, 3, 4, 5, 7, 8, 9, 10]) Agregue cualquier valor a la matriz usando el método append () Tenga en cuenta que el valor 6 se agregó a los valores de matriz existentes. Insertar valor en una matriz usando el método insert () Podemos usar el método insert() para insertar un valor en cualquier índice de la matriz. Aquí hay un ejemplo : En el ejemplo anterior, el valor 0 se insertó en el índice 0. Tenga en cuenta que el primer argumento es el índice, mientras que el segundo argumento es el valor. Extiende la matriz de python usando el método extend () Una matriz de python se puede ampliar con más de un valor utilizando extend() método extend() . Aquí hay un ejemplo : Vemos que la matriz my_array se extendió con los valores de my_extnd_array . Agregue elementos de la lista a la matriz usando el método fromlist () Aquí hay un ejemplo: Entonces vemos que los valores 11,12 y 13 se agregaron de la lista c a my_array . Elimine cualquier elemento del arreglo usando el método remove () print(my_array[2]) # 3 print(my_array[0]) # 1 my_array = array('i', [1,2,3,4,5]) c=[11,12,13] my_array.fromlist(c) # array('i', [1, 2, 3, 4, 5, 11, 12, 13])
    • 177. 112 my_array = array('i', [1,2,3,4,5]) my_array.remove(4) # array('i', [1, 2, 3, 5]) my_array = array('i', [1,2,3,4,5]) my_array.pop() # array('i', [1, 2, 3, 4]) my_array = array('i', [1,2,3,4,5]) print(my_array.index(5)) # 5 my_array = array('i', [1,2,3,3,5]) print(my_array.index(3)) # 3 my_array = array('i', [1,2,3,4,5]) my_array.reverse() # array('i', [5, 4, 3, 2, 1]) my_array = array('i', [1,2,3,4,5]) my_array.buffer_info() (33881712, 5) Aquí hay un ejemplo : Vemos que el elemento 4 fue eliminado de la matriz. Eliminar el último elemento de la matriz utilizando el método pop () pop elimina el último elemento de la matriz. Aquí hay un ejemplo : Así que vemos que el último elemento ( 5 ) se extrajo de la matriz. Obtenga cualquier elemento a través de su índice usando el método index () index() devuelve el primer índice del valor coincidente. Recuerde que las matrices están indexadas a cero. Tenga en cuenta en ese segundo ejemplo que solo se devolvió un índice, aunque el valor existe dos veces en la matriz Invertir una matriz de python usando el método reverse () El método reverse() hace lo que el nombre dice que hará: invierte la matriz. Aquí hay un ejemplo : Obtener información de búfer de matriz a través del método buffer_info () Este método le proporciona la dirección de inicio del búfer de matriz en la memoria y la cantidad de elementos en la matriz. Aquí hay un ejemplo:
    • 178. 113 my_array = array('i', [1,2,3,3,5]) my_array.count(3) # 2 my_char_array = array('c', ['g','e','e','k']) # array('c', 'geek') print(my_char_array.tostring()) # geek my_array = array('i', [1,2,3,4,5]) c = my_array.tolist() # [1, 2, 3, 4, 5] my_char_array = array('c', ['g','e','e','k']) my_char_array.fromstring("stuff") print(my_char_array) #array('c', 'geekstuff') Compruebe el número de apariciones de un elemento utilizando el método count () count() devolverá el número de veces y el elemento aparecerá en una matriz. En el siguiente ejemplo vemos que el valor 3 aparece dos veces. Convierte una matriz en una cadena usando el método tostring () tostring() convierte la matriz en una cadena. Convierta la matriz a una lista de python con los mismos elementos utilizando el método tolist () Cuandonecesiteunobjetodelist Python,puedeutilizarel métodotolist() paraconvertirsu matriz en una lista. Agregue una cadena a la matriz de caracteres utilizando el método fromstring () Puede agregar una cadena a una matriz de caracteres usando fromstring()
    • 179. 114 import pyglet audio = pyglet.media.load("audio.wav") audio.play() import winsound winsound.PlaySound("path_to_wav_file.wav", winsound.SND_FILENAME) assert len(frames) == sample_width * n_frames # Duplicate to a new WAV file. with wave.open("path_to_new_wav_file.wav", "wb") as wav_file: # Open WAV file in write-only mode. # Write audio data. params = (n_channels, sample_width, framerate, n_frames, comp_type, comp_name) wav_file.setparams(params) wav_file.writeframes(frames) # Read n_frames new frames. # Read audio data. frames = wav_file.readframes(n_frames) n_channels = wav_file.getnchannels() # Number of channels. (1=Mono, 2=Stereo). sample_width = wav_file.getsampwidth() # Sample width in bytes. framerate = wav_file.getframerate() # Frame rate. n_frames = wav_file.getnframes() # Number of frames. comp_type = wav_file.getcomptype() # Compression type (only supports "NONE"). comp_name = wav_file.getcompname() # Compression name. #Open WAVfile in read-only import wave with wave.open("path_to_wav_file.wav", "rb") as wav_file: mode. # Get basic information. Capítulo 19: Audio Examples Audio con pyglet Para más información, ver pyglet. Trabajando con archivos WAV WinSound • Entorno de Windows ola • Soporte mono / estéreo • No soporta compresión / descompresión
    • 180. 115 from subprocess import check_call ok = check_call(['ffmpeg','-i','input.mp3','output.wav']) if ok: with open('output.wav', 'rb') as f: wav_file = f.read() import winsound freq = 2500 # Set frequency To 2500 Hertz dur = 1000 # Set duration To 1000 ms == 1 second winsound.Beep(freq, dur) Convierte cualquier archivo de sonido con python y ffmpeg Nota: • http://superuser.com/questions/507386/why-would-i-choose-libav-over-ffmpeg-or-is-thereeven-a-difference • ¿Cuáles son las diferencias y similitudes entre ffmpeg, libav y avconv? Tocando los pitidos de Windows Windows proporciona una interfaz explícita a través de la cual el módulo winsound permite reproducir sonidos brutos en una frecuencia y duración determinadas.
    • 181. 116 class CustomError(Exception): pass x = 1 if x == 1: raise CustomError('This is custom error') Traceback (most recent call last): File "error_custom.py", line 8, in <module> raise CustomError('This is custom error') main .CustomError: This is custom error class CustomError(Exception): pass try: raise CustomError('Can you catch me ?') Capítulo 20: Aumentar errores / excepciones personalizados Introducción Python tiene muchas excepciones integradas que obligan a su programa a generar un error cuando algo falla. Sin embargo, a veces es posible que necesite crear excepciones personalizadas que sirvan a su propósito. En Python, los usuarios pueden definir dichas excepciones creando una nueva clase. Esta clase de excepción debe derivarse, directa o indirectamente, de la clase de excepción. La mayoría de las excepciones incorporadas también se derivan de esta clase. Examples Excepción personalizada Aquí, hemos creado una excepción definida por el usuario llamada CustomError que se deriva de la clase Exception. Esta nueva excepción se puede generar, como otras excepciones, usando la declaración de aumento con un mensaje de error opcional. Salida: Atrapar Excepción personalizada Este ejemplo muestra cómo capturar Excepciones personalizadas
    • 182. 117 Catched CustomError :Can you catch me ? Salida: except CustomError as e: print ('Catched CustomError :{}'.format(e)) except Exception as e: print ('Generic exception: {}'.format(e))
    • 183. 118 subprocess.call([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg']) subprocess.call('echo "Hello, world"', shell=True) Capítulo 21: Biblioteca de subproceso Sintaxis • subprocess.call (args, *, stdin = None, stdout = None, stderr = None, shell = False, timeout = None) • subprocess.Popen (args, bufsize = -1, executable = None, stdin = None, stdout = None, stderr = None, preexec_fn = None, close_fds = True, shell = False, cwd = None, env = None, universal_newlines = False , startupinfo = Ninguna, creationflags = 0, restore_signals = True, start_new_session = False, pass_fds = ()) Parámetros Parámetro Detalles args Un soloejecutable, osecuenciadeejecutables yargumentos -'ls',['ls', la'] '- shell Ejecutar bajo una cáscara? El shell predeterminado para /bin/sh en POSIX. cwd Directorio de trabajo del proceso hijo. Examples Llamando Comandos Externos El caso de uso más simple es usar la función subprocess.call . Acepta una lista como primer argumento. El primer elemento de la lista debe ser la aplicación externa a la que desea llamar. Los otros elementos de la lista son argumentos que se pasarán a esa aplicación. Para los comandos de shell, establezca shell=True y proporcione el comando como una cadena en lugar de una lista. Tenga en cuenta que los dos comandos anteriores solo devuelven el exitstatus de exitstatus delsubproceso.Además,presteatencióncuandouseshell=Trueyaqueproporcionaproblemas de seguridad (consulte aquí ). Si desea poder obtener la salida estándar del subproceso, sustituya el subprocess.call con subprocess.check_output . Para un uso más avanzado, refiérase a esto .
    • 184. 119 process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg']) process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg']) process.wait() process = subprocess.Popen([r'C:\path\to\app.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # This will block until process completes stdout, stderr = process.communicate() print stdout print stderr process = subprocess.Popen([r'C:\path\to\app.exe'], stdout = subprocess.PIPE, stdin = subprocess.PIPE) process.stdin.write('line of input\n') # Write input line = process.stdout.readline() # Read a line fromstdout Más flexibilidad con Popen El uso de subprocess.Popen proporciona un control más preciso sobre los procesos iniciados que subprocess.call . Lanzar un subproceso La firma para Popen es muy similar a la función de call ; sin embargo, Popen regresará de inmediato en lugar de esperar a que se complete el subproceso como lo hace la call . Esperando en un subproceso para completar Salida de lectura de un subproceso Acceso interactivo a subprocesos en ejecución. Puede leer y escribir en stdin y stdout incluso cuando el subproceso no se haya completado. Esto podría ser útil al automatizar la funcionalidad en otro programa. Escribiendo a un subproceso
    • 185. https://riptutorial.com/es/home 120 process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE) while process.poll() is None: output_line = process.stdout.readline() process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE) while process.poll() is None: output_line = process.stdout.read(1) import shlex cmd_to_subprocess = shlex.split(command_used_in_the_shell) import shlex Sinembargo, si solonecesitaun conjunto de entrada y salida, en lugar de una interacción dinámica, debe usar communicate() lugar de acceder directamente a stdin y stdout . Leyendo un stream desde un subproceso En caso de que quiera ver la salida de un subproceso línea por línea, puede usar el siguiente fragmento de código: en el caso de que la salida del subcomando no tenga un carácter EOL, el fragmento de código anterior no funciona. A continuación, puede leer el carácter de salida por carácter de la siguiente manera: El 1 especificado como argumento a la read método se indica a leer a leer 1 carácter cada vez. Puede especificar leer tantos caracteres como desee utilizando un número diferente. El número negativo o 0 indica que se read para leer como una sola cadena hasta que se encuentre el EOF ( consulte aquí ). En los dos fragmentos de código anteriores, process.poll() es None hasta que finalice el subproceso. Esto se usa para salir del bucle una vez que no hay más salida para leer. El mismo procedimiento podría aplicarse al stderr del subproceso. Cómo crear el argumento de la lista de comandos Elmétodo de subprocesoque permite ejecutarcomandosnecesitaelcomandoen formadeuna lista (al menos usando shell_mode=True ). Las reglas para crear la lista no siempre son sencillas de seguir, especialmente con comandos complejos. Afortunadamente, hay una herramienta muy útil que permite hacer eso: shlex . La forma más fácil de crear la lista que se utilizará como comando es la siguiente: Un ejemplo simple: # Do logic on line read.
    • 186. 121 shlex.split('ls --color -l -t -r') out: ['ls', '--color', '-l', '-t', '-r']
    • 187. 122 Capítulo 22: Bloques de código, marcos de ejecución y espacios de nombres. Introducción Un bloque de código es una parte del texto del programa Python que se puede ejecutar como una unidad, como un módulo, una definición de clase o un cuerpo de función. Algunos bloques de código (como módulos) normalmente se ejecutan solo una vez, otros (como cuerpos de función) pueden ejecutarse muchas veces. Los bloques de código pueden contener textualmente otros bloques de código. Los bloques de código pueden invocar otros bloques de código (que pueden o no estar contenidos textualmente en ellos) como parte de su ejecución, por ejemplo, invocando (llamando) una función. Examples Espacios de nombres de bloque de código Tipo de bloque de código Espacio de nombres global Espacio de nombres local Módulo ns para el modulo igual que global Script (archivo o comando) ns para main igual que global Comando interactivo ns para main igual que global Definición de clase ns globales del bloque que contiene nuevo espacio de nombres Cuerpo de funcion ns globales del bloque que contiene nuevo espacio de nombres Cadenapasada ala sentencia exec ns globales del bloque que contiene espacio de nombres local del bloque que contiene Cadena pasada a eval() ns global de la persona que llama ns locales de la persona que llama Archivo leído por execfile() ns global de la persona que llama ns locales de la persona que llama Expresión leída por input() ns global de la persona que llama ns locales de la persona que llama
    • 188. 123
    • 189. 124 for x in ['one', 'two', 'three', 'four']: print(x) one two Capítulo 23: Bucles Introducción Como una de las funciones más básicas de la programación, los bucles son una pieza importante para casi todos los lenguajes de programación. Los bucles permiten a los desarrolladores configurar ciertas partes de su código para que se repitan a través de una serie de bucles que se conocen como iteraciones. Este tema cubre el uso de múltiples tipos de bucles y aplicaciones de bucles en Python. Sintaxis • mientras que <expresión booleana>: • para <variable> en <iterable>: • para <variable> en rango (<número>): • para <variable> en el rango (<start_number>, <end_number>): • para <variable> en el rango (<start_number>, <end_number>, <step_size>): • para i, <variable> in enumerate (<iterable>): # con índice i • para <variable1>, <variable2> en zip (<iterable1>, <iterable2>): Parámetros Parámetro Detalles expresión booleana Expresión que se puede evaluar en un contexto booleano, por ejemplo, x < 10 variable Nombre de variable para el elemento actual del iterable iterable cualquier cosa que implemente iteraciones Examples Iterando sobre listas Para recorrer una lista puedes usar for : Esto imprimirá los elementos de la lista:
    • 190. 125 for x in range(1, 6): print(x) 1 2 3 4 5 forindex,iteminenumerate(['one','two','three','four']): print(index, '::', item) x = map(lambda e : e.upper(), ['one', 'two', 'three', 'four']) print(x) ['ONE', 'TWO', 'THREE', 'FOUR'] # Python 2.x La función de range genera números que también se utilizan a menudo en un bucle for. El resultado será un tipo de secuencia de rango especial en python> = 3 y una lista en python <= 2. Ambos se pueden pasar usando el bucle for. Si desea recorrer los elementos de una lista y también tener un índice para los elementos, puede usar la función de enumerate de Python: enumerate generará tuplas, que se desempaquetan en index (un entero) y item (el valorreal de la lista). El bucle de arriba se imprimirá (0, '::', 'one') (1, '::', 'two') (2, '::', 'three') (3, '::', 'four') Iterar sobre una lista con manipulación de valores usando map y lambda , es decir, aplicar la función lambda en cada elemento de la lista: Salida: NB: en Python 3.x map devuelve un iterador en lugar de una lista, por lo que, en caso de que necesite una lista, debe emitir la print(list(x)) del resultado print(list(x)) (consulte http://www.levcode.com/python/ example / 8186 / map-- en http://www.levcode.com/python/topic/809/incompatibilities-moving-from-python-2-to-python-3 ). Para bucles forbucles,repita una colección de elementos, como list o dict , y ejecute un bloque de código three four
    • 191. 126 for i in [0, 1, 2, 3, 4]: print(i) 0 1 2 3 4 for i in range(5): print(i) i = 0 while i < 7: print(i) if i == 4: print("Breaking from loop") break i += 1 con cada elemento de la colección. Lo anterior for bucle se repite sobre una lista de números. Cada iteración establece el valor de i en el siguiente elemento de la lista. Entonces primero será 0 , luego 1 , luego 2 , etc. La salida será la siguiente: range es una función que devuelve una serie de números bajo una forma iterable, porlo que se puede utilizar en for bucles: da exactamente el mismo resultado que el primer bucle for . Tenga en cuenta que 5 no se imprime, ya que el rango aquí corresponde a los primeros cinco números que cuentan desde 0 . Objetos iterables e iteradores. for loop puede iterar en cualquier objeto iterable que sea un objeto que defina una función getitem o iter . Lafunción iter devuelve uniterador, que es unobjeto con una función next que se utiliza para acceder al siguiente elemento delaiterable. Romper y continuar en bucles declaración de break Cuando una instrucción de break ejecuta dentro de un bucle, el flujo de control se "interrumpe" inmediatamente: El condicional de bucle no se evaluará después de que se ejecute la instrucción break . Tenga en
    • 192. 127 0 1 2 3 4 Breaking from loop for i in (0, 1, 2, 3, 4): print(i) if i == 2: break 0 1 2 for i in (0, 1, 2, 3, 4, 5): if i == 2 or i == 4: continue print(i) 0 1 3 5 cuenta que las declaraciones de break solo se permiten dentro de los bucles , sintácticamente. No se puede usar una declaración de break dentro de una función para terminar los bucles que llamaron a esa función. La ejecución de lo siguiente imprime cada dígito hasta el número 4 cuando se cumple la instrucción break y el bucle se detiene: break declaraciones de break también se pueden usar dentro for bucles, la otra construcción de bucle proporcionada por Python: La ejecución de este bucle ahora imprime: Tenga en cuenta que 3 y 4 no se imprimen ya que el bucle ha finalizado. Si un bucle tiene una cláusula else , no se ejecuta cuando el bucle termina a través de una instrucción de break . continue declaración Una instrucción de continue pasará a la siguiente iteración del bucle, omitiendo el resto del bloque actual pero continuando el bucle. Al igual que con break , continue solo puede aparecer dentro de los bucles: Tenga en cuenta que 2 y 4 no se imprimen, esto se debe a que continue va a la siguiente iteración
    • 193. 128 break # Will only break out of the inner loop! while True: for i inrange(1,5): if i == 2: def break_loop(): for i in range(1, 5): if (i == 2): return(i) print(i) return(5) def break_all(): for j in range(1, 5): for i inrange(1,4): if i*j == 6: return(i) print(i*j) 1 # 1*1 2 # 1*2 3 # 1*3 4 # 1*4 2 # 2*1 4 # 2*2 # return because 2*3 = 6, the remaining iterations of both loops are not executed en lugar de continuar print(i) cuando i == 2 o i == 4 . Bucles anidados break y continue solo funciona en un solo nivel de bucle. El siguiente ejemplo solo saldrá del bucle for interno, no del bucle while externo: Python no tiene la capacidad de romper múltiples niveles de bucles a la vez; si se desea este comportamiento, refactorizar uno o más bucles en una función y reemplazar la break con el return puede ser la forma de hacerlo. Usa el return desde dentro de una función como un break La declaración de return sale de una función, sin ejecutar el código que viene después de ella. Si tiene un bucle dentro de una función, usar el return desde dentro de ese bucle es equivalente a tener una break ya que el resto del código del bucle no se ejecuta ( tenga en cuenta que cualquier código después del bucle tampoco se ejecuta): Si tiene bucles anidados, la instrucción de return romperá todos los bucles: saldrá:
    • 194. 129 for i in range(3): print(i) else: print('done') i = 0 while i < 3: print(i) i += 1 else: print('done') 0 1 2 done for i in range(2): print(i) if i == 1: break else: print('done') 0 1 Bucles con una cláusula "else" Las declaraciones for y while (loops) pueden tener opcionalmente una cláusula else (en la práctica, este uso es bastante raro). El else cláusula sólo se ejecuta después de un for bucle termina por iteración a la terminación, o después de un while bucle termina por su expresión condicional convertirse en falsa. salida: La cláusula else no se ejecuta si el bucle termina de alguna otra manera (a través de una declaración de break o al generar una excepción): salida: La mayoría de los otros lenguajes de programación carecen de esta cláusula else opcional de bucles. El uso de la palabra clave else en particular a menudo se considera confuso. Elconceptooriginal para dicha cláusulase remonta aDonaldKnuth y el significado de la palabra claveelsequedaclarosireescribimosunbucleentérminosdedeclaracionesifygotodedías anterioresalaprogramaciónestructuradaodeunlenguajeensambladordenivel inferior. Por ejemplo:
    • 195. 130 # pseudocode <<start>>: if loop_condition(): ... if break_condition(): goto <<end>> ... goto <<start>> <<end>>: # pseudocode <<start>>: if loop_condition(): ... if break_condition(): goto <<end>> ... goto <<start>> else: print('done') <<end>>: es equivalente a: Estos siguen siendo equivalentes si adjuntamos una cláusula else a cada uno de ellos. Por ejemplo: es equivalente a: Un bucle for con una cláusula else puede entenderse de la misma manera. Conceptualmente, hayuna condición debucleque permanece verdadera mientrasel objetoolasecuenciaiterable aún tenga algunos elementos restantes. ¿Por qué uno usaría esta construcción extraña? while loop_condition(): ... if break_condition(): break ... else: print('done') while loop_condition(): ... if break_condition(): break ...
    • 196. 131 a = [1, 2, 3, 4] for i in a: if type(i) is not int: print(i) break else: print("no exception") d = {"a": 1, "b": 2, "c": 3} for key in d: print(key) "a" "b" "c" for key in d.keys(): print(key) for key in d.iterkeys(): print(key) for value in d.values(): El caso de uso principal para la construcción for...else es una implementación concisa de búsqueda como por ejemplo: Para hacer que la else de este constructo sea menos confuso, uno puede pensar en él como " si no se rompe " o " si no se encuentra ". Algunas discusiones sobre esto se pueden encontrar en [Python-ideas] Resumen de los hilos de for ... else , ¿Por qué python usa 'else' después de los bucles for y while? , y otras cláusulas en declaraciones de bucle Iterando sobre los diccionarios Teniendo en cuenta el siguiente diccionario: Para iterar a través de sus claves, puede utilizar: Salida: Esto es equivalente a: o en Python 2: Para iterar a través de sus valores, use:
    • 197. 132 1 2 3 for key, value in d.items(): print(key, "::", value) a :: 1 b ::2 c :: 3 i = 0 while i < 4: #loop statements i = i + 1 myObject = anObject() while myObject.isNotReady(): myObject.tryToGetReady() Salida: Para iterar a través de sus claves y valores, use: Salida: TengaencuentaqueenPython2,.keys(),.values()y.items()devuelvenunobjetodelist.Si simplementenecesitaiterarelresultado,puedeusarel.iterkeys(),.itervalues()y.iteritems(). La diferencia entre .keys() y .iterkeys() , .values() y .itervalues() , .items() y .iteritems() es quelosmétodos iter* songeneradores. Porlotanto, loselementosdentrodeldiccionario se producenunoporunoamedidaqueseevalúan. Cuandosedevuelveunobjeto delist ,todos loselementos se empaquetanenunalistay luegosedevuelvenparaunaevaluaciónadicional. Tenga en cuenta también que en Python 3, el orden de los elementos impresos de la manera anterior no sigue ningún orden. Mientras bucle A while bucle hará que las sentencias de bucle que se ejecutarán hasta que la condición de bucle es Falsey . El siguiente código ejecutará las instrucciones de bucle un total de 4 veces. Mientras que el bucle de arriba fácilmente se puede traducir en una más elegante for bucle, while los bucles son útiles para comprobar si alguna condición se ha cumplido. El siguiente bucle continuará ejecutándose hasta que myObject esté listo. print(value)
    • 198. 133 # Prints 1j forever while complex_num: # You can also replace complex_num with any number, True or a value of any type print(complex_num) import cmath complex_num = cmath.sqrt(-1) while True: print "Infinite loop" # Infinite loop # Infinite loop # Infinite loop # ... for x in range(10): pass #we don't want to do anything, or are not ready to do anything here, so we'll pass while x == y: pass while bucles también pueden ejecutarse sin unacondición usandonúmeros (complejos o reales) o True : Si la condición es siempre cierta, el bucle while se ejecutará para siempre (bucle infinito) si no se termina con una instrucción break o return o una excepción. La Declaración de Pase pass es una declaración nulo para cuando una instrucción se requiere por la sintaxis Python (tal como dentro del cuerpo de un for o while bucle), pero se requiere ninguna acción o se desee por el programador. Esto puede ser útil como un marcador de posición para el código que aúnno se ha escrito. En este ejemplo, nada pasará. El bucle for se completará sin error, pero no se ejecutará ningún comando o código. pass nos permite ejecutar nuestro código con éxito sin tener todos los comandos y acciones completamente implementados. Del mismo modo, pass puede ser utilizado en while bucles, así como en las selecciones y definiciones de función, etc. Iterando diferentes partes de una lista con diferentes tamaños de paso Supongamos que tiene una larga lista de elementos y solo está interesado en todos los demás elementos de la lista. Quizás solo desee examinar los primeros o últimos elementos, o un rango específico de entradas en su lista. Python tiene capacidades integradas de indexación fuertes. Aquí hay algunos ejemplos de cómo lograr estos escenarios. Aquí hay una lista simple que se utilizará a lo largo de los ejemplos:
    • 199. 134 for s in lst: print s[:1] # print the first letter a b c d e for idx, s in enumerate(lst): print("%s has an index of %d" % (s, idx)) alpha has an index of 0 bravo has an index of 1 charlie has an index of 2 delta has an index of 3 echo has an index of 4 for i in range(2,4): print("lst at %d contains %s" % (i, lst[i])) lst at 2 contains charlie lst at 3 contains delta Iteración sobre toda la lista. Para iterar sobre cada elemento de la lista, se puede usar un bucle for como abajo: El bucle for asigna s para cada elemento de lst . Esto imprimirá: A menudo necesitas tanto el elemento como el índice de ese elemento. La palabra clave enumerate realiza esa tarea. El índice idx comenzará con cero e incrementará para cada iteración, mientras que la s contendrá el elemento que se está procesando. El fragmento anterior se mostrará: Iterar sobre la sub-lista Si queremos iterar sobre un rango (recordando que Python usa indexación de base cero), use la palabra clave de range . Esto daría como resultado: La lista también puede ser cortada. La siguiente notación de segmento va desde el elemento en lst = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
    • 200. 135 for s in lst[1::2]: print(s) for i in range(1, len(lst), 2): print(lst[i]) bravo delta a = 10 while True: a = a-1 print(a) if a<7: break print('Done.') 9 8 7 6 Done. collection = [('a', 'b', 'c'), ('x', 'y', 'z'), ('1', '2', '3')] for item in collection: i1 = item[0] i2 = item[1] i3 = item[2] # logic el índice 1 hasta el final con un paso de 2. Los dos bucles for dan el mismo resultado. Las salidas de fragmento de código anteriores: La indexación y el corte es un tema propio. El "half loop" do-while A diferencia de otros idiomas, Python no tiene una construcción do-until o do-while (esto permitirá que el código se ejecute una vez antes de que se pruebe la condición). Sin embargo, puede combinar un while True con una break para lograr el mismo propósito. Esto imprimirá: Bucle y desembalaje Si quieres recorrer una lista de tuplas por ejemplo: En lugar de hacer algo como esto:
    • 201. 136 for item in collection: i1, i2, i3 = item # logic for i1, i2, i3 in collection: # logic o algo como esto: Simplemente puede hacer esto: Esto también funcionará para la mayoría de los tipos de iterables, no solo para tuplas.
    • 202. 137 # 4 # 20 astring.find('o') astring.rfind('o') astring = 'Hello on StackOverflow' astring.index('o') # 4 astring.rindex('o') # 20 astring.index('q') # ValueError: substring not found astring.find('q') # -1 astring.index('o', 5) # 6 astring.index('o', 6) # 6 - start is inclusive astring.index('o', 5, 7) # 6 astring.index('o', 5, 6) # - end is not inclusive astring.rindex('o', 20) # 20 astring.rindex('o', 19) # 20 - still from left to right astring.rindex('o', 4, 7) # 6 Capítulo 24: buscando Observaciones Todos los algoritmos de búsqueda en iterablesque contienen n elementos tienen complejidad O(n) . Solo los algoritmos especializados como bisect.bisect_left() pueden ser más rápidos con complejidad O(log(n)) . Examples Obtención del índice para cadenas: str.index (), str.rindex () y str.find (), str.rfind () String también tiene un método de index , pero también opciones más avanzadas y la función str.find adicional. Para ambos hay un método inverso complementario. Ladiferenciaentreindex / rindex y find /rfindesloquesucedesi lasubcadena noseencuentra en la cadena: Todos estos métodos permiten un índice de inicio y finalización: ValueError: subcadena no encontrada Buscando un elemento Todaslas colecciones integradasenPythonimplementanunaformadeverificarlapertenenciaal elemento usando in .
    • 203. 138 alist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 5 in alist # True 10 in alist # False atuple = ('0', '1', '2', '3', '4') 4 in atuple # False '4' in atuple # True astring = 'i am a string' 'a' in astring # True 'am' in astring # True 'I' in astring #False aset = {(10, 10), (20, 20), (30, 30)} (10, 10) in aset # True 10 in aset # False - explicitly searches in keys - explicitly searches in values - explicitly searches key/value pairs # True - implicitly searches in keys # False # True # True # True 1 in adict 'a' in adict 2 in adict.keys() 'a' in adict.values() (0, 'a') inadict.items() adict = {0: 'a', 1: 'b', 2: 'c', 3: 'd'} alist = [10, 16, 26, 5, 2, 19, 105, 26] # search for 16 in the list alist.index(16) # 1 alist[1] # 16 alist.index(15) Lista Tupla Cuerda Conjunto Dictado dict es un poco especial: lo normal in sólo comprueba las teclas. Si desea buscar en valores necesita especificarlo. Lo mismo si quieres buscar pares clave-valor . Obtención de la lista de índice y las tuplas: list.index (), tuple.index () list y tuple tienen un método de index para obtener la posición del elemento: ValueError: 15 no está en la lista
    • 204. 139 atuple = (10, 16, 26, 5, 2, 19, 105, 26) atuple.index(26) # 2 atuple[2] # 26 atuple[7] # 26 - is also 26! def getKeysForValue(dictionary, value): foundkeys = [] for keys in dictionary: if dictionary[key] == value: foundkeys.append(key) return foundkeys def getKeysForValueComp(dictionary, value): return [key for key in dictionary if dictionary[key] == value] def getOneKeyForValue(dictionary, value): return next(key for key in dictionary if dictionary[key] == value) getKeysForValueComp(adict, 10) # ['c', 'a'] - dito getKeysForValueComp(adict, 20) # ['b'] getKeysForValueComp(adict, 25) # [] getKeysForValue(adict, 10) # ['c', 'a'] - order is random could as well be ['a', 'c'] adict = {'a': 10, 'b': 20, 'c': 10} getOneKeyForValue(adict, 10) # 'c' - depending on the circumstances this could also be 'a' getOneKeyForValue(adict, 20) # 'b' getOneKeyForValue(adict, 25) Pero solo devuelve la posición del primer elemento encontrado: Buscando clave (s) para un valor en dict dict no tiene un método incorporado para buscar un valor o clave porque los diccionarios no están ordenados. Puede crear una función que obtenga la clave (o claves) para un valor específico: Esto también podría escribirse como una lista de comprensión equivalente: Si solo te importa una clave encontrada: Lasprimeras dosfunciones devolverán unalist de todaslaskeys quetienen el valor especificado: El otro solo devolverá una clave: y levante un StopIteration - Exception si el valor no está en el dict : StopIteration
    • 205. 140 import bisect def index_sorted(sorted_seq, value): """Locate the leftmost value exactly equal to x or raise a ValueError""" i = bisect.bisect_left(sorted_seq, value) ifi!=len(sorted_seq)andsorted_seq[i]==value: return i raise ValueError alist = [i for i in range(1, 100000, 3)] # Sorted list from 1 to 100000 with step 3 index_sorted(alist, 97285) # 32428 index_sorted(alist, 4) # 1 index_sorted(alist, 97286) %timeit index_sorted(alist, 97285) # 100000 loops, best of 3: 3 µs per loop %timeit alist.index(97285) # 1000 loops, best of 3: 1.58 ms per loop %timeit index_sorted(alist, 4) # 100000 loops, best of 3: 2.98 µs per loop %timeit alist.index(4) # 1000000 loops, best of 3: 580 ns per loop def outer_index(nested_sequence, value): return next(index for index, inner in enumerate(nested_sequence) for item in inner if item == value) alist_of_tuples = [(4, 5, 6), (3, 1, 'a'), (7, 0, 4.3)] outer_index(alist_of_tuples, 'a') # 1 outer_index(alist_of_tuples, 4.3) # 2 Obtención del índice para secuencias ordenadas: bisect.bisect_left () Las secuencias ordenadas permiten el uso de algoritmos de búsqueda más rápidos: bisect.bisect_left() 1 : ValueError Para secuencias clasificadas muy grandes , la ganancia de velocidad puede ser bastante alta. En caso de que la primera búsqueda sea aproximadamente 500 veces más rápida: Si bien es un poco más lento si el elemento es uno de los primeros: Buscando secuencias anidadas Labúsqueda ensecuencias anidadas comounalist detuple requiere unenfoquecomola búsqueda de valores en dict pero necesita funciones personalizadas. El índice de la secuencia más externa si el valor se encontró en la secuencia: o el índice de la secuencia externa e interna:
    • 206. 141 class ListList: def init (self, value): self.value = value # Create a set of all values for fast access self.setofvalues = set(item for sublist in self.value for item in sublist) def iter (self): print('Using iter .') # A generator over all sublist elements return (item for sublist in self.value for item in sublist) def contains (self, value): print('Usingcontains.') # Just lookup if the value is in the set return value in self.setofvalues # Even without the set you could use the iter method for the contains-check: # return any(item == value for item in iter(self)) a = ListList([[1,1,1],[0,1,1],[1,5,1]]) 10 in a # False # Prints: Using contains . 5 in a # True # Prints: Using contains . del ListList. contains 5 in a # True # Prints: Using iter . En general ( no siempre ) el uso del next y una expresión generadora con condiciones para encontrar la primera aparición del valor buscado es el enfoque más eficiente. Búsqueda en clases personalizadas: contains y iter Para permitirel uso de in para clases personalizadas, la clase debe proporcionar el método mágico contains o, en su defecto, un método iter . Supongamos que tiene una clase que contiene una list de list s: Usarla prueba de membresía es posible usando in : Incluso después de eliminar el método contains : def outer_inner_index(nested_sequence, value): return next((oindex, iindex) for oindex, inner in enumerate(nested_sequence) for iindex, item in enumerate(inner) if item == value) outer_inner_index(alist_of_tuples, 'a') # (1, 2) alist_of_tuples[1][2] # 'a' outer_inner_index(alist_of_tuples, 7) # (2, 0) alist_of_tuples[2][0] # 7
    • 207. 142 Nota:El buclein (como enfor i in a ) siempre usará iter inclusosi laclaseimplementaun método contains .
    • 208. 143 class Vector(object): def init (self, x, y): self.x = x self.y = y def add (self, v): # Addition with another vector. return Vector(self.x + v.x, self.y + v.y) def sub (self, v): # Subtraction with another vector. return Vector(self.x - v.x, self.y - v.y) def mul (self, s): # Multiplication with a scalar. return Vector(self.x * s, self.y * s) def div (self, s): # Division with a scalar. float_s = float(s) return Vector(self.x / float_s, self.y / float_s) def floordiv (self, s): # Divisionwith a scalar (value floored). return Vector(self.x // s, self.y // s) def repr (self): # Print friendly representation of Vector class. Else, it would # show up like, < main .Vector instance at 0x01DDDDC8>. return '<Vector (%f, %f)>' % (self.x, self.y, ) a = Vector(3, 5) b = Vector(2, 7) print a + b # Output: <Vector (5.000000, 12.000000)> print b - a # Output: <Vector (-1.000000, 2.000000)> print b * 1.3 # Output: <Vector (2.600000, 9.100000)> print a // 17 # Output: <Vector (0.000000, 0.000000)> Capítulo 25: Características ocultas Examples Sobrecarga del operador Todo en Python es un objeto. Cada objeto tiene algunos métodos internos especiales que utiliza para interactuar con otros objetos. En general, estos métodos siguen la convención de denominación action . En conjunto, esto se denomina como el modelo de datos de Python . Puedesobrecargar cualquieradeestosmétodos.Estoseusacomúnmenteenlasobrecargade operadoresenPython.A continuación se muestra un ejemplo de sobrecarga de operadores utilizando el modelo de datos de Python. La clase Vector crea un vector simple de dos variables. Agregaremoselsoporteadecuadoparaoperacionesmatemáticasdedosvectoresutilizandola sobrecarga de operadores.
    • 209. 144 El ejemplo anterior demuestra la sobrecarga de operadores numéricos básicos. Una lista completa se puede encontrar aquí . print a / 17 # Output: <Vector (0.176471, 0.294118)>
    • 210. 145 from chempy import Substance ferricyanide = Substance.from_formula('Fe(CN)6-3') ferricyanide.composition == {0: -3, 26: 1, 6: 6, 7: 6} True print(ferricyanide.unicode_name) Fe(CN)₆ ³⁻ print(ferricyanide.latex_name + ", " + ferricyanide.html_name) Fe(CN)_{6}^{3-}, Fe(CN)<sub>6</sub><sup>3-</sup> print('%.3f' % ferricyanide.mass) 211.955 from chempy import balance_stoichiometry # Main reaction in NASA's booster rockets: reac, prod = balance_stoichiometry({'NH4ClO4', 'Al'}, {'Al2O3', 'HCl', 'H2O', 'N2'}) from pprint import pprint pprint(reac) {'Al': 10, 'NH4ClO4': 6} pprint(prod) {'Al2O3': 5, 'H2O': 9, 'HCl': 6, 'N2': 3} from chempy import mass_fractions for fractions in map(mass_fractions, [reac, prod]): ... pprint({k: '{0:.3g} wt%'.format(v*100) for k, v in fractions.items()}) ... {'Al': '27.7 wt%', 'NH4ClO4': '72.3 wt%'} {'Al2O3': '52.3 wt%', 'H2O': '16.6 wt%', 'HCl': '22.4 wt%', 'N2': '8.62 wt%'} from chempy import Equilibrium from sympy import symbols K1, K2, Kw = symbols('K1 K2 Kw') e1 = Equilibrium({'MnO4-': 1, 'H+': 8, 'e-': 5}, {'Mn+2': 1, 'H2O': 4}, K1) e2 = Equilibrium({'O2': 1, 'H2O': 2, 'e-': 4}, {'OH-': 4}, K2) coeff = Equilibrium.eliminate([e1, e2], 'e-') Capítulo 26: ChemPy - paquete de python Introducción ChemPy es un paquete de Python diseñado principalmente para resolver y abordar problemas en Química física, analítica e inorgánica. Es un conjunto de herramientas gratuito de código abierto de Python para aplicaciones de química, ingeniería química y ciencia de materiales. Examples Fórmulas de análisis En composición, los números atómicos (y 0 para carga) se usan como claves y el recuento de cada tipo se convirtió en valor respectivo. Equilibrio de la estequiometría de una reacción química. Reacciones de equilibrio
    • 211. 146 from collections import defaultdict init_conc = defaultdict(float, {'H2O': 1, 'NH3': 0.1}) x, sol, sane = eqsys.root(init_conc) assert sol['success'] and sane print(sorted(sol.keys())) # see package "pyneqsys" for more info ['fun', 'intermediate_info', 'internal_x_vecs', 'nfev', 'njev', 'success', 'x', 'x_vecs'] print(', '.join('%.2g' % v for v in x)) 1, 0.0013, 7.6e-12, 0.099, 0.0013 print('\n'.join(map(str, eqsys.rxns))) # "rxns" short for "reactions" H2O = H+ + OH-; 1e-14 NH4+ = H+ + NH3; 5.75e-10 from chempy import Equilibrium from chempy.chemistry import Species water_autop = Equilibrium({'H2O'}, {'H+', 'OH-'}, 10**-14) # unit "molar" assumed ammonia_prot = Equilibrium({'NH4+'}, {'NH3', 'H+'}, 10**-9.24) # same here from chempy.equilibria import EqSystem substances = map(Species.from_formula, 'H2O OH- H+ NH3 NH4+'.split()) eqsys = EqSystem([water_autop, ammonia_prot], substances) from chempy.electrolytes import ionic_strength ionic_strength({'Fe+3': 0.050, 'ClO4-': 0.150}) == .3 True from chempy import ReactionSystem # The rate constants below are arbitrary rsys = ReactionSystem.from_string("""2 Fe+2 + H2O2 -> 2 Fe+3 + 2 OH-; 42 2 Fe+3 + H2O2 -> 2 Fe+2 + O2 + 2 H+; 17 H+ + OH- -> H2O; 1e10 H2O -> H+ + OH-; 1e-4 Fe+3 + 2 H2O -> FeOOH(s) + 3 H+; 1 FeOOH(s) + 3 H+ -> Fe+3 + 2 H2O; 2.5""") # "[H2O]" = 1.0 (actually 55.4 at RT) from chempy.kinetics.ode import get_odesys odesys, extra = get_odesys(rsys) from collections import defaultdict import numpy as np tout = sorted(np.concatenate((np.linspace(0, 23), np.logspace(-8, 1)))) c0 = defaultdict(float, {'Fe+2': 0.05, 'H2O2': 0.1, 'H2O': 1.0, 'H+': 1e-7, 'OH-': 1e-7}) result = odesys.integrate(tout, c0, atol=1e-12, rtol=1e-14) Equilibrios quimicos Fuerza iónica Cinética química (sistema de ecuaciones diferenciales ordinarias) coeff [4, -5] redox = e1*coeff[0] + e2*coeff[1] print(redox) 20 OH- + 32 H+ + 4 MnO4- = 26 H2O + 4 Mn+2 + 5 O2; K1**4/K2**5 autoprot = Equilibrium({'H2O': 1}, {'H+': 1, 'OH-': 1}, Kw) n = redox.cancel(autoprot) n 20 redox2 = redox + n*autoprot print(redox2) 12 H+ + 4 MnO4- = 4 Mn+2 + 5 O2 + 6 H2O; K1**4*Kw**20/K2**5
    • 212. 147 import matplotlib.pyplot as plt _ = plt.subplot(1, 2, 1) _ = result.plot(names=[k for k in rsys.substances if k != 'H2O']) _ = plt.legend(loc='best', prop={'size': 9}); _ = plt.xlabel('Time'); _ = plt.ylabel('Concentration') _ = plt.subplot(1, 2, 2) _ = result.plot(names=[k for k in rsys.substances if k != 'H2O'], xscale='log', yscale='log') _ = plt.legend(loc='best', prop={'size': 9}); _ = plt.xlabel('Time'); _ = plt.ylabel('Concentration') _ = plt.tight_layout() plt.show()
    • 213. 148 class Fruit: def check_ripeness(self): raise NotImplementedError("check_ripeness method not implemented!") class Apple(Fruit): pass a = Apple() a.check_ripeness() # raises NotImplementedError from abc import ABCMeta class AbstractClass(object): # the metaclass attribute must always be set as a class variable metaclass = ABCMeta # the abstractmethod decorator registers this method as undefined @abstractmethod def virtual_method_subclasses_must_define(self): # Can be left completely blank, or a base implementation can be provided # Note that ordinarily a blank interpretation implicitly returns `None`, # but by registering, this behaviour is no longer enforced. Capítulo 27: Clases base abstractas (abc) Examples Configuración de la metaclase ABCMeta Las clases abstractas son clases que están destinadas a ser heredadas pero evitan la implementación de métodos específicos, dejando atrás solo las firmas de métodos que las subclases deben implementar. Las clases abstractas son útiles para definir y hacer cumplir las abstracciones de clase a un alto nivel, similar al concepto de interfaces en lenguajes escritos, sin la necesidad de implementar métodos. Un enfoque conceptual para definir una clase abstracta es eliminar los métodos de la clase y, a continuación, generar un error NotImplemented si se accede. Esto evita que las clases de niños accedan a los métodos de los padres sin anularlos primero. Al igual que: La creación de una clase abstracta de esta manera evita el uso incorrecto de métodos que no se anulan, y ciertamente alienta a los métodos a ser definidos en clases secundarias, pero no impone su definición. Con el módulo abc podemos evitar que las clases secundarias se instalen cuando no pueden anular los métodos de clase abstracta de sus padres y ancestros: Ahora es posible simplemente subclasificar y anular:
    • 214. 149 class MontyPython: def joke(self): raise NotImplementedError() def punchline(self): raise NotImplementedError() class ArgumentClinic(MontyPython): def joke(self): return "Hahahahahah" >>> sketch = ArgumentClinic() >>> sketch.punchline() NotImplementedError from abc import ABCMeta, abstractmethod class MontyPython(metaclass=ABCMeta): @abstractmethod def joke(self): pass @abstractmethod def punchline(self): pass class ArgumentClinic(MontyPython): def joke(self): return "Hahahahahah" Por qué / Cómo usar ABCMeta y @abstractmethod Las clases base abstractas (ABC) imponen qué clases derivadas implementan métodos particulares de la clase base. Para entender cómo funciona esto y por qué debemos usarlo, echemos un vistazo a un ejemplo que Van Rossum disfrutaría. Digamos que tenemos una clase base "MontyPython" con dos métodos (broma y línea de remate) que deben ser implementados por todas las clases derivadas. Cuando creamos una instancia de un objeto y llamamos a sus dos métodos, obtendremos un error (como se esperaba) con el método punchline() . Sin embargo, esto todavía nos permite crear una instancia de un objeto de la clase ArgumentClinic sin obtener un error. De hecho, no recibimos un error hasta que buscamos el punchline (). Esto se evita utilizando el módulo de clase base abstracta (ABC). Veamos cómo funciona esto con el mismo ejemplo: class Subclass(AbstractClass): def virtual_method_subclasses_must_define(self): return
    • 215. 150 >>> c = ArgumentClinic() TypeError: "Can't instantiate abstract class ArgumentClinic with abstract methods punchline" class ArgumentClinic(MontyPython): def joke(self): return "Hahahahahah" def punchline(self): return "Send in the constable!" Esta vez, cuando intentamos crear una instancia de un objeto de la clase incompleta, ¡inmediatamente obtenemos un TypeError! En este caso, es fácil completar la clase para evitar cualquier TypeErrors: ¡Esta vez cuando creas un objeto, funciona!
    • 216. 151 min(7,2,1,5) # Output: 1 max(7,2,1,5) # Output: 7 list_of_tuples = [(0, 10), (1, 15), (2, 8)] min(list_of_tuples) # Output: (0, 10) import operator # The operator module contains efficient alternatives to the lambda function max(list_of_tuples, key=operator.itemgetter(0)) # Sorting by first element # Output: (2, 8) max(list_of_tuples, key=operator.itemgetter(1)) # Sorting by second element # Output: (1, 15) sorted(list_of_tuples, key=operator.itemgetter(0), reverse=True) #Reversed (decreasing) # Output: [(2, 8), (1, 15), (0, 10)] sorted(list_of_tuples, key=operator.itemgetter(1), reverse=True) # Reversed(decreasing) # Output: [(1, 15), (0, 10), (2, 8)] sorted(list_of_tuples, key=lambda x: x[1]) # Sorting by first element # Output: [(2, 8), (0, 10), (1, 15)] sorted(list_of_tuples, key=lambda x: x[0]) # Sorting byfirst element (increasing) # Output: [(0, 10), (1, 15), (2, 8)] min(list_of_tuples, key=lambda x: x[1]) # Sorting by second element # Output: (2, 8) min(list_of_tuples, key=lambda x: x[0]) # Sorting by first element # Output: (0, 10) Capítulo 28: Clasificación, mínimo y máximo Examples Obteniendo el mínimo o máximo de varios valores. Usando el argumento clave Encontrar el mínimo / máximo de una secuencia de secuencias es posible: pero si desea ordenar por un elemento específico en cada secuencia, use la key -argumento: Argumento predeterminado a max, min No puedes pasar una secuencia vacía a max o min :
    • 217. 152 max([], default=42) # Output: 42 max([], default=0) # Output: 0 adict = {'a': 3, 'b': 5, 'c': 1} min(adict) # Output:'a' max(adict) # Output: 'c' sorted(adict) # Output: ['a', 'b', 'c'] min(adict.items()) # Output: ('a', 3) max(adict.items()) # Output: ('c', 1) sorted(adict.items()) # Output: [('a', 3), ('b', 5), ('c', 1)] from collections import OrderedDict OrderedDict(sorted(adict.items())) # Output: OrderedDict([('a', 3), ('b', 5), ('c', 1)]) res = OrderedDict(sorted(adict.items())) res['a'] # Output: 3 min(adict.items(), key=lambda x: x[1]) # Output: ('c', 1) ValueError: min () arg es una secuencia vacía Sin embargo, con Python 3, puede pasar el default argumento de palabra clave con un valor que se devolverá si la secuencia está vacía, en lugar de generar una excepción: Caso especial: diccionarios Obtener el mínimo o el máximo o usar sorted depende de las iteraciones sobre el objeto. En el caso de dict , la iteración es solo sobre las teclas: Para mantener la estructura del diccionario, debe iterar sobre .items() : Para sorted , puede crear un OrderedDict para mantenerla clasificación mientras tiene una estructura similar a un dict : Por valor De nuevo, esto es posible usando el argumento key : min([])
    • 218. 153 sorted('bdca') # string # Output: ['a','b','c','d'] sorted({'11': 5, '3': 2, '10': 15}) # dict # Output: ['10', '11', '3'] # only iterates over the keys sorted({11, 8, 1}) # set # Output: [1, 8, 11] sorted(['c', 'A', 'b']) # list # Output: ['A', 'b', 'c'] sorted((7, 2, 1, 5)) # tuple # Output: [1, 2, 5, 7] min([2, 7, 5]) # Output: 2 sorted([2, 7, 5])[0] # Output: 2 max([2, 7, 5]) # Output: 7 sorted([2, 7, 5])[-1] # Output: 7 class MyClass(object): def init (self, value, name): self.value = value self.name =name def lt (self, other): Obteniendo una secuencia ordenada Usando una secuencia: El resultado es siempre una nueva list ; Los datos originales se mantienen sin cambios. Mínimo y máximo de una secuencia. Obtener el mínimo de una secuencia (iterable) es equivalente a acceder al primer elemento de una secuencia sorted : El máximo es un poco más complicado, porque sorted mantiene el orden y max devuelve el primer valor encontrado. En caso de que no haya duplicados, el máximo es el mismo que el último elemento de la declaración ordenada: Pero no si hay varios elementos que se evalúan como teniendo el valor máximo: max(adict.items(), key=operator.itemgetter(1)) # Output: ('b', 5) sorted(adict.items(), key=operator.itemgetter(1), reverse=True) # Output: [('b', 5), ('a', 3), ('c', 1)]
    • 219. 154 class IntegerContainer(object): def init (self, value): self.value = value def repr (self): return "{}({})".format(self. class . name , self.value) def lt (self, other): print('{!r} - Test less than {!r}'.format(self, other)) return self.value < other.value def le (self, other): print('{!r} - Test less than or equal to {!r}'.format(self, other)) return self.value <= other.value def gt (self, other): print('{!r} - Test greater than {!r}'.format(self, other)) return self.value > other.value def ge (self, other): print('{!r} - Test greater than or equal to {!r}'.format(self, other)) return self.value >= other.value def eq (self, other): print('{!r} - Test equal to {!r}'.format(self, other)) return self.value == other.value def ne (self, other): print('{!r} - Test not equal to {!r}'.format(self, other)) return self.value != other.value alist = [IntegerContainer(5), IntegerContainer(3), IntegerContainer(10), IntegerContainer(7) Se permite cualquier elemento que contenga iterable que admita < o > operaciones. Hacer clases personalizables ordenable min,maxysorted todosnecesitanquelosobjetossepuedanordenar.Paraserordenados adecuadamente,laclasenecesitadefinirtodoslos6métodos lt , gt , ge , le , ne y eq : Aunque implementar todos estos métodos parece innecesario, omitir algunos de ellos hará que su código sea propenso a errores . Ejemplos: return self.value < other.value def repr (self): return str(self.name) sorted([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')]) # Output: [second, first, third] max([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')]) # Output: first
    • 220. 155 res = sorted(alist, reverse=True) # Out: IntegerContainer(10) - Test less than IntegerContainer(7) # IntegerContainer(3) - Test less than IntegerContainer(10) # IntegerContainer(3) - Test less than IntegerContainer(10) # IntegerContainer(3) - Test less than IntegerContainer(7) # IntegerContainer(5) - Test less than IntegerContainer(7) # IntegerContainer(5) - Test less than IntegerContainer(3) print(res) # Out: [IntegerContainer(10), IntegerContainer(7), IntegerContainer(5), IntegerContainer(3)] del IntegerContainer. lt # The IntegerContainer no longer implements "less than" res = min(alist) # Out: IntegerContainer(5) - Test greater than IntegerContainer(3) # IntegerContainer(3) - Test greater than IntegerContainer(10) # IntegerContainer(3) - Test greater than IntegerContainer(7) print(res) # Out: IntegerContainer(3) del IntegerContainer. gt # The IntegerContainer no longer implements "greater then" res = min(alist) sorted con reverse=True también usa lt : Pero sorted puede usar gt cambio si el valor predeterminado no está implementado: Losmétodosdeclasificación generaránunTypeErrorsinoseimplementan lt ni gt : TypeError: tipos no ordenados: IntegerContainer () <IntegerContainer () ] res = max(alist) # Out: IntegerContainer(3) - Test greater than IntegerContainer(5) # IntegerContainer(10) - Test greater than IntegerContainer(5) # IntegerContainer(7) - Test greater than IntegerContainer(10) print(res) # Out: IntegerContainer(10) res = min(alist) # Out: IntegerContainer(3) - Test less than IntegerContainer(5) # IntegerContainer(10) - Test less than IntegerContainer(3) # IntegerContainer(7) - Test less than IntegerContainer(3) print(res) # Out: IntegerContainer(3) res = sorted(alist) # Out: IntegerContainer(3) - Test less than IntegerContainer(5) # IntegerContainer(10) - Test less than IntegerContainer(3) # IntegerContainer(10) - Test less than IntegerContainer(5) # IntegerContainer(7) - Test less than IntegerContainer(5) # IntegerContainer(7) - Test less than IntegerContainer(10) print(res) # Out: [IntegerContainer(3), IntegerContainer(5), IntegerContainer(7), IntegerContainer(10)]
    • 221. 156 import functools @functools.total_ordering class IntegerContainer(object): def init (self, value): self.value = value def repr (self): return "{}({})".format(self. class . name , self.value) def lt (self, other): print('{!r} - Test less than {!r}'.format(self, other)) return self.value < other.value def eq (self, other): print('{!r} - Test equal to {!r}'.format(self, other)) return self.value == other.value def ne (self, other): print('{!r} - Test not equal to {!r}'.format(self, other)) return self.value != other.value IntegerContainer(5) > IntegerContainer(6) # Output: IntegerContainer(5) - Test less than IntegerContainer(6) # Returns: False IntegerContainer(6) > IntegerContainer(5) # Output: IntegerContainer(6) - Test less than IntegerContainer(5) # Output: IntegerContainer(6) - Test equal to IntegerContainer(5) # Returns True import heapq # get 5 largest items from the range heapq.nlargest(5, range(10)) # Output: [9, 8, 7, 6, 5] heapq.nsmallest(5, range(10)) # Output: [0, 1, 2, 3, 4] functools.total_orderingdecoradorfunctools.total_ordering sepuedeutilizarparasimplificarel esfuerzodeescribirestosmétodosdecomparaciónricos.Sitotal_orderingtuclasecon total_ordering , necesitasimplementar eq , ne ysolo uno delos lt , le , ge o gt , y el decorador completará el resto: Observe cómo el > ( mayor que ) ahora llama al método menos que , y en algunos casos incluso el método eq . Esto también significa que si la velocidad es de gran importancia, debe implementar cada método de comparación enriquecida. Extraer N artículos más grandes o N más pequeños de un iterable Para encontrar un número (más de uno)delos valores más grandes o más pequeños de un iterable, puede usar el nlargest y nsmallest del módulo heapq :
    • 222. 157 longest_lines = sorted(f, key=len)[1000:] import heapq with open(filename) as f: longest_lines = heapq.nlargest(1000, f, key=len) Esto es mucho más eficiente que clasificar todo el material y luego cortarlo desde el final o el principio. Internamente, estas funciones utilizan la estructura de datos de la cola de prioridad del montón binario , que es muy eficiente para este caso de uso. Al igual que min , max y sorted , estas funciones aceptan el argumento de palabra key clave opcional,quedebe serunafunciónque,dado unelemento,devuelvesu clavedeclasificación. Aquí hay un programa que extrae 1000 líneas más largas de un archivo: Aquí abrimos el archivo y pasamos el identificador de archivo f a nlargest . La iteración del archivoproducecadalíneadelarchivocomounacadenaseparada; nlargestluegopasacada elemento(olínea)quepasaalafunciónlenparadeterminarsuclavedeclasificación.len,dada una cadena, devuelve la longitud de la línea en caracteres. Esto solo necesita almacenamiento para una lista de 1000 líneas más grandes hasta el momento, que se puede contrastar con que tendrá que mantener todo el archivo en la memoria .
    • 223. 158 # This is a single line comment in Python print("Hello World") # This line prints "HelloWorld" """ This type of comment spans multiple lines. These are mostly used for documentation of functions, classes and modules. """ Capítulo 29: Comentarios y Documentación Sintaxis • # Este es un comentario de una sola línea. • imprimir ("") # Este es un comentario en línea • "" Esto es un comentario multilínea "" Observaciones Los desarrolladores deben seguir las pautas PEP257 - Docstring Convenciones . En algunos casos, las guías de estilo (como las de la Guía de estilo de Google ) o la documentación que muestra a terceros (como Sphinx ) pueden detallar convenciones adicionales para las cadenas de documentación. Examples Comentarios de línea única, en línea y multilínea. Los comentarios se utilizan para explicar el código cuando el código básico en sí no está claro. Python ignora los comentarios, por lo que no ejecutará el código allí, ni generará errores de sintaxis para las oraciones simples en inglés. Los comentarios de una sola línea comienzan con el carácter de hash ( # ) y terminan al final de la línea. • Comentario de una sola línea: • Comentario en línea: • Loscomentarios queabarcan variaslíneas tienen """o''' en cualquieradelosextremos. Eslomismoqueunacadenamultilínea,perosepuedenusarcomocomentarios:
    • 224. 159 def func(): """This is a function that does nothing at all""" return print(func. doc ) help(func) def greet(name, greeting="Hello"): """Print a greeting to the user `name` Optional parameter `greeting` can change what they're greeted with.""" print("{} {}".format(greeting, name)) help(greet) Accediendo programáticamente a las cadenas de documentación Las cadenas de documentos son, a diferencia de los comentarios regulares, almacenados como un atributo de la función que documentan, lo que significa que puede acceder a ellos mediante programación. Una función de ejemplo Se puede acceder a la doc utilizando el atributo doc : Esta es una función que no hace nada en absoluto. Ayuda en la función de func en el módulo main : func() Esta es una función que no hace nada en absoluto. Otra función de ejemplo function. doc es sololacadena de documentos real como unacadena, mientras que la función dehelpproporcionainformacióngeneralsobreunafunción,incluidalacadenadedocumentos. Aquí hay un ejemplo másútil: Ayuda en función greet en el módulo main : greet(name, greeting='Hello') Imprime un saludo al name usuario El parámetro de greeting opcional puede cambiar lo que se saluda con.
    • 225. 160 def greet(name, greeting="Hello"): # Print a greeting to the user `name` # Optional parameter `greeting` can change what they're greeted with. print("{} {}".format(greeting, name)) print(greet. doc ) help(greet) def hello(name): """Greet someone. Print a greeting ("Hello") for the person with the given name. """ print("Hello "+name) class Greeter: """An object used to greet people. It contains multiple greeting functions for several languages and times of the day. """ Ventajas de docstrings sobre comentarios regulares El solo hecho de no poner una cadena de documentos o un comentario regular en una función hace que sea mucho menos útil. Ninguna Ayuda en función saludar en módulo principal : greet(name, greeting='Hello') Escribir documentación utilizando cadenas de documentación. Una cadena de documentación es un comentario de varias líneas que se utiliza para documentar módulos, clases, funciones y métodos. Tiene que ser la primera declaración del componente que describe. Se puede acceder al valor de la cadena de documentos dentro del programa y, por ejemplo, el comando de help utiliza. Convenciones de sintaxis PEP 257
    • 226. 161 def hello(): """Say hello to your friends.""" print("Hello my friends!") def hello(name, language="en"): """Say hello to a person. Arguments: name: the name of the person language: the language in which the person should be greeted """ print(greeting[language]+" "+name) def hello(name, language="en"): PEP 257 define un estándar de sintaxis para comentarios de cadena de documentación. Básicamente permite dos tipos: • Docstrings de una línea: Según PEP 257, deben usarse con funciones cortas y simples. Todo se coloca en una línea, por ejemplo: La cadena de documentos debe terminar con un punto, el verbo debe estar en la forma imperativa. • Docstrings multilínea: La cadena de documentos multilínea se debe utilizar para funciones, módulos o clases más largas y complejas. Comienzan con un breve resumen (equivalente al contenido de una cadena de documentación de una línea) que puede estar en la misma línea que las comillas o en la siguiente línea, dan detalles adicionales y enumeran parámetros y valores de retorno. La nota PEP 257 define qué información se debe dar dentro de una cadena de documentación, no define en qué formato se debe dar. Esta fue la razón para que otras partes y herramientas de análisis de documentación especifiquen sus propios estándares para la documentación, algunos de los cuales se enumeran a continuación y en esta pregunta . Esfinge Sphinx es una herramienta para generar documentación basada en HTML para proyectos de Python basados en cadenas de documentación. Su lenguaje de marcado utilizado es reStructuredText . Definen sus propios estándares para la documentación, pythonhosted.org alberga una muy buena descripción de ellos . El formato Sphinx es, por ejemplo, utilizado por el IDE de pyCharm . Una función se documentaría así utilizando el formato Sphinx / reStructuredText:
    • 227. 162 def hello(name, language="en"): """Say hello to a person. Args: name: the name of the person as string language: the language code string Returns: A number. """ print(greeting[language]+" "+name) return 4 Guía de estilo de Google Python Google ha publicado la Guía de estilo de Google Python que define las convenciones de codificación para Python, incluidos los comentarios de la documentación. En comparación con Sphinx / reST, muchas personas dicen que la documentación de acuerdo con las directrices de Google es mejor legible para los humanos. La página pythonhosted.org mencionada anteriormente también proporciona algunos ejemplos de buena documentación de acuerdo con la Guía de estilo de Google. Al usar el complemento de Napoleón , Sphinx también puede analizar la documentación en el formato compatible con la Guía de estilo de Google. Una función se documentaría así utilizando el formato de la Guía de estilo de Google: """Say hello to a person. :param name: the name of the person :type name: str :param language: the language in which the person should be greeted :type language: str :return: a number :rtype: int """ print(greeting[language]+" "+name) return 4
    • 228. 163 x > y x < y 12 > 4 # True 12 < 4 # False 1 < 4 # True Capítulo 30: Comparaciones Sintaxis • ! = - No es igual a • == - es igual a • > - mayor que • < - menos que • >= - mayor que o igual a • <= - menor o igual que • is - prueba si los objetos son exactamente el mismo objeto • no es = prueba si los objetos no son exactamente el mismo objeto Parámetros Parámetro Detalles X Primer artículo a comparar y Segundo elemento a comparar Examples Mayor o menor que Estos operadores comparan dos tipos de valores, son menos que y mayores que los operadores. Para los números, esto simplemente compara los valores numéricos para ver cuál es más grande: Para las cuerdas, se compararán lexicográficamente, lo cual es similar al orden alfabético pero no
    • 229. 164 "alpha" < "beta" # True "gamma" > "beta" # True "gamma" < "OMEGA" # False "GAMMA" < "OMEGA" # True x != y 12 != 1 # True 12 != '12' # True '12' != '12' # False x == y 12 == 12 # True 12 == 1 # False '12' == '12' # True 'spam' == 'spam' # True 'spam' == 'spam' # False '12' == 12 es exactamente el mismo. En estas comparaciones, las letras minúsculas se consideran "mayores que" en mayúsculas, por lo que "gamma" < "OMEGA" es falso. Si todos estuvieran en mayúsculas, devolvería el resultado de orden alfabético esperado: Cada tipo define su cálculo con los operadores < y > diferente, por lo que debe investigar qué significan los operadores con un tipo dado antes de usarlo. No igual a Esto devuelve True si x e y no son iguales y, de lo contrario, devuelve False . Igual a Esta expresión se evalúa si x y y son del mismo valor y devuelve el resultado como un valor booleano.En general, tanto el tipo como el valor deben coincidir, porlo que el int 12 no es lo mismo que la cadena '12' .
    • 230. 165 x > y > z x > y and y > z 1 > -1 < 2 > 0.5 < 100 != 24 1 > x > -4 > y != 8 Tenga en cuenta que cada tipo debe definir una función que se utilizará para evaluar si dos valores soniguales.Paralos tipos incorporados,estas funcionessecomportancomocabría esperar y solo evalúan las cosas basándose en el mismo valor. Sin embargo, los tipos personalizadospuedendefinirlaspruebasde igualdadcomolodeseen,incluyendodevolver siempre True o siempre False . Comparaciones de cadena Puede comparar varios elementos con múltiples operadores de comparación con comparación de cadena. Por ejemplo Es sólo una forma corta de: Esto se evaluará como True solo si ambas comparaciones son True . La forma general es Donde OP representa una de las múltiples operaciones de comparación que puede usar, y las letras representan expresiones válidas arbitrarias. Tenga en cuenta que 0 != 1 != 0 evalúa como True , aunque 0 != 0 sea False . A diferencia de la notación matemática común en la que x != y != z significa que x , y , z tienenvaloresdiferentes.Lasoperacionesdeencadenamiento == tienenelsignificado naturalenlamayoríadeloscasos, yaquelaigualdadesgeneralmentetransitiva. Estilo No hay un límite teórico sobre la cantidad de elementos y operaciones de comparación que utiliza, siempre que tenga la sintaxis adecuada: Lo anterior devuelve True si cada comparación devuelve True . Sin embargo, el uso de encadenamiento enrevesado no es un buen estilo. Un buen encadenamiento será "direccional", no más complicado que a OP b OP c OP d ... # False
    • 231. 166 a > exp and exp > b a = 'short' b = 'short' c = 5 d = 5 a is b # True c is d # True Efectos secundarios Tan pronto como una comparación devuelve False , la expresión se evalúa inmediatamente en False , omitiendo todas las comparaciones restantes. Tenga en cuenta que la expresión exp en a > exp > b seevaluará solo unavez, mientras queen el caso de exp se calculará dos veces si a > exp es verdadero. Comparación por `is` vs` == ` Un error común es confundir a los operadores de comparación de igualdad is y == . a == b compara el valor de a y b . a is b comparará las identidades de a y b . Para ilustrar: Básicamente, is puede considerar como una abreviatura para id(a) == id(b) . Más alláde esto,hay peculiaridades del entornodel tiempo de ejecución que complican aúnmás las cosas. Las cadenas cortas y los enteros pequeños devolverán True cuando se compara con is , debido a que la máquina Python intenta usar menos memoria para objetos idénticos. Pero las cadenas más largas y los enteros más grandes se almacenarán por separado. a = 'Python is fun!' b = 'Python is fun!' a == b # returns True a is b # returns False a = [1, 2, 3, 4, 5] b = a # b references a a == b # True a is b #True b = a[:] # b now references a copy of a a == b # True a is b # False [!!]
    • 232. 167 if myvar is not None: # not None pass if myvar is None: # None pass sentinel = object() def myfunc(var=sentinel): if var is sentinel: # value wasn’t provided pass else: # value was provided pass class Foo(object): def init (self, item): self.my_item = item def eq (self, other): return self.my_item == other.my_item a = Foo(5) b = Foo(5) a == b # True a != b # False a is b # False class Bar(object): def init (self, item): self.other_item = item def eq (self, other): return self.other_item == other.other_item Usted debe usar is para probar para None : Un uso de is es probar un "centinela" (es decir, un objeto único). Comparando objetos Paracompararlaigualdaddeclases personalizadas,puedeanular== y!= ne métodos eq y ne . También puede anular lt ( < ), le ( <= ), gt ( > )y ge ( > ). Tenga en cuentaquesolonecesita anulardos métodos decomparación, yPythonpuede manejarel resto ( == es lo mismo que not < y not > , etc.) Tenga en cuenta que esta comparación simple supone que other (el objeto que se está comparando) es el mismo tipo de objeto. Comparando con otro tipo lanzará un error: a = 'not so short' b = 'not so short' c = 1000 d = 1000 a is b # False c is d # False
    • 233. 168 if("asgdsrf" == 0) { //do stuff } myVariable = "1" if 1 == myVariable: #do stuff Verificar isinstance() o similar ayudará a prevenir esto (si se desea). Common Gotcha: Python no impone la escritura En muchos otros idiomas, si ejecuta lo siguiente (ejemplo de Java) ... obtendrá un error. No puedes ir comparando cadenas con enteros como ese. En Python, esta es una declaración perfectamente legal, solo se resolverá en False . Un gotcha común es el siguiente Esta comparación evaluará a False sin un error, cada vez, ocultando un error o rompiendo un condicional. def ne (self, other): return self.other_item != other.other_item c = Bar(5) a == c # throws AttributeError: 'Foo' object has no attribute 'other_item'
    • 234. 169 class Mixin1(object): def test(self): print "Mixin1" class Mixin2(object): def test(self): print "Mixin2" class MyClass(Mixin1, Mixin2): pass >>> obj = MyClass() >>> obj.test() Mixin1 class MyClass(Mixin2, Mixin1): pass >>> obj = MyClass() Capítulo 31: Complementos y clases de extensión Examples Mixins En el lenguaje de programación orientado a objetos, una mezcla es una clase que contiene métodos para el uso de otras clases sin tener que ser la clase principal de esas otras clases. Cómo esas otras clases obtienen acceso a los métodos de la mezcla depende del idioma. Proporciona un mecanismo para la herencia múltiple al permitir que varias clases usen la funcionalidad común, pero sin la semántica compleja de la herencia múltiple. Los mixins son útiles cuando un programador quiere compartir funcionalidad entre diferentes clases. En lugar de repetir el mismo código una y otra vez, la funcionalidad común puede simplemente agruparse en una mezcla y luego heredarse en cada clase que lo requiera. Cuando usamos más de un mixins, el orden de los mixins es importante. Aquí hay un ejemplo simple: En este ejemplo llamamos MyClass y método de test , El resultado debe ser Mixin1 porque el orden es de izquierda a derecha. Esto podría mostrar resultados inesperados cuando las súper clases lo agreguen. Así que el orden inverso es más bueno así: El resultado será:
    • 235. 170 class Base(object): def test(self): print("Base.") class PluginA(object): def test(self): super().test() print("Plugin A.") class PluginB(object): def test(self): super().test() print("Plugin B.") plugins = PluginA, PluginB class PluginSystemA(PluginA, Base): pass class PluginSystemB(PluginB, Base): pass PluginSystemA().test() # Base. # Plugin A. PluginSystemB().test() # Base. # Plugin B. class Base: plugins = [] def init_subclass (cls, **kwargs): super(). init_subclass (**kwargs) cls.plugins.append(cls) def test(self): print("Base.") class PluginA(Base): Los mixins se pueden utilizar para definir complementos personalizados. Python 3.x 3.0 Plugins con clases personalizadas En Python 3.6, PEP 487 agregó el método especial init_subclass , que simplifica y amplía la personalización de la clase sin usar metaclases . En consecuencia, esta característica permite crear complementos simples . Aquí demostramos esta característica modificando un ejemplo anterior : Python 3.x 3.6 >>> obj.test() Mixin2
    • 236. 171 PluginA().test() # Base. # Plugin A. PluginB().test() # Base. # Plugin B. Base.plugins # [ main .PluginA, main .PluginB] Resultados: def test(self): super().test() print("Plugin A.") class PluginB(Base): def test(self): super().test() print("Plugin B.")
    • 237. 172 import os path = "/home/myFiles/directory1" ## Check if path exists os.access(path, os.F_OK) ## Check if path is Readable os.access(path, os.R_OK) ## Check if path is Wriable os.access(path, os.W_OK) ##Check if path isExecuatble os.access(path, os.E_OK) os.access(path, os.F_OK & os.R_OK & os.W_OK & os.E_OK) Capítulo 32: Comprobando la existencia de ruta y permisos Parámetros Parámetro Detalles os.F_OK Valor para pasar como el parámetro de modo de acceso () para probar la existencia de ruta. os.R_OK Valor para incluir en el parámetro de modo de acceso () para probar la legibilidad de la ruta. os.W_OK Valor para incluir en el parámetro de modo de acceso () para probar la capacidad de escritura de la ruta. os.X_OK Valor que se incluirá en el parámetro de modo de acceso () para determinar si se puede ejecutar la ruta. Examples Realizar comprobaciones utilizando os.access os.access es una solución mucho mejor para verificar si existe un directorio y es accesible para leer y escribir. También es posible realizar todos los controles juntos. Todo lo anterior devuelve True si el acceso está permitido y False si no está permitido. Estos están
    • 238. 173 disponibles en Unix y Windows.
    • 239. 174 import multiprocessing def fib(n): """computing the Fibonacci in an inefficient way was chosen to slow down the CPU.""" if n <= 2: return 1 else: return fib(n-1)+fib(n-2) p = multiprocessing.Pool() print(p.map(fib,[38,37,36,35,34,33])) # Out: [39088169, 24157817, 14930352, 9227465, 5702887, 3524578] import time def main(): print "starting work" time.sleep(1) print "work work work work work" time.sleep(1) print "done working" if name == ' main ': Capítulo 33: Computación paralela Observaciones Debido al GIL (bloqueo de intérprete global), solo una instancia del intérprete de python se ejecuta en un soloproceso.Porlo tanto, engeneral, el usode subprocesos múltiples solo mejora los cálculos de E / S enlazados, no los de CPU. Se recomienda el módulo de multiprocessing si desea paralelizar las tareas relacionadas con la CPU. GIL se aplica a CPython, la implementación más popular de Python, así como a PyPy. Otras implementaciones como Jython y IronPython no tienen GIL . Examples Uso del módulo multiprocesamiento para paralelizar tareas. A medida que la ejecución de cada llamada a fib ocurre en paralelo, el tiempo de ejecución del ejemplo completo es 1.8 × más rápido que si se hiciera de forma secuencial en un procesador dual. Python 2.2+ Usando scripts de Padres e Hijos para ejecutar código en paralelo niño.py
    • 240. 175 import os def main(): for i in range(5): os.system("pythonchild.py&") if name == ' main ': main() #include "Python.h" ... PyObject *pyfunc(PyObject *self, PyObject *args) { ... Py_BEGIN_ALLOW_THREADS // Threaded C code ... Py_END_ALLOW_THREADS ... } import pypar as pp ncpus = pp.size() rank = pp.rank() node = pp.get_processor_name() print 'I am rank %d of %d on node %s' % (rank, ncpus, node) if rank == 0: msh = 'P0' pp.send(msg, destination=1) msg = pp.receive(source=rank-1) print 'Processor 0 received message "%s" from rank %d' % (msg, rank-1) parent.py Esto es útil para tareas de solicitud / respuesta HTTP independientes o para selección / inserción de base de datos. Los argumentos de la línea de comando también se pueden dar al script child.py . La sincronización entre scripts se puede lograr si todos los scripts revisan regularmente un servidor separado (como una instancia de Redis). Usando una extensión C para paralelizar tareas La idea aquí es mover los trabajos intensivos en computación a C (usando macros especiales), independientemente de Python, y hacer que el código C libere el GIL mientras está funcionando. Usando el módulo PyPar para paralelizar PyPar es una biblioteca que utiliza la interfaz de paso de mensajes (MPI) para proporcionar paralelismo en Python. Un ejemplo simple en PyPar (como se ve en https://github.com/daleroberts/pypar) se ve así: main()
    • 241. 176 else: source = rank-1 destination = (rank+1) % ncpus msg = pp.receive(source) msg = msg + 'P' + str(rank) pypar.send(msg, destination) pp.finalize()
    • 242. 177 import serial #Serial takes these two parameters: serial device and baudrate ser = serial.Serial('/dev/ttyUSB0', 9600) import serial #Serial takes two parameters: serial device and baudrate ser = serial.Serial('/dev/ttyUSB0', 9600) Capítulo 34: Comunicación Serial Python (pyserial) Sintaxis • ser.read (tamaño = 1) • ser.readline () • ser.write () Parámetros parámetro detalles Puerto Nombre del dispositivo, por ejemplo, / dev / ttyUSB0 en GNU / Linux o COM3 en Windows. velocidad de transmisión tipo de baudios: int por defecto: 9600 valores estándar: 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200 Observaciones Para más detalles echa un vistazo a la documentación de pyserial. Examples Inicializar dispositivo serie Leer del puerto serial Inicializar dispositivo serie para leer un solo byte desde el dispositivo serie
    • 243. 178 data = ser.read(size=5) data = ser.readline() #for python2.7 data = ser.read(ser.inWaiting()) #for python3 ser.read(ser.inWaiting) python -m serial.tools.list_ports from serial.tools import list_ports list_ports.comports() # Outputs list of available serial ports para leer el número dado de bytes del dispositivo serie para leer una línea desde el dispositivo serie. para leer los datos del dispositivo serie mientras se escribe algo sobre él. Compruebe qué puertos serie están disponibles en su máquina Para obtener una lista de los puertos serie disponibles use en un símbolo del sistema o de la cáscara de Python. data = ser.read()
    • 244. 179 from future import print_function import threading def counter(count): while count > 0: print("Count value", count) count -= 1 return t1 = threading.Thread(target=countdown,args=(10,)) t1.start() t2 =threading.Thread(target=countdown,args=(20,)) t2.start() from future import print_function import multiprocessing def countdown(count): while count > 0: print("Count value", count) count -= 1 return if name == " main ": p1 = multiprocessing.Process(target=countdown, args=(10,)) p1.start() p2 = multiprocessing.Process(target=countdown, args=(20,)) p2.start() Capítulo 35: Concurrencia de Python Observaciones Los desarrolladores de Python se aseguraron de que la API entre threading y multiprocessing sea similar, de modo que el cambio entre las dos variantes sea más fácil para los programadores. Examples El módulo de enhebrado. En ciertas implementaciones de Python como CPython, cierto paralelismo no se consigue utilizando hilos porque de la utilización de lo que se conoce como el GIL, o G lobal I nterpreter L ock. Aquí hay una excelente descripción de la concurrencia de Python: Concordancia Python por David Beazley (YouTube) El módulo multiprocesamiento.
    • 245. 180 Aquí, cada función se ejecuta en un nuevo proceso. Dado que una nueva instancia de Python VM ejecuta el código, no hay GIL y se ejecuta el paralelismo en varios núcleos. El método Process.start inicia este nuevo proceso y ejecuta la función pasada en el argumento de target con los argumentos args . El método Process.join espera el final de la ejecución de los procesos p1 y p2. Los nuevos procesos se inician de manera diferente según la versión de python y la plataforma en la que se ejecuta el código, por ejemplo : • Windows usa spawn para crear el nuevo proceso. • Con los sistemas y versiones de Unix anteriores a 3.3, los procesos se crean utilizando un fork . Tenga en cuenta que este método no respeta el uso POSIX de la bifurcación y, por lo tanto, conduce a comportamientos inesperados, especialmente al interactuar con otras bibliotecas de multiprocesamiento. • Conel sistemaUnixylaversión3.4+, puedeelegiriniciarlosnuevos procesoscon fork, forkserver o spawn utilizando multiprocessing.set_start_method al comienzo de su programa. forkserver métodos forkserver y spawn son más lentos que los forking, pero evitan algunos comportamientos inesperados. Uso de la horquilla POSIX : Después de una bifurcación en un programa multiproceso, el niño solo puede llamar de forma segura a funciones async-signal-safe hasta el momento en que lo llame execve. ( ver ) Usando fork, se iniciará un nuevo proceso con el mismo estado exacto para todo el mutex actual, pero solo se MainThread . Esto no es seguro ya que podría conducir a condiciones de carrera, por ejemplo : • Si utiliza un Lock en MainThread y lo pasa a otro hilo que se supone que debe bloquearlo en algún momento. Si la fork ocurre simultáneamente, el nuevo proceso comenzará con un bloqueo bloqueado que nunca se liberará ya que el segundo hilo no existe en este nuevo proceso. En realidad, este tipo de comportamiento no debería ocurrir en Python puro, ya que el multiprocessing maneja correctamente, pero si está interactuando con otra biblioteca, puede ocurrireste tipodecomportamiento,loquepuedeprovocarun falloensu sistema(por ejemplo, con numpy / acelerado en macOS) Transferencia de datos entre procesos de multiprocesamiento. Debido a que los datos son confidenciales cuando se manejan entre dos subprocesos (piense que la lectura concurrente y la escritura concurrente pueden entrar en conflicto entre sí, causando p1.join() p2.join()
    • 246. 181 import multiprocessing import queue my_Queue=multiprocessing.Queue() #Creates a queue with an undefined maximum size #this can be dangerous as the queue becomes increasingly large #it will take a long time to copy data to/from each read/write thread import multiprocessing import queue '''Import necessary Python standard libraries, multiprocessing for classes and queue for the queue exceptions it provides''' defQueue_Iftry_Get(get_queue,default=None, use_default=False,func=None,use_func=False): '''This global method for the Iftry block is provided for it's reuse and standard functionality, the if also saves on performance as opposed to catching the exception, which is expencive. It also allows the user to specify a function for the outgoing data to use, and a default value to return if the function cannot return the value from the queue''' if get_queue.empty(): if use_default: return default else: try: value = get_queue.get_nowait() except queue.Empty: if use_default: return default else: if use_func: return func(value) else: return value def Queue_Iftry_Put(put_queue, value): '''This global method for the Iftry block is provided because of its reuse and standard functionality, the If also saves on performance as opposed to catching the exception, which is expensive. ReturnTrue ifplacing value inthequeuewassuccessful.Otherwise,false''' if put_queue.full(): return False else: try: put_queue.put_nowait(value) except queue.Full: return False else: return True condiciones de carrera), se creó un conjunto de objetos únicos para facilitar la transferencia de datos entre los subprocesos. Cualquier operación verdaderamente atómica puede usarse entre subprocesos, pero siempre es seguro mantener la cola. La mayoría de las personas sugerirán que al usarla cola, siempre coloque los datos de lacolaen unintento: excepto:bloque enlugar de usar vacío.Sin embargo, para las aplicaciones en lasque no importa siomiteun ciclo deexploración (los datos se puedencolocar en la cola mientras se queue.Empty==True estados de la queue.Empty==True a la queue.Empty==False ) por lo general es mejor colocarla lectura y acceso de escritura en lo queyo llamo unbloque Iftry,porque una declaración 'if' es técnicamente más eficaz que atrapar laexcepción.
    • 247. 182
    • 248. 183 number = 5 if number > 2: print("Number is bigger than 2.") elif number < 2: # Optional clause (you can have multiple elifs) print("Number is smaller than 2.") else: # Optional clause (you can only have one else) print("Number is 2.") n = 5 Capítulo 36: Condicionales Introducción Las expresiones condicionales, que incluyen palabras clave como if, elif y else, proporcionan a los programas de Python la capacidad de realizar diferentes acciones dependiendo de una condición booleana: Verdadero o Falso. Esta sección cubre el uso de condicionales de Python, lógica booleana y sentencias ternarias. Sintaxis • <expression> if <conditional> else <expression> # Operador ternario Examples si, elif, y si no EnPythonpuedesdefinirunaseriedecondicionalesusandoifparaelprimero,elifparaelresto, hasta el final (opcional) else para cualquier cosa que no sea capturada por los otros condicionales. El Number is bigger than 2 salidas Number is bigger than 2 El uso de else if lugar de elif activará un error de sintaxis y no está permitido. Expresión condicional (o "El operador ternario") El operador ternario se utiliza para expresiones condicionales en línea. Se utiliza mejor en operaciones simples y concisas que se leen fácilmente. • El orden de los argumentos es diferente de muchos otros lenguajes (como C, Ruby, Java, etc.), lo que puede provocar errores cuando las personas que no están familiarizadas con el comportamiento "sorprendente" de Python lo usan (pueden invertir el orden). • Algunos lo consideran "poco manejable", ya que va en contra del flujo normal de pensamiento (pensando primero en la condición y luego en los efectos).
    • 249. 184 n = 5 "Hello" if n > 10 else "Goodbye" if n > 5 else "Good day" if condition: body if True: print "It is true!" >> It is true! if False: print "This won't get printed.." if 2 + 2 == 4: print "I know math!" >> I know math! if condition: body else: body if True: print "It is true!" else: print "This won't get printed.." El resultado de esta expresión será tal como se lee en inglés; si la expresión condicional es Verdadero, se evaluará la expresión en el lado izquierdo, de lo contrario, el lado derecho. Las operaciones de tenencia también se pueden anidar, como aquí: También proporcionan un método para incluir condicionales en las funciones lambda . Si declaración Lasdeclaracionesifcompruebanlacondición.Siseevalúacomo True ,ejecutaelcuerpodela sentencia if . Si se evalúa como False , se salta el cuerpo. La condición puede ser cualquier expresión válida: Otra declaración La sentencia else ejecutará su cuerpo solo si las sentencias condicionales anteriores se evalúan como Falso. "Greater than 2" if n > 2 else "Smaller than or equal to 2" # Out: 'Greater than 2'
    • 250. 185 "Hello World" >>> "" and "Pancakes" "" Expresiones lógicas booleanas Las expresiones lógicas booleanas, además de evaluar a True o False , devuelven el valor que se interpretó como True o False . Es una forma en Pythonic de representar la lógica que, de lo contrario, podría requerir una prueba if-else. Y operador El operador and evalúa todas las expresiones y devuelve la última expresión si todas las expresiones se evalúan como True . De lo contrario, devuelve el primer valor que se evalúa como False : >>> 2 1 and 2 >>> 0 1 and 0 >>> 1 and "Hello World" O operador El operador or evalúa las expresiones de izquierda a derecha y devuelve el primer valor que se evalúa como True o el último valor (si ninguno es True ). >>> 1 1 or 2 >>> 1 None or 1 >>> [] 0 or [] # Output: It is true! if False: print "This won't get printed.." else: print "It is false!" # Output: It is false!
    • 251. 186 >>> def print_me(): print('I am here!') >>> 0 and print_me() 0 >>> a = 1 >>> b = 6 >>> if a and b > 2: ... print('yes') ... else: ... print('no') yes >>> if a > 2 and b > 2: ... print('yes') ... else: ... print('no') no >>> a = 1 >>> if a == 3 or 4 or 6: ... print('yes') ... else: Evaluación perezosa Cuando utilice este enfoque, recuerde que la evaluación es perezosa. Las expresiones que no requieren evaluación para determinar el resultado no se evalúan. Por ejemplo: En el ejemplo anterior, print_me nunca se ejecuta porque Python puede determinar que la expresión completa es False cuando encuentra el 0 ( False ). Tenga esto en cuenta si print_me necesita ejecutarse para servir la lógica de su programa. Pruebas para condiciones múltiples Un error común al verificar múltiples condiciones es aplicar la lógica de manera incorrecta. Esteejemplo está tratandodeverificar si dos variables son cada una mayorque2.La declaración se evalúa como - if (a) and (b > 2) . Esto produce un resultado inesperado porque bool(a) evalúa como True cuando a no es cero. Cada variable debe compararse por separado. Otro error similar secomete al verificar si una variable es uno de varios valores. La declaraciónen este ejemplo se evalúa como -if (a == 3) or (4) or (6) .Esto produce unresultado inesperado porque bool(4) y bool(6) evalúan como True
    • 252. 187 >>> if a == 3 or a == 4 or a == 6: ... print('yes') ... else: ... print('no') no >>> if a in (3, 4, 6): ... print('yes') ... else: ... print('no') no Nuevamente cada comparación debe hacerse por separado Usar el operador in es la forma canónica de escribir esto. Valores de verdad Los siguientes valores se consideran falsey, ya que se evalúan como False cuando se aplican a un operador booleano. • Ninguna • Falso • 0 , o cualquier valor numérico equivalente a cero, por ejemplo 0L , 0.0 , 0j • Secuencias vacías: '', "" , () , [] • Asignaciones vacías: {} • Tipos definidos por el usuario dondelos métodos bool o len devuelven 0 o False Todos los demás valores en Python se evalúan como True . Nota:UnerrorcomúnessimplementeverificarlaFalsedaddeunaoperaciónquedevuelve diferentes valoresdeFalseydondeladiferenciaesimportante.Porejemplo,usarif foo()lugar de más explícito if foo() is None Usando la función cmp para obtener el resultado de comparación de dos objetos Python 2 incluye una función cmp que le permite determinar si un objeto es menor, igual o mayor que otro objeto. Esta función se puede usar para elegir una opción de una lista basada en una de esas tres opciones. Supongamos que necesita imprimir 'greater than' si x > y , 'less than' si x < y e 'equal' si x == y yes ... print('no')
    • 253. 188 ['equal', 'greater than', 'less than', ][cmp(x,y)] # x,y = 1,1 output: 'equal' # x,y = 1,2 output: 'less than' # x,y = 2,1 output: 'greater than' >> n = 16 >> print [10, 20][n <= 15] 10 [10, 20][n <= 15] ==> [10, 20][False] ==> [10, 20][0] #False==0, True==1 (Check Boolean Equivalencies in Python) ==> 10 . cmp(x,y) devuelve los siguientes valores Comparación Resultado x <y -1 x == y 0 x> y 1 Esta función se elimina en Python 3. Puede usar la cmp_to_key(func) ayuda cmp_to_key(func) ubicada en functools en Python 3 para convertir las funciones de comparación antiguas en funciones clave. Evaluación de expresiones condicionales usando listas de comprensión Python te permite hackear las comprensiones de la lista para evaluar expresiones condicionales. Por ejemplo, Ejemplo: Aquí n<=15 devuelve False (que equivale a 0 en Python). Entonces, lo que Python está evaluando es: Python 2.x 2.7 El método cmp incorporado devolvió 3 valores posibles: 0, 1, -1, donde cmp (x, y) devolvió 0: si los dos objetos eran iguales 1: x> y -1: x <y Esto podría usarse con la lista de comprensión para devolver el primer elemento (es decir, índice [value_false, value_true][<conditional-test>]
    • 254. 189 [value_equals, value_greater, value_less][<conditional-test>] [lambda: value_false, lambda: value_true][<test>]() count = [lambda:0, lambda:N+1][count==N]() if aDate is None: aDate=datetime.date.today() if not aDate: aDate=datetime.date.today() aDate=aDate or datetime.date.today() 0) , segundo (es decir, índice 1) y último (es decir, índice -1) de la lista. Dándonos uncondicional de este tipo: Finalmente, en todos los ejemplos anteriores, Python evalúa ambas ramas antes de elegir una. Para evaluar solo la rama elegida: donde agregar el () al final asegura que las funciones lambda solo se llamen / evalúen al final. Así, solo evaluamos la rama elegida. Ejemplo: Probar si un objeto es Ninguno y asignarlo A menudo querrá asignar algo a un objeto si es None , lo que indica que no se ha asignado. Usaremos una aDate . La forma más sencilla de hacer esto es usar la prueba is None . (Tenga en cuenta que es más Pythonic decir is None lugar de == None ). Pero esto puede optimizarse ligeramente explotando la noción de que not None se evaluará como True en una expresión booleana. El siguiente código es equivalente: Pero hay una forma más pitónica. El siguiente código también es equivalente: Estohaceunaevaluacióndecortocircuito.Si aDateseinicializaynot Noneesnot None,entonces seasignaasímismosinefectoneto.Siis None ,entoncesdatetime.date.today()seasignaauna aDate .
    • 255. 190 import pymssql SERVER = "servername" USER = "username" PASSWORD = "password" DATABASE = "dbname" connection = pymssql.connect(server=SERVER, user=USER, password=PASSWORD, database=DATABASE) cursor = connection.cursor() # to access field as dictionary use cursor(as_dict=True) cursor.execute("SELECT TOP 1 * FROM TableName") row = cursor.fetchone() ######## CREATE TABLE ######## cursor.execute(""" CREATETABLEposts( post_id INT PRIMARY KEY NOT NULL, message TEXT, publish_date DATETIME ) """) ######## INSERT DATA IN TABLE ######## cursor.execute(""" INSERT INTO posts VALUES(1, "Hey There", "11.23.2016") """) # commit your work to database connection.commit() ######## ITERATE THROUGH RESULTS ######## cursor.execute("SELECT TOP 10 * FROM posts ORDER BY publish_date DESC") for row in cursor: print("Message: " + row[1] + " | " + "Date: " + row[2]) # if you pass as_dict=True to cursor # print(row["message"]) connection.close() Capítulo 37: Conectando Python a SQL Server Examples Conectar al servidor, crear tabla, consultar datos Instala el paquete: $ pip install pymssql Puede hacer cualquier cosa si su trabajo está relacionado con expresiones SQL, simplemente pase estas expresiones al método de ejecución (operaciones CRUD).
    • 256. 191 Para la declaración, el procedimiento almacenado de llamada, el manejo de errores o más control de ejemplo: pymssql.org
    • 257. 192 from paramiko import client ssh = client.SSHClient() # create a new SSHClient object ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #auto-accept unknown host keys ssh.connect(hostname, username=username, port=port, password=password) #connect with a host stdin, stdout, stderr = ssh.exec_command(command) # submit a command to ssh print stdout.channel.recv_exit_status() #tells the status 1 - job failed Capítulo 38: Conexión segura de shell en Python Parámetros Parámetro Uso nombre de host Este parámetro le indica al host al que se debe establecer la conexión. nombre de usuario nombre de usuario requerido para acceder al host Puerto Puerto host contraseña contraseña para la cuenta Examples conexión ssh
    • 258. 193 [DEFAULT] debug = True name = Test password = password [FILES] path = /path/to/file from ConfigParser import ConfigParser config = ConfigParser() #Load configuration file config.read("config.ini") # Access the key "debug" in "DEFAULT" section config.get("DEFAULT", "debug") # Return 'True' # Access the key "path" in "FILES" destion config.get("FILES", "path") # Return '/path/to/file' Capítulo 39: configparser Introducción Este módulo proporciona la clase ConfigParser que implementa un lenguaje de configuración básico en archivos INI. Puede usar esto para escribir programas Python que los usuarios finales pueden personalizar fácilmente. Sintaxis • Cada nueva línea contiene un nuevo par de valores clave separados por el signo = • Las teclas se pueden separar en secciones • En el archivo INI, cada título de la sección se escribe entre paréntesis: [] Observaciones Todos los valores de retorno de ConfigParser.ConfigParser().get son cadenas. Se puede convertir a tipos más comunes gracias a eval Examples Uso básico En config.ini: En Python:
    • 259. 194 import configparser config = configparser.ConfigParser() config['settings']={'resolution':'320x240', 'color':'blue'} with open('example.ini', 'w') as configfile: config.write(configfile) [settings] resolution = 320x240 color = blue settings=config['settings'] settings['color']='red' Creando programáticamente el archivo de configuración. El archivo de configuración contiene secciones, cada sección contiene claves y valores. El módulo configparser se puede usar para leer y escribir archivos de configuración. Creando el archivo de configuración: - El archivo de salida contiene la siguiente estructura Si desea cambiar un campo en particular, obtenga el campo y asigne el valor
    • 260. 195 restaurants = ["McDonald's", "Burger King", "McDonald's", "Chicken Chicken"] unique_restaurants = set(restaurants) print(unique_restaurants) # prints {'Chicken Chicken', "McDonald's", 'Burger King'} Capítulo 40: Conjunto Sintaxis • empty_set = set () # inicializa un conjunto vacío • literal_set = {'foo', 'bar', 'baz'} # construye un conjunto con 3 cadenas dentro de él • set_from_list = set (['foo', 'bar', 'baz']) # llama a la función set para un nuevo conjunto • set_from_iter = set (x para x en el rango (30)) # usa iterables arbitrarios para crear un conjunto • set_from_iter = {x para x en [random.randint (0,10) para i en rango (10)]} # notación alternativa Observaciones Los conjuntos no están ordenados y tienen un tiempo de búsqueda muy rápido (amortizado O (1) si desea obtener asistencia técnica). Es genial usarlo cuando tienes una colección de cosas, el orden no importa, y buscarás muchos artículos por nombre. Si tiene más sentido buscar elementos por un número de índice, considere usar una lista en su lugar. Si el orden importa, considera una lista también. Los conjuntos son mutables y, por lo tanto, no se pueden hashear, por lo que no puede usarlos como claves de diccionario o colocarlos en otros conjuntos o en cualquier otro lugar que requiera tipos de hashable. En tales casos, puede utilizar un frozenset inmutable. Loselementos de unconjunto deben ser hashable .Esto significaque tienen un método correcto de hash ,que es consistente con eq .Engeneral,lostipos mutables, comolalistoelset, nosonhashablesynosepuedencolocar enunconjunto.Siseencuentraconesteproblema, considere usar claves dict yinmutables. Examples Consigue los elementos únicos de una lista. Digamos que tienes una lista de restaurantes, tal vez la lees de un archivo. Te preocupas por los restaurantes únicos en la lista. La mejor manera de obtener los elementos únicos de una lista es convertirlos en un conjunto: Tenga en cuenta que el conjunto no está en el mismo orden que la lista original; eso es porque los conjuntos no están ordenados , al igual que dict s.
    • 261. 196 # Intersection {1, 2, 3, 4, 5}.intersection({3, 4, 5, 6}) # {3, 4, 5} {1, 2, 3, 4, 5} & {3, 4, 5, 6} # {3, 4, 5} # Union {1, 2, 3, 4, 5}.union({3, 4, 5, 6}) {1, 2, 3, 4,5} | {3, 4, 5, 6} # {1, 2, 3, 4, 5, 6} # {1, 2, 3, 4, 5, 6} # Difference {1, 2, 3, 4}.difference({2, 3, 5}) # {1, 4} {1, 2, 3, 4} - {2, 3, 5} # {1, 4} # Symmetric difference with {1, 2, 3, 4}.symmetric_difference({2, 3, 5}) # {1, 4, 5} {1, 2, 3, 4} ^ {2, 3, 5} # {1, 4, 5} # Superset check {1, 2}.issuperset({1, 2, 3}) # False {1, 2} >= {1, 2, 3} # False # Subset check {1, 2}.issubset({1, 2, 3}) # True {1, 2} <= {1, 2, 3} # True list(unique_restaurants) # ['Chicken Chicken', "McDonald's", 'Burger King'] # Removes all duplicates and returns another list list(set(restaurants)) # Existence check 2 in {1,2,3} # True 4 in {1,2,3} # False 4 not in {1,2,3} # True # Add and Remove s = {1,2,3} s.add(4) # s == {1,2,3,4} Estosepuede volver atransformarfácilmenteenuna List conla función de list incorporada de Python, dando otra lista que es la misma que la original pero sin duplicados: También es común ver esto como una sola línea: Ahora, cualquier operación que se pueda realizar en la lista original se puede hacer de nuevo. Operaciones en sets con otros sets # Disjoint check {1, 2}.isdisjoint({3, 4}) # True {1, 2}.isdisjoint({1, 4}) # False con elementos individuales
    • 262. 197 s = {1, 2} s.update({3, 4}) # s == {1, 2, 3, 4} >>> setA = {'a','b','b','c'} >>> setA set(['a', 'c', 'b']) >>> listA = ['a','b','b','c'] >>> listA ['a', 'b', 'b', 'c'] Las operaciones de configuración devuelven conjuntos nuevos, pero tienen las versiones locales correspondientes: método operación en el lugar método en el lugar Unión s | = t actualizar intersección s & = t intersection_update diferencia s - = t diferencia_update diferencia de simetría s ^ = t symmetric_difference_update Por ejemplo: Conjuntos versus multisets Los conjuntos son colecciones desordenadas de elementos distintos. Pero a veces queremos trabajar con colecciones desordenadas de elementos que no son necesariamente distintos y hacer un seguimiento de las multiplicidades de los elementos. Considera este ejemplo: Alguardarlascadenas'a','b','b','c'enunaestructuradedatosestablecida,hemosperdido lainformaciónsobreelhechodeque'b'ocurredosveces.Porsupuesto,guardarloselementos en una lista conservaría esta información pero una lista de estructura de datos introduce un orden adicional innecesario que ralentizará nuestros cálculos. Para implementar multisets, Python proporciona la clase Counter desde el módulo de collections # s == {1,4} # KeyError! s.remove(2) s.remove(2) # s == {1,2,4} # s == {1,2,4} s.discard(3) s.discard(5)
    • 263. 198 >>> from collections import Counter >>> counterA = Counter(['a','b','b','c']) >>> counterA Counter({'b': 2, 'a': 1, 'c': 1}) >>> a = {1, 2, 2, 3, 4} >>> b = {3, 3, 4, 4, 5} >>> a.intersection(b) {3, 4} >>> a.union(b) {1, 2, 3, 4, 5} >>> a.difference(b) {1, 2} >>> b.difference(a) {5} (a partir de la versión 2.7): Python 2.x 2.7 Counter es un diccionario donde los elementos se almacenan como claves de diccionario y sus conteos se almacenan como valores de diccionario. Y como todos los diccionarios, es una colección desordenada. Establecer operaciones usando métodos e incorporaciones Definimos dos conjuntos a y b NOTA: {1} crea un conjunto de un elemento, pero {} crea un dict vacío. La forma correcta de crear un conjunto vacío es set(). Intersección a.intersection(b) devuelve un nuevo conjunto con elementos presentes tanto en a como en b Unión a.union(b) devuelve un nuevo conjunto con elementos presentes en a y b Diferencia a.difference(b) devuelve un nuevo conjunto con elementos presentes en a pero no en b
    • 264. 199 >>> a.symmetric_difference(b) {1, 2, 5} >>> b.symmetric_difference(a) {1, 2, 5} >>> c = {1, 2} >>> c.issubset(a) True >>> a.issuperset(c) True >>> d = {5, 6} >>> a.isdisjoint(b) # {2, 3, 4} are in both sets False Diferencia simétrica a.symmetric_difference(b) devuelve un nuevo conjunto con elementos presentes en ya sea a o b pero no en ambas NOTA : a.symmetric_difference(b) == b.symmetric_difference(a) Subconjunto y superconjunto c.issubset(a) comprueba si cada elemento de c está en a . a.issuperset(c) comprueba si cada elemento de c está en a . Las últimas operaciones tienen operadores equivalentes como se muestra a continuación: Método Operador a.intersection(b) a & b a.union(b) a | b a.difference(b) a - b a.symmetric_difference(b) a ^ b a.issubset(b) a <= b a.issuperset(b) a >= b Conjuntos desunidos Los conjuntos a y d son disjuntos si ningún elemento en a también está en d y viceversa.
    • 265. 200 >>> 1 in a True >>> 6 in a False >>>len(a) 4 >>> len(b) 3 {{1,2}, {3,4}} TypeError: unhashable type: 'set' {frozenset({1, 2}), frozenset({3, 4})} Membresía de prueba El incorporado in palabra clave busca ocurrencias Longitud La función len() incorporada devuelve el número de elementos en el conjunto Conjunto de conjuntos lleva a: En su lugar, utilice frozenset : >>> a.isdisjoint(d) True # This is an equivalent check, but less efficient >>> len(a & d) == 0 True # This is even less efficient >>> a & d == set() True
    • 266. 201 from collections import Counter c = Counter(["a", "b", "c", "d", "a", "b", "a", "c", "d"]) c # Out: Counter({'a': 3, 'b': 2, 'c': 2, 'd': 2}) c["a"] # Out: 3 c[7] # not in the list (7 occurred 0 times!) # Out: 0 Counter({"e": 2}) # Out: Counter({"e": 2}) Counter({"e": "e"}) # warning Counter does not verify the values are int # Out: Counter({"e": "e"}) from collections import Counter adict = {'a': 5, 'b': 3, 'c': 5, 'd': 2, 'e':2, 'q': 5} Counter(adict.values()) # Out: Counter({2: 2, 3: 1, 5: 3}) # Sorting them from most-common to least-common value: Counter(adict.values()).most_common() # Out: [(5, 3), (2, 2), (3, 1)] # Getting the most common value Counter(adict.values()).most_common(1) # Out: [(5, 3)] Capítulo 41: Contando Examples Contando todas las apariciones de todos los elementos en un iterable: colecciones.Contador Lascollections.Counter sepuedeutilizar paracualquier iterable ycuentacada aparición para cada elemento. Nota : una excepción es si se otorga un dict u otra collections.Mapping crear una clase similar a la de un dict , no se contabilizarán, sino que creará un contador con estos valores: Obtención del valor más común (-s): collections.Counter.most_common () No es posible contar las claves de un Mapping con collections.Counter Contador, pero podemos contar los valores : Los elementos más comunes están disponibles por el método most_common :
    • 267. 202 alist = [1, 2, 3, 4, 1, 2, 1, 3, 4] alist.count(1) # Out: 3 atuple = ('bear', 'weasel', 'bear', 'frog') atuple.count('bear') # Out: 2 atuple.count('fox') # Out: 0 astring = 'thisisashorttext' astring.count('t') # Out: 4 astring.count('th') # Out: 1 astring.count('is') # Out: 2 astring.count('text') # Out: 1 from collections import Counter Counter(astring) # Out: Counter({'a': 1, 'e': 1, 'h': 2, 'i': 2, 'o': 1, 'r': 1, 's': 3, 't': 4, 'x': 1}) >>> import numpy as np >>> a=np.array([0,3,4,3,5,4,7]) >>> print np.sum(a==3) 2 Contando las ocurrencias de un elemento en una secuencia: list.count () y tuple.count () Contando las ocurrencias de una subcadena en una cadena: str.count () Esto funciona incluso para subcadenas de más de un carácter: lo que no sería posible con collections.Counter que solo cuenta con caracteres individuales: Contando ocurrencias en matriz numpy Para contar las ocurrencias de un valor en una matriz numpy. Esto funcionará: La lógica es que la declaración booleana produce una matriz donde todas las apariciones de los valores solicitados son 1 y todas las demás son cero. Así que sumando estos da el número de ocurrencias. Esto funciona para matrices de cualquier forma o tipo de dtype. # Getting the two most common values Counter(adict.values()).most_common(2) # Out: [(5, 3), (2, 2)]
    • 268. 203 >>> unique,counts=np.unique(a,return_counts=True) >>> print unique,counts # counts[i] is equal to occurrences of unique[i] in a [0 3 4 5 7] [1 2 2 1 1] >>> bin_count=np.bincount(a) >>> print bin_count # bin_count[i] is equal to occurrences of i in a [1 0 0 2 2 1 0 1] Hay dos métodos que utilizo para contar las ocurrencias de todos los valores únicos en numpy. Único y bincount. Unique automáticamente aplana las matrices multidimensionales, mientras que bincount solo funciona con matrices 1d que solo contienen enteros positivos. Si sus datos son matrices numpy, generalmente es mucho más rápido usar métodos numpy que convertir sus datos a métodos genéricos.
    • 269. 204 >>> import copy >>> c = [[1,2]] >>> d = copy.copy(c) >>> c isd False >>> c[0] is d[0] True >>> import copy >>> c = [[1,2]] >>> d = copy.deepcopy(c) >>> c isd False >>> c[0] is d[0] False # Perform the shallow copy. >>> l1 = [1,2,3] >>> l2 = l1[:] >>> l2 [1,2,3] >>> l1 is l2 False >>> d1 = {1:[]} >>> d2 = d1.copy() >>> d1 is d2 False >>> d1[1] is d2[1] Capítulo 42: Copiando datos Examples Realizando una copia superficial Una copia superficial es una copia de una colección sin realizar una copia de sus elementos. Realizando una copia profunda Si tiene listas anidadas, también es deseable clonar las listas anidadas. Esta acción se llama copia profunda. Realizando una copia superficial de una lista Puedes crear copias superficiales de listas usando cortes. Copiar un diccionario Un objeto de diccionario tiene el método de copy . Realiza una copia superficial del diccionario.
    • 270. 205 >>> s1 = {()} >>> s2 = s1.copy() >>> s1 is s2 False >>> s2.add(3) >>> s1 {[]} >>> s2 {3,[]} Copiar un conjunto Los conjuntos también tienen un método de copy . Puede utilizar este método para realizar una copia superficial. True
    • 271. 206 a[-1] # last item in the array a[-2:] # last two items in the array a[:-2] # everything except the last twoitems lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] lst[::2] # Output: ['a', 'c', 'e', 'g'] lst[::3] # Output: ['a', 'd', 'g'] lst = ['a', 'b', 'c', 'd', 'e'] lst[2:4] # Output: ['c', 'd'] lst[2:] # Output: ['c', 'd', 'e'] Capítulo 43: Corte de listas (selección de partes de listas) Sintaxis • a [inicio: final] # los elementos comienzan hasta el final-1 • a [inicio:] # los elementos comienzan en el resto de la matriz • a [: fin] # elementos desde el principio hasta el final-1 • a [inicio: final: paso] # comienzo a través de no pasado, paso a paso • a [:] # una copia de toda la matriz • fuente Observaciones • lst[::-1] le da una copia invertida de la lista • start o el end puede ser un número negativo, lo que significa que cuenta desde el final de la matriz en lugar del principio. Asi que: ( fuente ) Examples Usando el tercer argumento del "paso" Seleccionando una lista secundaria de una lista
    • 272. 207 a = [1, 2, 3, 4, 5] # steps through the list backwards (step=-1) b = a[::-1] # built-in list method to reverse 'a' a.reverse() if a = b: print(True) print(b) # Output: # True # [5, 4, 3, 2, 1] def shift_list(array, s): """Shifts the elements of a list to the left or right. Args: array - the list to shift s - the amount to shift the list ('+': right-shift, '-': left-shift) Returns: shifted_array - the shifted list """ # calculate actual shift amount (e.g., 11 --> 1 if length of the array is 5) s %= len(array) # reverse the shift direction to be more intuitive s *= -1 # shift array with list slicing shifted_array = array[s:] + array[:s] return shifted_array my_array = [1, 2, 3, 4, 5] # negative numbers shift_list(my_array, -7) >>> [3, 4, 5, 1, 2] # no shift on numbers equal to the size of the array shift_list(my_array, 5) >>> [1, 2, 3, 4, 5] # works on positive numbers shift_list(my_array, 3) Invertir una lista con rebanar Desplazando una lista usando rebanar lst[:4] # Output: ['a', 'b', 'c', 'd']
    • 273. 208 >>> [3, 4, 5, 1, 2]
    • 274. 209 $ virtualenv .virtualenv ... $ source .virtualenv/bin/activate $ python setup.py install running install ... Installed .../package_name-0.1 .........egg Capítulo 44: Creando paquetes de Python Observaciones El proyecto de ejemplo pypa contiene una plantilla setup.py fácilmente modificable y completa que demuestra una amplia gama de capacidades que las herramientas de configuración pueden ofrecer. Examples Introducción Cada paquete requiere un archivo setup.py que describe el paquete. Considere la siguiente estructura de directorio para un paquete simple: El init .py contiene solo la línea def foo(): return 100 . El siguiente setup.py definirá el paquete: from setuptools import setup setup( name='package_name', version='0.1', description='Package Description', url='http://example.com', install_requires=[], packages=['package_name'], ) # package name # version # short description # package URL # list of packages this package depends # on. # List of module names that installing # this package will provide. virtualenv es ideal para probar las instalaciones de paquetes sin modificar sus otros entornos de Python: +-- package_name | | | +-- init .py | +-- setup.py
    • 275. 210 # .pypirc file [distutils] index-servers = pypi pypitest [pypi] repository=https://pypi.python.org/pypi username=your_username password=your_password [pypitest] repository=https://testpypi.python.org/pypi username=your_username password=your_password $ pip install twine $ python setup.py register -r pypitest Subiendo a PyPI Una vez que su setup.py sea completamente funcional (vea Introducción ), es muy fácil cargar su paquete a PyPI . Configurar un archivo .pypirc Este archivo almacena inicios de sesión y contraseñas para autenticar sus cuentas. Normalmente se almacena en su directorio personal. Es más seguro usar twine para cargar paquetes, así que asegúrese de que esté instalado. Registrarse y subir a testpypi (opcional) Nota : PyPI no permite sobrescribir paquetes cargados , por lo que es prudente probar primero su implementación en un servidor de prueba dedicado, por ejemplo, testpypi. Esta opción será discutida. Considere un esquema de control de versiones para su paquete antes de cargar, como el control de versiones del calendario o el control de versiones semántico . Inicie sesión o cree una nueva cuenta en testpypi . El registro solo se requiere la primera vez, aunque registrarse más de una vez no es perjudicial. ... $ python >>> import package_name >>> package_name.foo() 100
    • 276. 211 $ twine upload dist/* -r pypitest # Using virtualenv $ mkdir testenv $ cd testenv $ virtualenv .virtualenv ... $ source .virtualenv/bin/activate # Test from testpypi (.virtualenv) pip install --verbose --extra-index-url https://testpypi.python.org/pypi package_name ... # Or test from PyPI (.virtualenv) $ pip install package_name ... (.virtualenv) $ python Python 3.5.1 (default, Jan 27 2016, 19:16:39) [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import package_name >>> package_name.foo() 100 $ pip install twine $ python setup.py register -r pypi $ twine upload dist/* Mientras que en el directorio raíz de su paquete: Su paquete ahora debe ser accesible a través de su cuenta. Pruebas Realiza un entorno virtual de prueba. Intente pip install su paquete desde testpypi o PyPI. Si tiene éxito, su paquete es menos importable. Puede considerar probar su API también antes de su carga final a PyPI. Si el paquete falló durante la prueba, no se preocupe. Aún puedes arreglarlo, volver a subirlo a testpypi y probar de nuevo. Registrarse y subir a PyPI Asegúrate de que el twine esté instalado: Inicie sesión o cree una nueva cuenta en PyPI . ¡Eso es! Su paquete ya está en vivo . Si descubre un error, simplemente cargue una nueva versión de su paquete.
    • 277. 212 [metadata] description-file = README.rst python -m package_name Documentación No olvide incluir al menos algún tipo de documentación para su paquete. PyPi toma como idioma de formato predeterminado reStructuredText . Readme Si su paquete no tiene una gran documentación, incluya lo que puede ayudar a otros usuarios en el archivo README.rst . Cuando el archivo está listo, se necesita otro para decirle a PyPi que lo muestre. Cree el archivo setup.cfg y ponga estas dos líneas en él: Tenga en cuenta que si intenta colocar el archivo Markdown en su paquete, PyPi lo leerá como un archivo de texto puro sin ningún formato. Licenciamiento A menudo es más que bienvenido poner un archivo LICENSE.txt en su paquete con una de las licenciasdeOpenSource parainformaralos usuarios si pueden usar su paquete,por ejemplo,en proyectos comerciales o si su código se puede usar con su licencia. De manera más legible, algunas licencias se explican en TL; DR . Haciendo paquete ejecutable Si su paquete no es solo una biblioteca, sino que tiene una pieza de código que puede usarse como una vitrina o una aplicación independiente cuando su paquete está instalado, coloque esa pieza de código en el archivo main .py . Ponga la main .py en el package_name carpeta. De esta manera podrás ejecutarlo directamente desde la consola: Si no hay main .py archivo main .py disponible, el paquete no se ejecutará con este comando y se imprimirá este error: python:Nohayunmódulollamadopackage_name. main ; 'package_name'esun paquete y no se puede ejecutar directamente.
    • 278. 213 paquetes-de-python
    • 279. 214 import win32serviceutil import win32service import win32event import servicemanager import socket class AppServerSvc (win32serviceutil.ServiceFramework): _svc_name_ = "TestService" _svc_display_name_ = "Test Service" def init (self,args): win32serviceutil.ServiceFramework. init (self,args) self.hWaitStop =win32event.CreateEvent(None,0,0,None) socket.setdefaulttimeout(60) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) def SvcDoRun(self): servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_,'')) self.main() def main(self): pass if name == ' main ': Capítulo 45: Creando un servicio de Windows usando Python Introducción Los procesos sin cabeza (sin interfaz de usuario) en Windows se denominan Servicios. Se pueden controlar (iniciar, detener, etc.) mediante los controles estándar de Windows, como la consola de comandos, Powershell o la pestaña Servicios en el Administrador de tareas. Un buen ejemplo podría ser una aplicación que proporcione servicios de red, como una aplicación web, o tal vez una aplicación de respaldo que realice varias tareas de archivado en segundo plano. Hay varias formas de crear e instalar una aplicación de Python como un Servicio en Windows. Examples Un script de Python que se puede ejecutar como un servicio Los módulos utilizados en este ejemplo son parte de pywin32 (Python para extensiones de Windows). Dependiendo de cómo instaló Python, es posible que necesite instalar esto por separado.
    • 280. 215 nssm install MyServiceName c:\python27\python.exe c:\temp\myscript.py import win32serviceutil import win32service import win32event import servicemanager from multiprocessing import Process from app import app class Service(win32serviceutil.ServiceFramework): _svc_name_ = "TestService" _svc_display_name_ = "Test Service" _svc_description_ = "Tests Python service framework by receiving and echoing messages over a named pipe" def init (self, *args): super(). init (*args) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) self.process.terminate() self.ReportServiceStatus(win32service.SERVICE_STOPPED) def SvcDoRun(self): self.process = Process(target=self.main) self.process.start() self.process.run() Esto es sólo boilerplate. Su código de aplicación, probablemente invocando un script separado, iría en la función main (). También necesitarás instalar esto como un servicio. La mejor solución para esto en este momento parece ser utilizar el Administrador de servicios que no chupa . Esto le permite instalar un servicio y proporciona una GUI para configurar la línea de comandos que ejecuta el servicio. Para Python puedes hacer esto, lo que crea el servicio de una sola vez: Donde my_script.py es el script de boilerplate anterior, modificado para invocar su script o código de aplicación en la función main (). Tenga en cuenta que el servicio no ejecuta la secuencia de comandos de Python directamente, ejecuta el intérprete de Python y le pasa la secuencia de comandos principal en la línea de comandos. Alternativamente, puede usar las herramientas proporcionadas en el Kit de recursos de Windows Server para la versión de su sistema operativo, así que cree el servicio. Ejecutando una aplicación web de Flask como un servicio Estaesunavariacióndelejemplogenérico.Solonecesitaimportarelscriptdesuaplicacióne invocar el métodorun() en la función main().Enestecaso, también estamosusando el módulo de multiprocesamiento debido a un problema al acceder a WSGIRequestHandler . win32serviceutil.HandleCommandLine(AppServerSvc)
    • 281. 216 Adaptado de http://stackoverflow.com/a/25130524/318488 def main(self): app.run() if name == ' main ': win32serviceutil.HandleCommandLine(Service)
    • 282. 217 workon < environment name> mkvirtualenv <name> Create a new virtualenv environment named <name>. The environment will be created in WORKON_HOME. lsvirtualenv List all of the enviornments stored in WORKON_HOME. rmvirtualenv <name> Remove the environment <name>. Uses folder_delete.bat. workon [<name>] If<name> isspecified, activate the environmentnamed <name> (change theworking virtualenv to <name>). If a project directory has been defined, we will change into it. If no argument is specified, list the available environments. One can pass additional option -c after virtualenv name to cd to virtualenv directory if no projectdir isset. deactivate Deactivate the working virtualenv and switch back to the default system Python. add2virtualenv <full or relative path> If a virtualenv environment is active, appends <path> to virtualenv_path_extensions.pth inside Capítulo 46: Crear entorno virtual con virtualenvwrapper en windows Examples Entorno virtual con virtualenvwrapper para windows Supongamos que necesita trabajar en tres proyectos diferentes. El proyecto A, el proyecto B y el proyecto C. el proyecto A y el proyecto B necesitan Python 3 y algunas bibliotecas requeridas. Pero para el proyecto C necesitas Python 2.7 y bibliotecas dependientes. Así que la mejor práctica para esto es separar esos entornos de proyecto. Para crear un entorno virtual de Python separado, debe seguir los siguientes pasos: Paso 1: instala pip con este comando: python -m pip install -U pip Paso 2: Luego instale el paquete "virtualenvwrapper-win" usando el comando (el comando puede ejecutarse en Windows Power Shell): pip install virtualenvwrapper-win Paso 3: Crea un nuevo entorno virtualenv usando el comando: mkvirtualenv python_3.5 Paso 4: Activar el entorno mediante el comando: Comandos principales para virtualenvwrapper:
    • 283. 218 the environment’s site-packages, which effectively adds <path> to the environment’s PYTHONPATH. If a virtualenv environment is not active, appends <path> to virtualenv_path_extensions.pth inside the default Python’s site-packages. If <path> doesn’t exist, it will be created.
    • 284. 219 >>> ntohl = libc.ntohl >>> ntohl <_FuncPtr object at 0xbaadf00d> >>> ntohl(0x6C) 1811939328 >>> hex(_) '0x6c000000' Capítulo 47: ctypes Introducción ctypes es una biblioteca incorporada de python que invoca funciones exportadas desde bibliotecas compiladas nativas. Nota: Dado que esta biblioteca maneja el código compilado, es relativamente dependiente del sistema operativo. Examples Uso básico Digamosquequeremosusarlalibc ntohl libc . Primero, debemos cargarlibc.so : Entonces, obtenemos el objeto de función: Y ahora, simplemente podemos invocar la función: Lo que hace exactamente lo que esperamos que haga. Errores comunes No cargar un archivo El primer error posible está fallando al cargar la biblioteca. En ese caso, un OSError normalmente se plantea. Esto se debe a que el archivo no existe (o el sistema operativo no lo puede encontrar): >>> from ctypes import * >>> libc = cdll.LoadLibrary('libc.so.6') >>> libc <CDLL 'libc.so.6', handle baadf00d at 0xdeadbeef>
    • 285. 220 >>> cdll.LoadLibrary("libc.so") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.5/ctypes/ init .py", line 425, in LoadLibrary return self._dlltype(name) File "/usr/lib/python3.5/ctypes/ init .py", line 347, in init self._handle = _dlopen(self._name, mode) OSError: /usr/lib/i386-linux-gnu/libc.so: invalid ELF header >>> libc.foo Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.5/ctypes/ init .py", line 360, in getattr func = self. getitem(name) File "/usr/lib/python3.5/ctypes/ init .py", line 365, in getitem func = self._FuncPtr((name_or_ordinal, self)) AttributeError: /lib/i386-linux-gnu/libc.so.6: undefined symbol: foo >>> obj = ctypes.c_int(12) >>> obj c_long(12) Como puede ver, el error es claro y bastante indicativo. La segunda razón es que se encuentra el archivo, pero no tiene el formato correcto. En este caso, el archivo es un archivo de script y no un archivo .so . Esto también puede suceder cuando se intenta abrir un archivo .dll en una máquina Linux o un archivo de 64 bits en un intérprete de 32 bits de Python. Como puede ver, en este caso el error es un poco más vago y requiere un poco de investigación. No acceder a una función Suponiendo que .so éxito el archivo .so , necesitamos acceder a nuestra función como lo hemos hecho en el primer ejemplo. Cuando se usa una función que no existe, se AttributeError un AttributeError : Objeto de ctypes básico El objeto más básico es un int: >>> cdll.LoadLibrary("foobar.so") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.5/ctypes/ init .py", line 425, in LoadLibrary return self._dlltype(name) File "/usr/lib/python3.5/ctypes/ init .py", line 347, in init self._handle = _dlopen(self._name, mode) OSError: foobar.so: cannot open shared object file: No such file or directory
    • 286. 221 >>> sizeof(obj) 4 >>> hex(addressof(obj)) '0xdeadbeef' >>> c_int * 16 <class ' main .c_long_Array_16'> >>> arr = (c_int * 16)(*range(16)) >>> arr < main .c_long_Array_16 object at 0xbaddcafe> >>> sizeof(arr) 64 # sizeof(c_int) * 16 >>> hex(addressof(arr)) '0xc000l0ff' Ahora, obj refiere a una porción de memoria que contiene el valor 12. Se puede acceder a ese valor directamente, e incluso modificarse: Ya que obj refiere a un trozo de memoria, también podemos averiguar su tamaño y ubicación: arrays de ctypes Como cualquier buen programador de C sabe, un solo valor no lo llevará tan lejos. ¡Lo que realmente nos hará avanzar son matrices! Estono esuna matriz real, peroestá bastante cerca!Creamos unaclasequedenotauna matriz de 16 int s. Ahora todo lo que tenemos que hacer es inicializarlo: Ahora arr es una matriz real que contiene los números del 0 al 15. Se puede acceder a ellos como en cualquier lista: Y al igual que cualquier otro objeto ctypes , también tiene un tamaño y una ubicación: >>> arr[5] 5 >>> arr[5] = 20 >>> arr[5] 20 >>> obj.value 12 >>> obj.value = 13 >>> obj c_long(13)
    • 287. 222 >>> def max(x, y): return x if x >= y else y >>> CFUNCTYPE(c_int, c_int, c_int) <CFunctionType object at 0xdeadbeef> >>> CFUNCTYPE(c_int, c_int, c_int)(max) <CFunctionType object at 0xdeadbeef> >>> libc.ntohl() # garbage in - garbage out >>> CFUNCTYPE(c_int, c_int)(libc.ntohl)() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: this function takes at least 1 argument (0 given) >>> compar_proto = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int)) >>> lfind_proto = CFUNCTYPE(c_void_p, c_void_p, c_void_p, POINTER(c_uint), c_uint, compar_proto) Funciones de envoltura para ctypes. En algunos casos, una función C acepta un puntero de función. Como usuarios ávidos de ctypes , nos gustaría usar esas funciones, e incluso pasar la función python como argumentos. Vamos a definir una función: Ahora, esa función toma dos argumentos y devuelve un resultado del mismo tipo. Por el bien del ejemplo, asumamos que el tipo es un int. Como hicimos en el ejemplo de matriz, podemos definir un objeto que denota ese prototipo: Ese prototipo denota una función que devuelve un c_int (el primer argumento), y acepta dos argumentos c_int (los otros argumentos). Ahora vamos a envolver la función: Los prototipos de funciones tienen un mayor uso: pueden envolver la función ctypes (como libc.ntohl ) y verificar que se usan los argumentos correctos cuando se invoca la función. Uso complejo lfind todos los ejemplos anteriores en un escenario complejo: utilizando la libc lfind libc . Para más detalles sobre la función, lea la página del manual . Les insto a que lo lean antes de continuar. Primero, definiremos los prototipos adecuados: Entonces, vamos a crear las variables:
    • 288. 223 >>> def compar(x, y): return x.contents.value - y.contents.value >>> lfind = lfind_proto(libc.lfind) >>> ptr = lfind(byref(key), byref(arr), byref(nmemb), sizeof(c_int), compar_proto(compar)) >>> cast(ptr, POINTER(c_int)).contents c_long(12) >>> addressof(arr) + 12 * sizeof(c_int) == ptr True Y ahora definimos la función de comparación: Tenga en cuenta que x , y y son POINTER(c_int) , por lo tanto, debemos desreferenciarlos y tomar sus valores para poder comparar realmente el valor almacenado en la memoria. Ahora podemos combinar todo juntos: ptr es el puntero vacío devuelto. Si no se encontró la key en arr , el valor sería None , pero en este caso obtuvimos un valor válido. Ahora podemos convertirlo y acceder al valor: También, podemosverqueptr apuntaal valorcorrectodentrodearr: >>> key = c_int(12) >>> arr = (c_int * 16)(*range(16)) >>> nmemb = c_uint(16)
    • 289. 224 from struct import pack print(pack('I3c', 123, b'a', b'b', b'c')) # b'{\x00\x00\x00abc' from struct import unpack print(unpack('I3c', b'{\x00\x00\x00abc')) # (123, b'a', b'b', b'c') import struct import sys print "Native byteorder: ", sys.byteorder # If no byteorder is specified, native byteorder is used buffer = struct.pack("ihb", 3, 4, 5) print "Byte chunk: ", repr(buffer) print "Byte chunk unpacked: ", struct.unpack("ihb", buffer) # Last element as unsigned short instead of unsigned char ( 2 Bytes) buffer = struct.pack("ihh", 3, 4, 5) print "Byte chunk: ", repr(buffer) Capítulo 48: Datos binarios Sintaxis • paquete (fmt, v1, v2, ...) • desempaquetar (fmt, buffer) Examples Formatear una lista de valores en un objeto byte Desempaquetar un objeto byte de acuerdo con una cadena de formato Embalaje de una estructura El módulo " struct " proporciona facilidad para empaquetar objetos de python como trozos contiguos de bytes o para diseminar un trozo de bytes en estructuras de python. La función de paquete toma una cadena de formato y uno o más argumentos, y devuelve una cadena binaria. Esto se parece mucho a que está formateando una cadena, excepto que la salida no es una cadena sino una porción de bytes. Salida: Byteorder nativo: fragmento de bytes pequeño: '\ x03 \ x00 \ x00 \ x00 \ x04 \ x00 \ x00' Fragmento de bytes sin empaquetar: (3, 4, 5) Fragmento de bytes: '\ x03 \ x00 \ x00 \ x00 \ x04 \ x00 \ x05 \ x00 '
    • 290. 225 import struct # If no byteorder is specified, native byteorder is used buffer = struct.pack("hhh", 3, 4, 5) print "Byte chunk native byte order: ", repr(buffer) buffer = struct.pack("!hhh", 3, 4, 5) print "Byte chunk network byte order: ", repr(buffer) import struct from ctypes import create_string_buffer bufferVar = create_string_buffer(8) bufferVar2 = create_string_buffer(8) # We use a buffer that has already been created # provide format, buffer, offset and data struct.pack_into("hhh", bufferVar, 0, 3, 4, 5) print "Byte chunk: ", repr(bufferVar.raw) struct.pack_into("hhh", bufferVar2, 2, 3, 4, 5) print "Byte chunk: ", repr(bufferVar2.raw) Puede usar el orden de bytes de la red con los datos recibidos de la red o datos del paquete para enviarlos a la red. Salida: Orden de bytes nativo del byte: '\ x03 \ x00 \ x04 \ x00 \ x05 \ x00' Orden de bytes de la red de bytes: '\ x00 \ x03 \ x00 \ x04 \ x00 \ x05' Puede optimizar evitando la sobrecarga de asignar un nuevo búfer al proporcionar un búfer que se creó anteriormente. Salida: Fragmento de bytes: '\ x03 \ x00 \ x04 \ x00 \ x05 \ x00 \ x00 \ x00' Fragmento de bytes: '\ x00 \ x00 \ x03 \ x00 \ x04 \ x00 \ x05 \ x00'
    • 291. 226 # This simplest decorator does nothing to the function being decorated. Such # minimal decorators can occasionally be used as a kind of code markers. def super_secret_function(f): return f @super_secret_function def my_function(): print("This is my secret function.") Capítulo 49: Decoradores Introducción Las funciones de decorador son patrones de diseño de software. Alteran dinámicamente la funcionalidad de una función, método o clase sin tener que usar subclases directamente o cambiar el código fuente de la función decorada. Cuando se usan correctamente, los decoradores pueden convertirse en herramientas poderosas en el proceso de desarrollo. Este tema cubre la implementación y las aplicaciones de las funciones de decorador en Python. Sintaxis • def decorator_function (f): pass # define un decorador llamado decorator_function • @decorator_function def decorated_function (): pass # la función ahora está envuelta (decorada por) decorator_function • decorated_function = decorator_function (decorated_function) # esto es equivalente a usar el azúcar sintáctico @decorator_function Parámetros Parámetro Detalles F La función a decorar (envolver) Examples Función decoradora Los decoradores aumentan el comportamiento de otras funciones o métodos. Cualquier función que tome una función como parámetro y devuelva una función aumentada puede usarse como decorador . La notación @ es azúcar sintáctica que es equivalente a lo siguiente:
    • 292. 227 def disabled(f): """ This function returns nothing, and hence removes the decorated function from the local scope. """ pass @disabled def my_function(): print("This function can no longer be called...") my_function() # TypeError: 'NoneType' object is not callable #This is the decorator def print_args(func): def inner_func(*args, **kwargs): print(args) print(kwargs) return func(*args, **kwargs) #Call the original function with its arguments. return inner_func @print_args def multiply(num_a, num_b): return num_a * num_b print(multiply(3, 5)) #Output: # (3,5) - This is actually the 'args' that the function receives. # {} - This is the 'kwargs', empty because we didn't specify keyword arguments. # 15 - The result of the function. Es importante tener esto en cuenta para comprender cómo funcionan los decoradores. Esta sintaxis "no saturada" deja claro por qué la función decoradora toma una función como argumento y por qué debería devolver otra función. También demuestra lo que sucedería si no devuelves una función: Por lo tanto, generalmente definimos una nueva función dentro del decorador y la devolvemos. Esta nueva función primero haría algo que debe hacer, luego llama a la función original y, finalmente, procesa el valor de retorno. Considere esta función decoradora simple que imprime los argumentos que recibe la función original y luego la llama. Clase de decorador Como se mencionó en laintroducción, un decoradores una función que se puede aplicar a otra funciónparaaumentarsucomportamiento.Elazúcarsintácticoesequivalentealosiguiente: my_func = decorator(my_func) . Pero, ¿y si el decorator fuera una clase? La sintaxis aún funcionaría, exceptoqueahora my_func sereemplaza conunainstanciadela clase decorator .Si esta clase implementa el método mágico call () , entonces todavía sería posible usar my_func como si fuera una función: my_function = super_secret_function(my_function)
    • 293. 228 import types isinstance(testfunc, types.FunctionType) # False type(testfunc) # <class ' main .Decorator'> from types import MethodType class Decorator(object): def init (self, func): self.func = func def call (self, *args, **kwargs): print('Inside the decorator.') return self.func(*args, **kwargs) def get (self, instance, cls): # Return a Method if it is called on an instance return self if instance is None else MethodType(self, instance) class Test(object): @Decorator def init (self): pass a = Test() Tenga en cuenta que una función decorada con un decorador de clase ya no se considerará una "función" desde la perspectiva de la comprobación de tipo: Métodos de decoración Para los métodos de decoración debe definir un método get adicional: class Decorator(object): """Simple decorator class.""" def init (self, func): self.func = func def call (self, *args, **kwargs): print('Before the function call.') res = self.func(*args, **kwargs) print('After the function call.') return res @Decorator def testfunc(): print('Inside the function.') testfunc() # Before the function call. # Inside the function. # After the function call.
    • 294. 229 from types import MethodType class CountCallsDecorator(object): def init (self, func): self.func = func self.ncalls = 0 # Number of calls of this method def call (self, *args, **kwargs): self.ncalls += 1 # Increment the calls counter return self.func(*args, **kwargs) def get (self, instance, cls): return self if instance is None else MethodType(self, instance) class Test(object): def init (self): pass @CountCallsDecorator def do_something(self): return 'something was done' from functools import wraps Dentro del decorador. ¡Advertencia! Los decoradores de clase solo producen una instancia para una función específica, por lo que decorar un método con un decorador de clase compartirá el mismo decorador entre todas las instancias de esa clase: a = Test() a.do_something() a.do_something.ncalls # 1 b = Test() b.do_something() b.do_something.ncalls # 2 Hacer que un decorador se vea como la función decorada. Los decoradores normalmente eliminan los metadatos de la función ya que no son lo mismo. Esto puede causar problemas cuando se utiliza la meta-programación para acceder dinámicamente a los metadatos de la función. Los metadatos también incluyen las cadenas de documentación de la función y su nombre. functools.wraps hace que la función decorada se vea como la función original al copiar varios atributos a la función de envoltura. Los dos métodos de envolver a un decorador están logrando lo mismo al ocultar que la función original ha sido decorada. No hay razón para preferir la versión de la función a la versión de clase a menos que ya esté utilizando una sobre la otra.
    • 295. 230 def decorator(func): # Copies the docstring, name, annotations and module to the decorator @wraps(func) def wrapped_func(*args, **kwargs): return func(*args, **kwargs) return wrapped_func @decorator def test(): pass test. name class Decorator(object): def init (self, func): # Copies name, module, annotations and docstring to the instance. self._wrapped = wraps(func)(self) def call (self, *args, **kwargs): return self._wrapped(*args,**kwargs) @Decorator def test(): """Docstring of test.""" pass test. doc def decoratorfactory(message): def decorator(func): def wrapped_func(*args, **kwargs): Como una función 'prueba' Como una clase 'Docstring of test'. Decorador con argumentos (decorador de fábrica). Un decorador toma solo un argumento: la función a decorar. No hay forma de pasar otros argumentos. Pero a menudo se desean argumentos adicionales. El truco es, entonces, hacer una función que tome argumentos arbitrarios y devuelva un decorador. Funciones de decorador
    • 296. 231 @decoratorfactory # Without parentheses def test(): pass test() def decoratorfactory(*decorator_args, **decorator_kwargs): class Decorator(object): def init (self, func): self.func = func def call (self, *args, **kwargs): print('Inside the decorator with arguments {}'.format(decorator_args)) return self.func(*args, **kwargs) return Decorator @decoratorfactory(10) def test(): pass test() El decorador quiere decirte: Hola Mundo. Nota IMPORTANTE: Con tales fábricas de decoradores debe llamar al decorador con un par de paréntesis: TypeError: decorator () falta 1 argumento posicional requerido: 'func' Clases de decorador Dentro del decorador con argumentos (10,) Crea una clase de singleton con un decorador. Un singleton es un patrón que restringe la creación de instancias de una clase a una instancia / objeto. Usando un decorador, podemos definir una clase como un singleton forzando a la clase a print('The decorator wants to tell you: {}'.format(message)) return func(*args, **kwargs) return wrapped_func return decorator @decoratorfactory('Hello World') def test(): pass test()
    • 297. 232 def singleton(cls): instance = [None] def wrapper(*args, **kwargs): if instance[0] is None: instance[0] = cls(*args, **kwargs) return instance[0] return wrapper # 3 instance.x = 3 print(SomeSingletonClass().x) @singleton classSomeSingletonClass: x = 2 def init (self): print("Created!") instance = SomeSingletonClass() # prints: Created! instance = SomeSingletonClass() # doesn't print anything print(instance.x) # 2 import time def timer(func): def inner(*args, **kwargs): t1 = time.time() f = func(*args, **kwargs) t2 = time.time() print 'Runtime took {0} seconds'.format(t2-t1) return f return inner @timer def example_function(): #do stuff example_function() devolver una instancia existente de la clase o crear una nueva instancia (si no existe). Este decorador se puede agregar a cualquier declaración de clase y se asegurará de que se cree como máximo una instancia de la clase. Cualquier llamada posterior devolverá la instancia de clase ya existente. Por lo tanto, no importa si se refiere a la instancia de clase a través de su variable local o si crea otra "instancia", siempre obtiene el mismo objeto. Usando un decorador para cronometrar una función.
    • 298. 233 def func(myList): for item in myList: print(item) func([1,2,3,5,7]) 1 2 3 5 7 aList = ['a','b','c','d'] func(aList) a b c d Capítulo 50: Definiendo funciones con argumentos de lista Examples Función y Llamada Las listas como argumentos son solo otra variable: y se puede pasar en la llamada de función en sí: O como una variable:
    • 299. 234 with shelve.open('spam') as db: db['eggs'] = 'eggs' Capítulo 51: dejar de lado Introducción Shelve es un módulo de Python que se utiliza para almacenar objetos en un archivo. El módulo de almacenamiento implementa el almacenamiento persistente para objetos Python arbitrarios que pueden ser decapados, utilizando una API similar a un diccionario. El módulo de almacenamiento puede usarse como una opción de almacenamiento persistente simple para objetos de Python cuando una base de datos relacional es excesiva. Se accede a la estantería mediante llaves, igual que con un diccionario. Los valores se decapan y se escriben en una base de datos creada y administrada por anydbm. Observaciones Nota: No confíe en que el estante se cierre automáticamente; siempre llame a close() explícitamente cuando ya nolonecesite más,ouse shelve.open() como administrador de contexto: Advertencia: Debido a que la shelve módulo está respaldado por pickle , es inseguro para cargar un estante de una fuente no fiable. Al igual que con Pickle, cargar un estante puede ejecutar código arbitrario. Restricciones 1 . La elección del paquete de base de datos que se utilizará (como dbm.ndbm o dbm.gnu) depende de la interfaz disponible. Por lo tanto, no es seguro abrir la base de datos directamente usando dbm. La base de datos también está (desafortunadamente) sujeta a las limitaciones de dbm, si se usa; esto significa que (la representación en escabeche) de los objetos almacenados en la base de datos debería ser bastante pequeña, y en casos raros, las colisiones de claves pueden hacer que la base de datos rechazar actualizaciones. 2. El módulo de archivado no admite el acceso simultáneo de lectura / escritura a objetos archivados. (Múltiples accesos de lectura simultáneos son seguros.) Cuando un programa tiene un estante abierto para escribir, ningún otro programa debería tenerlo abierto para leer o escribir. El bloqueo de archivos de Unix se puede usar para resolver esto, pero esto difiere entre las versiones de Unix y requiere conocimiento sobre la implementación de la base de datos utilizada. Examples
    • 300. 235 import shelve database = shelve.open(filename.suffix) object = Object() database['key'] = object d.close() # close it # as d was opened WITHOUT writeback=True, beware: d['xx'] = [0, 1, 2] # this works as expected, but... d['xx'].append(3) # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]! # having opened d without writeback=True, you need to code carefully: temp = d['xx'] # extracts the copy temp.append(5) # mutates the copy d['xx'] = temp # stores the copy right back, to persist it # or, d=shelve.open(filename,writeback=True) would let you just code # d['xx'].append(5) and have it work as expected, BUT it would also #consumemorememory andmake the d.close() operation slower. # true if the key exists # a list of all existing keys (slow!) flag = key in d klist = list(d.keys()) # store data at key (overwrites old data if # using an existing key) # retrieve a COPY of data at key (raise KeyError # if no such key) # delete data stored at key (raises KeyError # if no such key) d[key] = data data = d[key] del d[key] import shelve d = shelve.open(filename) # open -- file may get suffix added by low-level # library import shelve s = shelve.open('test_shelf.db') try: s['key1'] = { 'int': 10, 'float':9.5, 'string':'Sample data' } Código de muestra para estantería Para archivar un objeto, primero importe el módulo y luego asigne el valor del objeto de la siguiente manera: Para resumir la interfaz (la clave es una cadena, los datos son un objeto arbitrario): Creando un nuevo estante La forma más sencilla de usar shelve es a través de la clase DbfilenameShelf . Utiliza anydbm para almacenar los datos. Puede usar la clase directamente, o simplemente llamar a shelve.open () :
    • 301. 236 import shelve s = shelve.open('test_shelf.db') try: existing = s['key1'] finally: s.close() print existing $ python shelve_create.py $ python shelve_existing.py {'int': 10, 'float': 9.5, 'string': 'Sample data'} import shelve s = shelve.open('test_shelf.db', flag='r') try: existing = s['key1'] finally: s.close() print existing import shelve s = shelve.open('test_shelf.db') try: print s['key1'] s['key1']['new_value'] = 'this was not here before' finally: Para volver a acceder a los datos, abra el estante y utilícelo como un diccionario: Si ejecuta ambos scripts de muestra, debería ver: El módulo dbm no admite múltiples aplicaciones que escriban en la misma base de datos al mismo tiempo. Si sabe que su cliente no modificará el estante, puede pedirle a la estantería que abra la base de datos de solo lectura. Si su programa intenta modificar la base de datos mientras se abre solo para lectura, se genera una excepción de error de acceso. El tipo de excepción depende del módulo de base de datos seleccionado por anydbm cuando se creó la base de datos. Respóndeme Los estantes no rastrean las modificaciones a objetos volátiles, por defecto. Eso significa que si cambia el contenido de un elemento almacenado en el estante, debe actualizar el estante explícitamente almacenándolo nuevamente. finally: s.close()
    • 302. 237 $ python shelve_create.py $ python shelve_withoutwriteback.py {'int': 10, 'float': 9.5, 'string': 'Sample data'} {'int': 10, 'float': 9.5, 'string': 'Sample data'} import shelve s = shelve.open('test_shelf.db', writeback=True) try: print s['key1'] s['key1']['new_value'] = 'this was not here before' print s['key1'] finally: s.close() s = shelve.open('test_shelf.db', writeback=True) try: print s['key1'] finally: s.close() $ python shelve_create.py $ python shelve_writeback.py {'int': 10, 'float': 9.5, 'string': 'Sample data'} {'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'} En este ejemplo, el diccionario en 'key1' no se almacena de nuevo, por lo que cuando el estante se vuelve a abrir, los cambios no se han conservado. Para capturar automáticamente los cambios en los objetos volátiles almacenados en el estante, abra el estante con la función de escritura habilitada. El indicador de reescritura hace que el estante recuerde todos los objetos recuperados de la base de datos utilizando un caché en memoria. Cada objeto de caché también se vuelve a escribir en la base de datos cuando se cierra el estante. Aunque reduce la posibilidad de error del programador y puede hacer que la persistencia del objeto sea más transparente, el uso del modo de reescritura puede no ser deseable en todas las situaciones. La memoria caché consume memoria adicional mientras el estante está abierto, y hacer una pausa para escribir cada objeto almacenado en caché de nuevo en la base de datos cuando se cierra puede llevar más tiempo. Dado que no hay forma de saber si los objetos almacenados en caché se han modificado, todos se han vuelto a escribir. Si su aplicación lee datos más de lo que escribe, la respuesta por escrito agregará más sobrecarga de la que podría desear. s.close() s = shelve.open('test_shelf.db', writeback=True) try: print s['key1'] finally: s.close()
    • 303. 238 {'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}
    • 304. 239 python -m pdb <my_file.py> import pdb def divide(a, b): pdb.set_trace() return a/b # What's wrong with this? Hint: 2 != 3 print divide(1, 2) python foo.py > ~/scratch/foo.py(5)divide() -> return a/b (Pdb) import pdf; pdb.set_trace() (Pdb) p a 1 (Pdb) print a Capítulo 52: Depuración Examples El depurador de Python: depuración paso a paso con _pdb_ La biblioteca estándar de Python incluye una biblioteca de depuración interactiva llamada pdb . pdb tiene capacidades extensivas, la más comúnmente utilizada es la capacidad de "avanzar" en un programa. Para entrar de inmediato en el uso de depuración paso a paso: Esto iniciará el depurador en la primera línea del programa. Por lo general, deseará apuntar a una sección específica del código para la depuración. Para hacer esto, importamos la biblioteca pdb y usamos set_trace () para interrumpir el flujo de este código de ejemplo problemático. Ejecutando este programa se iniciará el depurador interactivo. A menudo, este comando se usa en una línea, por lo que se puede comentar con un solo # carácter En el comando (Pdb) se pueden introducir comandos. Estos comandos pueden ser comandos de depuración o python. Para imprimir variables podemos usar p del depurador, o la impresión de python.
    • 305. 240 locals -> return a/b (Pdb) p a+b 3 (Pdb) [ str(m) for m in [a,b]] ['1', '2'] (Pdb) [ d for d in xrange(5)] [0, 1, 2, 3, 4] (Pdb) !c Para ver la lista de todas las variables locales use función incorporada Estos son buenos comandos de depuración para saber: b <n> | <f>: set breakpoint at line *n* or function named *f*. # b 3 # b divide b: show all breakpoints. c: continue until the next breakpoint. s: step through this line (will enter a function). n: step over this line (jumps over a function). r: continue until the current function returns. l: list a window of code around this line. p <var>: print variable named *var*. # p x q: quit debugger. bt: print the traceback of the current execution call stack up: move your scope up the function call stack to the caller of the current function down: Move your scope back down the function call stack one level step: Run the program until the next line of execution in the program, then return control back to the debugger next: run the program until the next line of execution in the current function, then return control back to the debugger return: run the program until the current function returns, then return control back to the debugger continue: continue running the program until the next breakpoint (or set_trace si called again) El depurador también puede evaluar python interactivamente: Nota: Si alguno de sus nombres de variable coincide con los comandos del depurador, use un signo de exclamación ' ! 'antes de la var para referirse explícitamente a la variable y no al comando del depurador. Por ejemplo, a menudo puede suceder que use el nombre de variable ' c ' para un contador, y tal vez desee imprimirlo mientras está en el depurador. un simple comando ' c ' continuaría la ejecución hasta el siguiente punto de interrupción. En su lugar, use ' ! C ' para imprimir el valor de la variable de la siguiente manera: 1
    • 306. 241 import ipdb ipdb.set_trace() /home/usr/ook.py(3)<module>() 1 import ipdb 2 ipdb.set_trace() ----> 3 print("Hello world!") ipdb> from IPython.core import ultratb sys.excepthook = ultratb.FormattedTB(mode='Verbose', color_scheme='Linux', call_pdb=1) # In the Python file you want to debug. import rpdb rpdb.set_trace() # Call in a terminal to see the output $ nc 127.0.0.1 4444 > /home/usr/ook.py(3)<module>() -> print("Hello world!") A través de IPython y ipdb Si se instala IPython (o Jupyter ), se puede invocar al depurador usando: Cuando se alcanza, el código saldrá e imprimirá: Claramente, esto significa que uno tiene que editar el código. Hay una forma más sencilla: Esto hará que se llame al depurador si se produce una excepción no detectada. Depurador remoto Algunasvecesnecesitasdepurarel códigopython que seejecuta medianteotro proceso y,en este caso, rpdb es muy útil. rpdb es un envoltorio alrededor de pdb que redirige stdin y stdout a un controlador de socket. Por defecto abre el depurador en el puerto 4444. Uso: Y luego necesitas ejecutar esto en la terminal para conectarte a este proceso. Y obtendrás pdb promt 4
    • 307. 242 (Pdb)
    • 308. 243 file_unzip = 'filename.zip' unzip=zipfile.ZipFile(file_unzip, 'r') unzip.extractall() unzip.close() file_untar = 'filename.tar.gz' untar = tarfile.TarFile(file_untar) untar.extractall() untar.close() Capítulo 53: Descomprimir archivos Introducción Paraextraero descomprimir un archivo tar,ZIPogzip,seproporcionan los módulos tarfile, zipfile ygzipdePython,respectivamente.ElmóduloTarFile.extractall(path=".", members=None)Python proporciona la función TarFile.extractall(path=".", members=None) para extraer de un archivo tarball.El módulo zipfile dePython proporcionala función ZipFile.extractall([path[, members[, pwd]]])paraextraerodescomprimirarchivoscomprimidosZIP.Finalmente,elmódulogzipde Python proporciona la clase GzipFile para descomprimir. Examples Usando Python ZipFile.extractall () para descomprimir un archivo ZIP Usando Python TarFile.extractall () para descomprimir un tarball
    • 309. 244 descr. get (self, obj, type=None) --> value descr. set (self, obj, value) --> None descr. delete (self, obj) --> None class DescPrinter(object): """A data descriptor that logs activity.""" _val = 7 defget(self,obj,objtype=None): print('Getting ...') return self._val def set (self, obj, val): print('Setting', val) self._val = val def delete (self, obj): print('Deleting ...') del self._val class Foo(): x = DescPrinter() i = Foo() i.x # Getting ... # 7 i.x = 100 # Setting 100 Capítulo 54: Descriptor Examples Descriptor simple Haydos tipos diferentes de descriptores.Los descriptoresdedatos se definencomoobjetosque definen tanto un get () como un set () , mientras que los descriptores que no son de datos solo definen un get () . Esta distinción es importante cuando se consideran las sustituciones y el espacio de nombres del diccionario de una instancia.Si un descriptor de datos y una entrada en el diccionario de una instancia comparten el mismo nombre, el descriptor de datos tendrá prioridad. Sin embargo, si en cambio un descriptor que no es de datos y una entrada en el diccionario de una instancia comparten el mismo nombre, la entrada del diccionario de la instancia tendrá prioridad. Para hacer un descriptor de datos de solo lectura, defina tanto get () como set () con el conjunto () generando un AttributeError cuando se le llama. Definir el método set () con un marcador de posición de aumento de excepción es suficiente para convertirlo en un descriptor de datos. Un ejemplo implementado:
    • 310. 245 >>> oscillator = Oscillator(freq=100.0) # Set frequency to 100.0 Hz >>>oscillator.period # Period is 1 / frequency, i.e. 0.01 seconds 0.01 >>> oscillator.period = 0.02 # Set period to 0.02seconds >>> oscillator.freq # The frequency is automatically adjusted 50.0 >>> oscillator.freq = 200.0 # Set the frequency to 200.0 Hz >>> oscillator.period # The period is automatically adjusted 0.005 class Hertz(object): def get (self, instance, owner): return self.value def set (self, instance, value): self.value = float(value) class Second(object): def get (self, instance, owner): # When reading period, convert from frequency return 1 / instance.freq def set (self, instance, value): # When setting period, update the frequency instance.freq = 1 / float(value) Conversiones bidireccionales Los objetos descriptores pueden permitir que los atributos de los objetos relacionados reaccionen a los cambios automáticamente. Supongamos que queremos modelar un oscilador con una frecuencia determinada (en hercios) y un período (en segundos). Cuando actualizamos la frecuencia, queremos que el período se actualice, y cuando actualizamos el período, queremos que la frecuencia se actualice: Seleccionamos uno de los valores (frecuencia, en Hertz) como el "ancla", es decir, el que se puede establecer sin conversión, y escribimos una clase de descriptor para él: El "otro" valor (período, en segundos) se define en términos del ancla. Escribimos una clase de descriptor que hace nuestras conversiones: Ahora podemos escribir la clase Oscilador: i.x # Getting ... # 100 del i.x # Deleting... i.x # Getting ... # 7
    • 311. 246 class Oscillator(object): period = Second() # Set the other value as a class attribute def init (self, freq): self.freq = Hertz() # Set the anchor value as an instance attribute self.freq = freq # Assign the passed value - self.period will be adjusted
    • 312. 247 $ conda install binstar $ conda update binstar $ pip install binstar $ binstar login $ binstar whoami $ git clone https://github.com/<NAME>/<Package> package/ setup.py test_package/ init .py hello.py bld.bat build.sh meta.yaml Capítulo 55: Despliegue Examples Cargando un paquete Conda Antes de comenzar debes tener: Anaconda instalado en su sistema Cuenta en Binstar Si no está utilizando Anaconda 1.6+, instale el cliente de línea de comandos de binstar : Si no está utilizando Anaconda, Binstar también está disponible en pypi: Ahora podemos iniciar sesión: Prueba tu nombre de usuario con el comando whoami: Vamos a cargar un paquete con una función simple de "hola mundo". Para seguir, comience obteniendo mi paquete de demostración de Github: Este es un pequeño directorio que se ve así: Setup.py es el archivo de compilación estándar de python y hello.py tiene nuestra única función hello_world (). bld.bat , build.sh y meta.yaml son scripts y metadatos para el paquete Conda . Puede leer lapágina decompilación de Condapara obtener más información sobre esos tresarchivos y supropósito.
    • 313. 248 $ conda build test_package/ $ binstar upload /home/xavier/anaconda/conda-bld/linux-64/test_package-0.1.0-py27_0.tar.bz2 Ahora creamos el paquete ejecutando: Eso es todo lo que se necesita para crear un paquete Conda. El último paso es cargar en binstar copiando y pegando la última línea de la impresión después de ejecutar el comando / paquete de conda build test. En mi sistema el comando es: Como es la primera vez que creas un paquete y una versión, se te pedirá que completes algunos campos de texto que, alternativamente, se podrían hacer a través de la aplicación web. Verá una done impresa para confirmar que ha cargado correctamente su paquete Conda en Binstar.
    • 314. 249 dictionary = {"Hello": 1234, "World": 5678} print(dictionary["Hello"]) Capítulo 56: Diccionario Sintaxis • mydict = {} • mydict [k] = valor • valor = mydict [k] • valor = mydict.get (k) • value = mydict.get (k, "default_value") Parámetros Parámetro Detalles llave La clave deseada para buscar valor El valor a establecer o devolver. Observaciones Elementos útiles para recordar al crear un diccionario: • Cada clave debe ser única (de lo contrario, se anulará) • Cada tecla tiene que ser hashable (puede usar el hash la función hash que, de lo contrario TypeError será lanzada) • No hay un orden particular para las llaves. Examples Accediendo a los valores de un diccionario. El código anterior imprimirá 1234 . La cadena "Hello" en este ejemplo se llama clave . Se utiliza para buscar un valor en el dict colocando la clave entre corchetes. El número 1234 se ve después de los dos puntos respectivos en la definición de dict . Esto se llama el valor al que "Hello" asigna en este dict . Buscar un valor como este con una clave que no existe KeyError una excepción KeyError , que KeyError ejecución si no se detecta. Si queremos acceder a un valor sin arriesgar un KeyError ,
    • 315. 250 w = dictionary.get("whatever") x = dictionary.get("whatever", "nuh-uh") 6} 3} 3} # {'d': 4, 'e': 5, 'f': # {'a': 1, 'b': 2, 'c': # {'a': 1, 'b': 2, 'c': dict(a=1, b=2, c=3) # {'a': 1, 'b': 2, 'c': 3} dict([('d', 4), ('e', 5), ('f', 6)]) dict([('a', 1)], b=2, c=3) dict({'a' : 1, 'b' : 2}, c=3) mydict = {} mydict['not there'] Traceback (most recent call last): File "<stdin>", line 1, in<module> KeyError: 'not there' value = mydict.get(key, default_value) mydict = {} print(mydict) # {} print(mydict.get("foo", "bar")) # bar print(mydict) # {} print(mydict.setdefault("foo", "bar")) # bar podemos usar el método dictionary.get . Por defecto, si la clave no existe, el método devolverá None . Podemos pasarle un segundo valor para devolver en lugar de None en caso de una búsqueda fallida. En este ejemplo, w obtendrá el valor None y x obtendrá el valor "nuh-uh" . El constructor dict () El constructor dict() se puede utilizar para crear diccionarios a partir de argumentos de palabras clave, o desde una única iterable de pares clave-valor, o desde un diccionario único y argumentos de palabras clave. Evitar las excepciones de KeyError Unerror común cuando se usan diccionarios esacceder a una clave que no existe.Esto generalmente resulta en una excepción KeyError Una forma de evitar errores clave es utilizar el método dict.get , que le permite especificar un valor predeterminado para devolver en el caso de una clave ausente. Lo que devuelve mydict[key] si existe, pero de lo contrario devuelve default_value . Tenga en cuentaqueestonoagregakey amydict. Asíque si deseaconservar esepardevaloresclave, se debe utilizar mydict.setdefault(key, default_value) , lo que almacenar el par de valores clave.
    • 316. 251 try: value = mydict[key] except KeyError: value = default_value if key in mydict: value = mydict[key] else: value = default_value mydict = { 'a': '1', 'b': '2' } print(mydict.keys()) # Python2: ['a', 'b'] # Python3: dict_keys(['b', 'a']) print(mydict.values()) # Python2: ['1', '2'] # Python3: dict_values(['2', '1']) Una forma alternativa de lidiar con el problema es atrapar la excepción. También puede comprobar si la clave está in el diccionario. Sin embargo, tenga en cuenta que, en entornos de subprocesos múltiples, es posible que la clave se elimine del diccionario después de la verificación, creando una condición de carrera en la que aún se puede lanzar la excepción. Otra opción es usar una subclase de dict, collections.defaultdict, que tiene un default_factory para crear nuevas entradas en el dict cuando se le da una new_key. Acceso a claves y valores. Cuando se trabaja con diccionarios, a menudo es necesario acceder a todas las claves y valores del diccionario, ya sea en un bucle for , en una lista de comprensión, o simplemente como una lista simple. Dado un diccionario como: Puede obtener una lista de claves utilizando el método keys() : Si, en cambio, desea una lista de valores, use el método de values() : Si desea trabajar con la clave y su valor correspondiente, puede usar el método items() : print(mydict) # {'foo': 'bar'}
    • 317. 252 # empty dict # dict with initial values d = {} d = {'key': 'value'} # Also unpacking one or multiple dictionaries with the literal syntax is possible # makes a shallow copy of otherdict d = {**otherdict} # also updates the shallow copy with the contents of the yetanotherdict. d = {**otherdict, **yetanotherdict} d = {k:v for k,v in [('key', 'value',)]} NOTA:Debidoaqueundictno estáclasificado,laskeys(),losvalues()ylositems()notienen ordendeclasificación.Usesort(),sorted()oOrderedDictsileimportaelordenenqueregresan estos métodos. DiferenciadePython 2/3:EnPython3,estosmétodos devuelvenobjetosespeciales iterables, no listas, y son el equivalente de los iterkeys() , itervalues() y iteritems() . Estos objetos se pueden usarcomolistasen su mayor parte,aunque hay algunas diferencias.VerPEP3106para más detalles. Introducción al Diccionario Un diccionario es un ejemplo de un almacén de valores clave también conocido como Mapeo en Python. Le permite almacenar y recuperar elementos haciendo referencia a una clave. Como los diccionarios son referenciados por clave, tienen búsquedas muy rápidas. Como se utilizan principalmente para hacer referencia a elementos por clave, no están ordenados. creando un dict Los diccionarios se pueden iniciar de muchas maneras: sintaxis literal Python 3.x 3.5 comprensión de dictado Ver también: Comprensiones. clase incorporada: dict() print(mydict.items()) # Python2: [('a', '1'), ('b', '2')] # Python3: dict_items([('b', '2'), ('a', '1')])
    • 318. 253 d['newkey'] = 42 d['new_list'] = [1, 2, 3] d['new_dict'] = {'nested_dict': 1} del d['newkey'] # 'full' # 'empty' # 5 d = defaultdict(lambda: 'empty') d['key'] d['key'] = 'full' d['key'] # 0 from collections import defaultdict d = defaultdict(int) d['key'] d['key'] = 5 d['key'] >>> d = {} {} >>> d.setdefault('Another_key', []).append("This worked!") >>> d {'Another_key': ['This worked!']} modificando un dict Para agregar elementos a un diccionario, simplemente cree una nueva clave con un valor: También es posible agregar list y dictionary como valor: Para eliminar un elemento, elimine la clave del diccionario: Diccionario con valores por defecto Disponible en la biblioteca estándar como defaultdict [*]Alternativamente, sidebesusarlaclasedict incorporada, using dict.setdefault() tepermitirá crear unvalor predeterminado cadavezqueusing dict.setdefault() aunaclavequeno existía antes: Tenga en cuenta que si tiene muchos valores paraagregar, dict.setdefault() creará una nueva instanciadelvalorinicial(eneste ejemploa[]) cadavezquesellame,loquepuedecrear cargas d = dict() # emtpy dict d = dict(key='value') # explicit keyword arguments d = dict([('key', 'value')]) # passing in a list of key/value pairs # make a shallow copy of another dict (only possible if keys are only strings!) d = dict(**otherdict)
    • 319. 254 from collections import OrderedDict d = OrderedDict() d['first'] = 1 d['second'] = 2 d['third'] = 3 d['last'] = 4 # Outputs "first 1", "second 2", "third 3", "last 4" for key in d: print(key, d[key]) >>> >>> def parrot(voltage, state, action): ... print("This parrot wouldn't", action, end=' ') ... print("if you put", voltage, "volts through it.", end='') ... print("E's", state, "!") ... >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} >>> parrot(**d) This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised ! >>> fish = {'name': "Nemo", 'hands': "fins", 'special': "gills"} >>> dog = {'name': "Clifford", 'hands': "paws", 'color': "red"} >>> fishdog = {**fish, **dog} >>> fishdog {'hands': 'paws', 'color': 'red', 'name': 'Clifford', 'special': 'gills'} de trabajo innecesarias. [*] Python Cookbook, 3ª edición, por David Beazley y Brian K. Jones (O'Reilly). Derechos de autor 2013 David Beazley y Brian Jones, 978-1-449-34037-7. Creando un diccionario ordenado Puede crear un diccionario ordenado que seguirá un orden determinado al iterar sobre las claves en el diccionario. Usa OrderedDict del módulo de collections . Esto siempre devolverá los elementos del diccionario en el orden de inserción original cuando serepita. Desempaquetando diccionarios usando el operador ** Puede utilizar el operador de desempaquetado de ** argumentos de palabras clave para entregar los pares clave-valor en un diccionario en los argumentos de una función. Un ejemplo simplificado de la documentación oficial : ApartirdePython 3.5, tambiénpuede utilizar esta sintaxispara fusionarunnúmero arbitrariode objetos dict . Como lo demuestra este ejemplo, las claves duplicadas se asignan a su último valor (por ejemplo,
    • 320. 255 >>> fishdog = {**fish, **dog} >>> fishdog {'hands': 'paws', 'color': 'red', 'name': 'Clifford', 'special': 'gills'} >>> from collections import ChainMap >>> dict(ChainMap(fish, dog)) {'hands': 'fins', 'color': 'red', 'special': 'gills', 'name': 'Nemo'} >>> from itertools import chain >>> dict(chain(fish.items(), dog.items())) {'hands': 'paws', 'color': 'red', 'name': 'Clifford', 'special': 'gills'} >>> fish.update(dog) >>> fish {'color': 'red', 'hands': 'paws', 'name': 'Clifford', 'special': 'gills'} "Clifford" reemplaza a "Nemo"). Fusionando diccionarios Considere los siguientes diccionarios: Python 3.5+ Como lo demuestra este ejemplo, las claves duplicadas se asignan a su último valor (por ejemplo, "Clifford" reemplaza a "Nemo"). Python 3.3+ Con esta técnica, el valor más importante tiene prioridad para una clave dada en lugar de la última ("Clifford" se desecha a favor de "Nemo"). Python 2.x, 3.x Esto utiliza el último valor, como en la técnica basada en ** para la fusión ("Clifford" anula "Nemo"). dict.update utiliza el último dict para sobrescribir el anterior. >>> fish = {'name': "Nemo", 'hands': "fins", 'special': "gills"} >>> dog = {'name': "Clifford", 'hands': "paws", 'color': "red"}
    • 321. 256 role = {"By day": "A typical programmer", "By night": "Still a typical programmer", } options = { "x": ["a", "b"], "y": [10, 20, 30] } import itertools options = { "x": ["a", "b"], "y": [10, 20, 30]} keys = options.keys() values = (options[key] for key in keys) combinations = [dict(zip(keys, combination)) for combination in itertools.product(*values)] print combinations [{'x': 'a', 'y': 10}, {'x': 'b', 'y': 10}, {'x': 'a', 'y': 20}, {'x': 'b', 'y': 20}, {'x': 'a', 'y': 30}, {'x': 'b', 'y': 30}] d = {'a': 1, 'b': 2, 'c':3} for key in d: La coma final Al igual que las listas y las tuplas, puede incluir una coma al final en su diccionario. El PEP 8 dicta que debe dejar un espacio entre la coma final y la llave de cierre. Todas las combinaciones de valores de diccionario. Dado un diccionario como el que se muestra arriba, donde hay una lista que representa un conjuntodevaloresparaexplorarlaclavecorrespondiente.Supongamosquedeseaexplorar "x"="a" con "y"=10 , luego "x"="a" con "y"=10 , y así sucesivamente hasta que haya explorado todas las combinaciones posibles. Puede crear una lista que devuelva todas estas combinaciones de valores utilizando el siguiente código. Esto nos da la siguiente lista almacenada en las combinations variables: Iterando sobre un diccionario Si utiliza un diccionario como iterador (por ejemplo, en una declaración for ), atraviesa las claves del diccionario. Por ejemplo:
    • 322. 257 print([keyforkeyind]) # ['c', 'b', 'a'] for key, value in d.items(): print(key, value) # c 3 # b 2 # a 1 for key, value in d.values(): print(key, value) # 3 # 2 # 1 # Creating and populating it with values stock = {'eggs': 5, 'milk': 2} # Or creating an empty dictionary dictionary = {} # And populating it after dictionary['eggs'] = 5 dictionary['milk'] = 2 # Values can also be lists Lo mismo es cierto cuando se usa en una comprensión. Python 3.x 3.0 El método items() se puede utilizar para recorrer simultáneamente tanto la clave como el valor : Si bien el método de values() se puede usar para iterar solo sobre los valores, como se esperaría: Python 2.x 2.2 Aquí,laskeys()métodoskeys(),losvalues()ylositems()devuelvenlaslistas,yexistenlostres métodos adicionales iterkeys() itervalues() y iteritems() para devolver los iteraters. Creando un diccionario Reglas para crear un diccionario: • Cada clave debe ser única (de lo contrario, se anulará) • Cada tecla tiene que ser hashable (puede usar el hash la función hash que, de lo contrario TypeError será lanzada) • No hay un orden particular para las llaves. print(key, d[key]) # c 3 # b 2 # a 1
    • 323. 258 car = {} car["wheels"] = 4 car["color"] = "Red" car["model"] = "Corvette" print "Little " + car["color"] + " " + car["model"] + "!" # This would print out "Little RedCorvette!" car = {"wheels": 4, "color": "Red", "model": "Corvette"} for key in car: print key + ": " + car[key] # wheels: 4 # color: Red # model: Corvette Diccionarios ejemplo Diccionarios mapean claves a valores. Los valores del diccionario se pueden acceder por sus claves. Los diccionarios también se pueden crear en un estilo JSON: Los valores del diccionario se pueden iterar sobre: mydict = {'a': [1, 2, 3], 'b': ['one', 'two', 'three']} # Use list.append() method to add new elements to the values list mydict['a'].append(4) # => {'a': [1, 2, 3, 4], 'b': ['one', 'two', 'three']} mydict['b'].append('four') # => {'a': [1, 2, 3, 4], 'b': ['one', 'two', 'three', 'four']} # We can also create a dictionary using a list of two-items tuples iterable = [('eggs', 5), ('milk', 2)] dictionary = dict(iterables) # Or using keyword argument: dictionary = dict(eggs=5, milk=2) # Another way will be to use the dict.fromkeys: dictionary = dict.fromkeys((milk, eggs)) # => {'milk': None, 'eggs': None} dictionary = dict.fromkeys((milk, eggs), (2, 5)) # => {'milk': 2, 'eggs': 5}
    • 324. 259 import sys sys.path.append("package.zip") def hi(): print("Hello world!") import module module.hi() >>> from module import hi >>> hi() # Hello world! Capítulo 57: Diferencia entre Módulo y Paquete Observaciones Es posible poner un paquete de Python en un archivo ZIP, y usarlo de esa manera si agrega estas líneas al comienzo de su script: Examples Módulos Un módulo es un único archivo de Python que se puede importar. El uso de un módulo se ve así: module.py my_script.py en un intérprete Paquetes Un paquete se compone de varios archivos (o módulos) de Python e incluso puede incluir bibliotecas escritas en C o C ++. En lugar de ser un solo archivo, es una estructura de carpetas completa que podría tener este aspecto: package carpetas • init .py • dog.py • hi.py init .py
    • 325. 260 def woof(): print("WOOF!!!") def hi(): print("Hello world!") dog.py hi.py TodoslospaquetesdePythondebencontenerunarchivo init .py.Cuandoimportaun paquete en su script ( import package ), se init .py script init .py , que le dará acceso a todas las funciones del paquete. En este caso, le permite utilizarlas funciones package.hi y package.woof . from package.dog import woof from package.hi import hi
    • 326. 261 sudo easy_install -U py2app pip install py2app py2applet --make-setup MyApplication.py """ This is a setup.py script generated by py2applet Usage: python setup.py py2app """ from setuptools import setup APP = ['test.py'] DATA_FILES = [] OPTIONS = {'argv_emulation': True} setup( app=APP, data_files=DATA_FILES, options={'py2app': OPTIONS}, setup_requires=['py2app'], ) DATA_FILES = ['myInsertedImage.jpg'] OPTIONS = {'argv_emulation': True, 'iconfile': 'myCoolIcon.icns'} Capítulo 58: Distribución Examples py2app Para usar el framework py2app debes instalarlo primero. Haga esto abriendo el terminal e ingresando el siguiente comando: También puede pip instalar los paquetes como: Luego crea el archivo de configuración para tu script de python: Edite la configuración del archivo de configuración a su gusto, esta es la predeterminada: Para agregar un archivo de icono (este archivo debe tener una extensión .icns), o incluir imágenes en su aplicación como referencia, cambie las opciones como se muestra: Finalmente ingrese esto en la terminal:
    • 327. 262 python setup.py build sudo python setup.py install application_title = "My Application" # Use your own application name main_python_file = "my_script.py" # Your python script import sys from cx_Freeze import setup, Executable base = None if sys.platform == "win32": base = "Win32GUI" includes = ["atexit","re"] setup( name = application_title, version = "0.1", description = "Your Description", options = {"build_exe" : {"includes" : includes }}, executables = [Executable(main_python_file, base = base)]) python setup.py bdist_mac El script debería ejecutarse y encontrará su aplicación terminada en la carpeta dist. Usa las siguientes opciones para más personalización: cx_Freeze Instala cx_Freeze desde aquí Descomprima la carpeta y ejecute estos comandos desde ese directorio: Cree un nuevo directorio para su script de python y cree un archivo "setup.py" en el mismo directorio con el siguiente contenido: Ahora ejecuta tu setup.py desde la terminal: comma-separated list of additional scripts to include in an application or plugin. extra-scripts Bundle extension [default:.app for app, .plugin for plugin] extension packages (-p) comma-separated list of packages to include includes (-i) comma-separated list of modules to include optimization level: -O1 for "python -O", -O2 for "python -OO", and -O0 to disable [default: -O0] optimize (-O) python setup.py py2app
    • 328. 263 NOTA: En El Capitán, esto deberá ejecutarse como root con el modo SIP deshabilitado.
    • 329. 264 from django.http import HttpResponse define helloWorld(request): return HttpResponse("Hello World!! Django Welcomes You.") Capítulo 59: Django Introducción Django es un marco web de Python de alto nivel que fomenta el desarrollo rápido y el diseño limpio y pragmático. Creado por desarrolladores experimentados, se encarga de gran parte de la molestia del desarrollo web, por lo que puede centrarse en escribir su aplicación sin necesidad de reinventar la rueda. Es gratis y de código abierto. Examples Hola mundo con django Haz un ejemplo simple de Hello World usando tu django. Asegurémonos de que tienes django instalado en tu PC primero. abre una terminal y escribe: python -c "import django" -> si no aparece ningún error, significa que django ya está instalado. Ahora vamos a crear un proyecto en django. Para eso escribe abajo el comando en la terminal: django-admin startproject HelloWorld El comando anterior creará un directorio llamado HelloWorld. La estructura del directorio será como: Hola Mundo | | | - init .py | | --settings.py | | --urls.py | | --wsgi.py | --manejar.py Escritura de vistas (Referencia de la documentación de django) Una función de vista, o vista para abreviar, es simplemente una función de Python que toma una solicitud web y devuelve una respuesta web. Esta respuesta puede ser el contenido HTML de una página web o cualquier cosa. La documentación dice que podemos escribir la función de vistas en cualquier lugar, pero es mejor escribir en views.py ubicado en nuestro directorio de proyectos. Aquí hay una vista que devuelve un mensaje de hello world. (Views.py)
    • 330. 265 from django.conf.urls import url from . import views #import the views.py from current directory urlpatterns = [ url(r'^helloworld/$', views.helloWorld), ] entendamos el código, paso a paso. • Primero, importamos la clase HttpResponse desde el módulo django.http. • A continuación, definimos una función llamada helloworld. Esta es la función de vista.Cada función de vista toma un objeto HttpRequest como su primer parámetro, que normalmente se denomina solicitud. Tenga en cuenta que el nombre de la función de vista no importa; no tiene que ser nombrado de cierta manera para que Django lo reconozca. Lo llamamos helloworld aquí, para que quede claro lo que hace. • La vista devuelve un objeto HttpResponse que contiene la respuesta generada. Cada función de vista es responsable de devolver un objeto HttpResponse. Para más información sobre las vistas de Django, haga clic aquí. Mapeo de URLs a vistas Para mostrar esta vista en una URL particular, deberá crear una URLconf; Antes de eso vamos a entender cómo django procesa las solicitudes. • Django determina el módulo raíz URLconf a usar. • Django carga ese módulo de Python y busca las variables urlpatterns. Esta debería ser una lista de Python de instancias de django.conf.urls.url (). • Django recorre cada patrón de URL, en orden, y se detiene en el primero que coincide con la URL solicitada. • Una vez que una de las expresiones regulares coincide, Django importa y llama a la vista dada, que es una función simple de Python. Así es como se ve nuestro URLconf: Para más información sobre las URL de Django, haga clic aquí. Ahora cambie el directorio a HelloWorld y escriba el comando siguiente en la terminal. python manage.py runserver de forma predeterminada, el servidor se ejecutará en 127.0.0.1:8000 Abra su navegador y escriba 127.0.0.1:8000/helloworld/. La página te mostrará "¡Hola mundo! Django te da la bienvenida". Lea Django en línea: https://levcode.com/es/python/topic/8994/django
    • 331. 266 Capítulo 60: Ejecución de código dinámico con `exec` y` eval` Sintaxis • eval (expresión [, globals = None [, locals = None]]) • exec (objeto) • exec (objeto, globals) • exec (objeto, globales, locales) Parámetros Argumento Detalles expression El código de expresión como una cadena o un objeto de code object El código de la declaración como una cadena, o un objeto de code globals El diccionario a utilizar para variables globales.Si no se especificanlos locales, esto también se usa para los locales.Si se omite, se utilizan los globals() del ámbito de llamada. locals Unobjetodemapeoqueseutilizaparalasvariableslocales.Siseomite,se usaelque sepasaparalos globals.Siseomitenambos,entonces seutilizan los globals() y locals() del ámbito de llamada para los globals y locals respectivamente. Observaciones En exec , si los globals son locals (es decir, se refieren al mismo objeto), el código se ejecuta como si estuviera en el nivel del módulo. Silos elementos globals ylocals sonobjetosdistintos, el código se ejecuta como si estuviera en un cuerpo de clase . Si las globals de objeto se pasa en, pero no especifica builtins clave, entonces Python funcionesintegradas ylos nombresseañadenautomáticamentealámbitoglobal.Parasuprimirla disponibilidad de funciones como la print o la isinstance en el ámbito ejecutado, permita que los globals tengan la clave builtins asignada al valor None . Sin embargo, esto no es una característica de seguridad. La sintaxis específica de Python 2 no debe usarse; La sintaxis de Python 3 funcionará en Python 2. Por lo tanto, los siguientes formularios están en desuso: <s> • exec object • exec object in globals
    • 332. 267 >>> expression = '5 + 3 * a' >>> a = 5 >>> result = eval(expression) >>> result 20 >>> code = compile('a * b + c', '<string>', 'eval') >>> code <code object <module> at 0x7f0e51a58830, file "<string>", line 1> >>> a, b, c = 1, 2, 3 >>> eval(code) 5 >>> variables = {'a': 6, 'b': 7} >>> eval('a * b', globals=variables) 42 >>> eval('variables') {'a': 6, 'b': 7} >>> eval('variables', globals=variables) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 1, in <module> • exec object in globals, locals Examples Evaluando declaraciones con exec >>> code = """for i in range(5):\n >>> exec(code) Hello world! Hello world! Hello world! Hello world! Hello world! print('Hello world!')""" Evaluando una expresión con eval Precompilando una expresión para evaluarla varias veces. compile función incorporada de compile se puede utilizar para precompilar una expresión en un objeto de código; este objeto de código se puede pasar a eval.Esto acelerará las ejecuciones repetidas del código evaluado. El tercer parámetro para compile debe ser la cadena 'eval' . Evaluar una expresión con eval utilizando globales personalizados Como un plus, con esto el código no puede referirse accidentalmente a los nombres definidos fuera:
    • 333. 268 >>> from collections import defaultdict >>> variables = defaultdict(int, {'a': 42}) >>> eval('a * c', globals=variables) # note that 'c' is not explicitly defined 0 >>> import ast >>> code = """(1, 2, {'foo': 'bar'})""" >>> object = ast.literal_eval(code) >>> object (1, 2, {'foo': 'bar'}) >>> type(object) <class 'tuple'> >>> import ast >>> ast.literal_eval('()' * 1000000) [5] 21358 segmentation fault (core dumped) python3 El uso de defaultdict permite, por ejemplo, tener variables indefinidas configuradas en cero: Evaluar una cadena que contiene un literal de Python con ast.literal_eval Sitieneunacadena quecontieneliterales de Python,como cadenas,flotadores,etc.,puedeusar ast.literal_eval para evaluar su valor en lugar de eval . Esto tiene la característica adicional de permitir solo cierta sintaxis. Sin embargo, esto no es seguro para la ejecución del código proporcionado por un usuario no confiable, y es trivial bloquear un intérprete con una entrada cuidadosamente diseñada Aquí, la entrada es una cadena de () repetida un millón de veces, lo que provoca un bloqueo en el analizador CPython. Los desarrolladores de CPython no consideran los errores en el analizador como problemas de seguridad. Código de ejecución proporcionado por un usuario no confiable que utiliza exec, eval o ast.literal_eval No es posible usar eval o exec para ejecutar código de un usuario no confiable de forma segura. Incluso ast.literal_eval es propenso a bloqueos en el analizador. A veces es posible protegerse contra la ejecución de código malicioso, pero no excluye la posibilidad de bloqueos directos en el analizador o el tokenizador. Para evaluar el código por un usuario que no es de confianza, debe recurrir a algún módulode terceros, o tal vez escribir su propio analizador y su propia máquina virtual en Python. NameError: name 'variables' is not defined
    • 334. 269 EXTENDED_ARG = 145 # All opcodes greater than this have 2 operands HAVE_ARGUMENT = 90 # All opcodes greater than this have at least 1 operands cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', 'is ... # A list of comparator id's. The indecies are used as operands in some opcodes # All opcodes in these lists have the respective types as there operands hascompare = [107] hasconst = [100] haslocal = [124, 125, 126] hasname = [90, 91, 95, 96, 97, 98, 101, 106, 108, 109, 116] # A map of opcodes to ids opmap = {'BINARY_ADD': 23, 'BINARY_AND': 64, 'BINARY_DIVIDE': 21, 'BIN... # A map of ids to opcodes opname = ['STOP_CODE', 'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'DUP_TOP', '... >>> def hello(): ... print "Hello, World" ... >>> dis.dis(hello) Capítulo 61: El dis módulo Examples Constantes en el módulo dis hasfree = [135, 136, 137] hasjabs = [111, 112, 113, 114, 115, 119] hasjrel = [93, 110, 120, 121, 122, 143] ¿Qué es el código de bytes de Python? Python es un intérprete híbrido. Al ejecutar un programa, primero lo ensambla en un código de bytes que luego puede ejecutarse en el intérprete de Python (también denominado máquina virtual de Python ). El módulo dis en la biblioteca estándar se puede usar para hacer que el bytecode de Python sea legible al desensamblar clases, métodos, funciones y objetos de código. 2 0 LOAD_CONST 1 ('Hello, World') 3 PRINT_ITEM 4 PRINT_NEWLINE 5 LOAD_CONST 0 (None) 8 RETURN_VALUE El intérprete de Python se basa en la pila y utiliza un sistema de último en entrar, último en salir. Cada código de operación (código de operación) en el lenguaje ensamblador de Python (el bytecode) toma un número fijo de elementos de la pila y devuelve un número fijo de elementos a la pila. Si no hay suficientes elementos en la pila para un código de operación, el intérprete de Python se bloqueará, posiblemente sin un mensaje de error. Desmontaje de módulos.
    • 335. 270 python -m compileall <file>.py import dis import marshal with open("<file>.pyc", "rb") as code_f: code_f.read(8)#Magicnumber andmodificationtime code = marshal.load(code_f) # Returns a code object which can be disassembled dis.dis(code) # Output the disassembly Para desensamblar un módulo de Python, primero se debe convertir en un archivo .pyc (compilado por Python). Para hacer esto, corre Luego, en un intérprete, ejecute Esto compilará un módulo de Python y dará salida a las instrucciones del código de bytes con dis . El módulo nunca se importa, por lo que es seguro utilizarlo con código no confiable.
    • 336. 271 >>> help() Welcome to Python 3.4's help utility! If this is your first time using Python, you should definitely check out the tutorial on the Internet at http://docs.python.org/3.4/tutorial/. Enter the name of any module, keyword, or topic to get help on writing Python programs and usingPython modules. To quit this help utility and return to the interpreter, just type "quit". To get a list of available modules, keywords, symbols, or topics, type "modules", "keywords", "symbols",or "topics". Eachmodulealsocomes with a one-line summary of what it does; to list the modules whose name or summary contain a given string such as "spam", type "modules spam". >>> 2 + 2 4 >>> _ 4 >>> _ + 6 10 >>> "Hello, {0}".format("World") 'Hello, World' >>> _ 'Hello, World' >>> def wontchangethings(): ... pass Capítulo 62: El intérprete (consola de línea de comandos) Examples Obtención de ayuda general Si se llama a la función de help en la consola sin ningún argumento, Python presenta una consola de ayuda interactiva, donde puede obtener información sobre módulos, símbolos, palabras clave y más de Python. Refiriéndose a la última expresión. Para obtener el valor del último resultado de su última expresión en la consola, use un guión bajo _ . Este valor de subrayado mágico solo se actualiza cuando se usa una expresión de python que da como resultado un valor. Definir funciones o para bucles no cambia el valor. Si la expresión genera una excepción, no habrá cambios en _ .
    • 337. 272 $ py Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> print("Welcome!") $ py Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. Welcome! >>> Recuerde, esta variable mágica solo está disponible en el intérprete interactivo de Python. Ejecutar scripts no hará esto. Abriendo la consola de Python Laconsola para la versión principal dePythonporlo general se puede abrir escribiendo py enla consola de Windows o python en otrasplataformas. Si tiene varias versiones, entonces, de forma predeterminada, sus ejecutables se asignarán a python2 o python3 respectivamente. Por supuesto, esto depende de que los ejecutables de Python estén en tu RUTA. La variable PYTHONSTARTUP Puede establecer una variable de entorno llamada PYTHONSTARTUP para la consola de Python. Cada vez que ingrese a la consola de Python, este archivo se ejecutará, lo que le permitirá agregar funcionalidad adicional a la consola, como la importación automática de módulos de uso común. Si la variable PYTHONSTARTUP se configuró en la ubicación de un archivo que contiene esto: Luego, abrir la consola de Python resultaría en esta salida adicional: Argumentos de línea de comando Python tiene una variedad deinterruptores delínea de comando que se pueden pasar a py .Se pueden encontrar ejecutando py --help , que proporciona esta salida en Python 3.4: >>> _ 'Hello, World' >>> 27 / 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero >>> _ 'Hello, World'
    • 338. 273 Python Launcher usage: py [ launcher-arguments ] [ python-arguments ] script [ script-arguments ] Launcher arguments: -2 : Launch the latest Python 2.x version -3 : Launch the latest Python 3.x version -X.Y : Launch the specified Python version -X.Y-32: Launch the specified 32bit Python version The following help text is from Python: usage: G:\Python34\python.exe [option] ... [-c cmd | -m mod | file | -] [arg] ... Options and arguments(and corresponding environment variables): -b : issue warnings about str(bytes_instance), str(bytearray_instance) and comparing bytes/bytearray with str. (-bb: issue errors) -B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x -c cmd : program passed in as string (terminates option list) -d : debug output from parser; also PYTHONDEBUG=x -E : ignore PYTHON* environment variables (such as PYTHONPATH) -h : print this help message and exit (also --help) -i : inspect interactively after running script; forces a prompt even if stdin does not appear to be a terminal; also PYTHONINSPECT=x -I : isolate Python from the user's environment (implies -E and -s) -m mod : run library module as a script (terminates option list) -O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x -OO : remove doc-strings in addition to the -O optimizations -q : don't print version and copyright messages on interactive startup -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE -S : don't imply 'import site' on initialization -u : unbuffered binary stdout and stderr, stdin always buffered; also PYTHONUNBUFFERED=x see man page for details on internal buffering relating to '-u' -v : verbose (trace importstatements); also PYTHONVERBOSE=x can be supplied multiple times to increase verbosity -V : print the Python version number and exit (also --version) -W arg : warning control; arg is action:message:category:module:lineno also PYTHONWARNINGS=arg -x : skip first line of source, allowing use of non-Unix forms of #!cmd -Xopt:setimplementation-specificoption file : program read from script file - : program read from stdin (default; interactive mode if a tty) arg ...: arguments passed to program in sys.argv[1:] Other environment variables: PYTHONSTARTUP: file executed on interactive startup (no default) PYTHONPATH : ';'-separated list of directories prefixed to the default module search path. The result issys.path. PYTHONHOME : alternate <prefix> directory (or <prefix>;<exec_prefix>). The default module search path uses <prefix>\lib. PYTHONCASEOK : ignore case in 'import' statements (Windows). PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr. PYTHONFAULTHANDLER: dump the Python traceback on fatal errors. PYTHONHASHSEED: if this variable issetto 'random', a random value is used to seed the hashes of str, bytes anddatetime objects. It can also be set to an integer in the range [0,4294967295] to get hash values with a predictable seed. Obteniendo ayuda sobre un objeto
    • 339. 274 >>> help(print) Help on built-in function print in module builtins: print(...) print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments: file: a file-like object (stream); defaults to the currentsys.stdout. sep: string inserted between values, default a space. end: string appended after the last value, default a newline. flush: whether to forcibly flush the stream. Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x. int (). For floating point numbers, this truncates towards zero. If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int('0b100', base=0) 4 Methods defined here: abs (self, /) abs(self) add (self, value, /) Return self+value... int(x=0) -> integer int(x, base=10) -> integer | | | | | | | | | | | | | | | | | | | | | | >>> x = 2 >>> help(x) Help on int object: class int(object) La consola de Python agrega una nueva función, help , que se puede usar para obtener información sobre una función u objeto. Para una función, la help imprime su firma (argumentos) y su cadena de documentación, si la función tiene una. Para un objeto, la help enumera la cadena de documentos del objeto y las diferentes funciones miembro que tiene el objeto.
    • 340. 275 Capítulo 63: El módulo base64 Introducción La codificación de Base 64 representa un esquema común para la codificación de binarios en formato de cadena ASCII utilizando radix 64. El módulo base64 es parte de la biblioteca estándar, lo que significa que se instala junto con Python. La comprensión de los bytes y las cadenas es fundamental para este tema y se puede revisar aquí . Este tema explica cómo usar las distintas funciones y bases numéricas del módulo base64. Sintaxis • base64.b64encode (s, altchars = Ninguno) • base64.b64decode (s, altchars = None, validate = False) • base64.standard_b64encode (s) • base64.standard_b64decode (s) • base64.urlsafe_b64encode (s) • base64.urlsafe_b64decode (s) • base64.b32encode (s) • base64.b32decode (s) • base64.b16encode (s) • base64.b16decode (s) • base64.a85encode (b, foldspaces = False, wrapcol = 0, pad = False, adobe = False) • base64.a85decode (b, foldpaces = False, adobe = False, ignorechars = b '\ t \ n \ r \v') • base64.b85encode (b, pad = False) • base64.b85decode (b) Parámetros Parámetro Descripción base64.b64encode(s, altchars=None) s Un objeto parecido a bytes altares Un objeto similar a bytes de longitud 2+ de caracteres para reemplazar los caracteres '+' y '=' al crear el alfabeto Base64. Los caracteres adicionales son ignorados. base64.b64decode(s, altchars=None, validate=False) s Un objeto parecido a bytes altares Un objeto similar a bytes de longitud 2+ de
    • 341. 276 Parámetro Descripción caracteres para reemplazar los caracteres '+' y '=' al crear el alfabeto Base64. Los caracteres adicionales son ignorados. validar Si valide es True, los caracteres que no están en el alfabeto Base64 normal o en el alfabeto alternativo no se descartan antes de la verificación de relleno base64.standard_b64encode(s) s Un objeto parecido a bytes base64.standard_b64decode(s) s Un objeto parecido a bytes base64.urlsafe_b64encode(s) s Un objeto parecido a bytes base64.urlsafe_b64decode(s) s Un objeto parecido a bytes b32encode(s) s Un objeto parecido a bytes b32decode(s) s Un objeto parecido a bytes base64.b16encode(s) s Un objeto parecido a bytes base64.b16decode(s) s Un objeto parecido a bytes base64.a85encode(b, foldspaces=False, wrapcol=0, pad=False, adobe=False) segundo Un objeto parecido a bytes espacios de plegado Si foldspaces es True, se utilizará el carácter 'y' en lugar de 4 espacios consecutivos. envoltura Los caracteres numéricos antes de una nueva línea (0 implica que no hay nuevas líneas) almohadilla Si el pad es True, los bytes se rellenan a un
    • 342. 277 import base64 Parámetro Descripción adobe múltiplo de 4 antes de codificar Si Adobe es verdadero, la secuencia codificada se debe enmarcar con '<~' y '' ~> 'como se usa con los productos de Adobe. base64.a85decode(b, foldspaces=False, adobe=False, ignorechars=b'\t\n\r\v') segundo Un objeto parecido a bytes espacios de plegado Si foldspaces es True, se utilizará el carácter 'y' en lugar de 4 espacios consecutivos. adobe Si Adobe es verdadero, la secuencia codificada se debe enmarcar con '<~' y '' ~> 'como se usa con los productos de Adobe. ignorantes Un objeto de caracteres similar a bytes que se ignorará en el proceso de codificación. base64.b85encode(b, pad=False) segundo Un objeto parecido a bytes almohadilla Si el pad es True, los bytes se rellenan a un múltiplo de 4 antes de codificar base64.b85decode(b) segundo Un objeto parecido a bytes Observaciones Hasta que salió Python 3.4, las funciones de codificación y decodificación de base64 solo funcionaban con bytes o tipos de bytearray . Ahora estas funciones aceptan cualquier objeto similar a bytes . Examples Codificación y decodificación Base64 Para incluir el módulo base64 en su script, primero debe importarlo: Las funciones de codificación y decodificación de base64 requieren un objeto similar a bytes .
    • 343. 278 s = "Hello World!" b = s.encode("UTF-8") import base64 s = "Hello World!" b = s.encode("UTF-8") e = base64.b64encode(b) print(e) import base64 s = "Hello World!" b = s.encode("UTF-8") e = base64.b64encode(b) s1 = e.decode("UTF-8") print(s1) import base64 # Creating a string s = "Hello World!" # Encoding the string into bytes b = s.encode("UTF-8") # Base64 Encode the bytes e = base64.b64encode(b) # Decoding the Base64 bytes to string s1 = e.decode("UTF-8") # Printing Base64 encoded string Para convertir nuestra cadena en bytes, debemos codificarla utilizando la función de codificación incorporada de Python. Más comúnmente, se usa la codificación UTF-8 , sin embargo, se puede encontrar una lista completa de estas codificaciones estándar (incluidos los idiomas con diferentes caracteres) aquí en la Documentación oficial de Python. A continuación se muestra un ejemplo de codificación de una cadena en bytes: La salida de la última línea sería: b'Hello World!' El prefijo b se utiliza para indicar que el valor es un objeto de bytes. Para codificar en Base64 estos bytes, usamos la función base64.b64encode() : Ese código daría como resultado lo siguiente: b'SGVsbG8gV29ybGQh' que todavía está en el objeto bytes.Para obtener una cadena deestos bytes, podemos usar el método decode() Python con la UTF-8 : La salida sería entonces: SGVsbG8gV29ybGQh Si quisiéramos codificar la cadena y luego decodificar, podríamos usar el método base64.b64decode() :
    • 344. 279 Base64 Encoded: SGVsbG8gV29ybGQh Hello World! import base64 # Creating a string s = "Hello World!" # Encoding the string into bytes b = s.encode("UTF-8") # Base32 Encode the bytes e = base64.b32encode(b) # Decoding the Base32 bytes to string s1 = e.decode("UTF-8") # Printing Base32 encoded string print("Base32 Encoded:", s1) # Encoding the Base32 encoded string into bytes b1 = s1.encode("UTF-8") # Decoding the Base32 bytes d = base64.b32decode(b1) # Decoding the bytes to string s2 = d.decode("UTF-8") print(s2) Base32 Encoded: JBSWY3DPEBLW64TMMQQQ==== Hello World! import base64 # Creating a string s = "Hello World!" # Encoding the string into bytes Como es de esperar, la salida sería la cadena original: Codificación y decodificación Base32 El módulo base64 también incluye funciones de codificación y decodificación para Base32. Estas funciones son muy similares a las funciones de Base64: Esto produciría el siguiente resultado: Codificación y decodificación Base16 El módulo base64 también incluye funciones de codificación y decodificación para Base16. La base 16 es comúnmente conocida como hexadecimal . Estas funciones son muy similares a las funciones Base64 y Base32: print("Base64 Encoded:", s1) # Encoding the Base64 encoded string into bytes b1 = s1.encode("UTF-8") # Decoding the Base64 bytes d = base64.b64decode(b1) # Decoding the bytes to string s2 = d.decode("UTF-8") print(s2)
    • 345. 280 Base16 Encoded: 48656C6C6F20576F726C6421 Hello World! import base64 # Creating a string s = "Hello World!" # Encoding the string into bytes b = s.encode("UTF-8") # ASCII85 Encode the bytes e = base64.a85encode(b) # Decoding the ASCII85 bytes to string s1 = e.decode("UTF-8") # Printing ASCII85 encoded string print("ASCII85 Encoded:", s1) # Encoding the ASCII85 encoded string into bytes b1 = s1.encode("UTF-8") # Decoding the ASCII85 bytes d = base64.a85decode(b1) # Decoding the bytes to string s2 = d.decode("UTF-8") print(s2) ASCII85 Encoded: 87cURD]i,"Ebo80 Hello World! Esto produciría el siguiente resultado: Codificación y decodificación ASCII85 Adobe creó su propia codificación llamada ASCII85 que es similar a Base85, pero tiene sus diferencias. Esta codificación se utiliza con frecuencia en los archivos PDF de Adobe. Estas funciones fueron lanzadas en la versión 3.4 de Python. De lo contrario, las funciones base64.a85encode() y base64.a85encode() son similares a las anteriores: Esto da como resultado lo siguiente: Codificación y decodificación Base85 Al igual que las funciones Base64, Base32 y Base16, las funciones de codificación y b = s.encode("UTF-8") # Base16 Encode the bytes e = base64.b16encode(b) # Decoding the Base16 bytes to string s1 = e.decode("UTF-8") # Printing Base16 encoded string print("Base16 Encoded:", s1) # Encoding the Base16 encoded string into bytes b1 = s1.encode("UTF-8") # Decoding the Base16 bytes d = base64.b16decode(b1) # Decoding the bytes to string s2 = d.decode("UTF-8") print(s2)
    • 346. 281 import base64 # Creating a string s = "Hello World!" # Encoding the string into bytes b = s.encode("UTF-8") # Base85 Encode the bytes e = base64.b85encode(b) # Decoding the Base85 bytes to string s1 = e.decode("UTF-8") # Printing Base85 encoded string print("Base85 Encoded:", s1) # Encoding the Base85 encoded string into bytes b1 = s1.encode("UTF-8") # Decoding the Base85 bytes d = base64.b85decode(b1) # Decoding the bytes to string s2 = d.decode("UTF-8") print(s2) Base85 Encoded: NM&qnZy;B1a%^NF Hello World! decodificación base64.b85encode() son base64.b85encode() y base64.b85decode() : que produce lo siguiente:
    • 347. 282 import locale locale.setlocale(locale.LC_ALL, '') Out[2]: 'English_United States.1252' locale.currency(762559748.49) Out[3]: '$762559748.49' locale.currency(762559748.49, grouping=True) Out[4]: '$762,559,748.49' Capítulo 64: El módulo de configuración regional Observaciones Python 2 Docs: [ https://docs.python.org/2/library/locale.html#locale.currency◆ [ ]] Examples Formato de moneda Dólares estadounidenses utilizando el módulo de configuración regional
    • 348. 283 os.mkdir('newdir') os.mkdir('newdir', mode=0700) print(os.getcwd()) os.name Capítulo 65: El módulo os Introducción Este módulo proporciona una forma portátil de utilizar la funcionalidad dependiente del sistema operativo. Sintaxis • importación OS Parámetros Parámetro Detalles Camino Una ruta a un archivo. El separador de ruta puede ser determinado por os.path.sep . Modo El permiso deseado, en octal (por ejemplo, 0700 ) Examples Crear un directorio Si necesita especificar permisos, puede usar el argumento de mode opcional: Obtener directorio actual Utilice la función os.getcwd() : Determinar el nombre del sistema operativo. El módulo os proporciona una interfaz para determinar en qué tipo de sistema operativo se está ejecutando actualmente el código.
    • 349. 284 os.rmdir(path) print(os.readlink(path_to_symlink)) os.chmod(path, mode) import os os.makedirs("./dir2/subdir1") os.makedirs("./dir2/subdir2") ├── dir1 │ ├── subdir1 Esto puede devolver uno de los siguientes en Python 3: • posix • nt • ce • java Se puede obtener información más detallada de sys.platform Eliminar un directorio Eliminar el directorio en la path : No debe usar os.remove() para eliminar un directorio. Esa función es para archivos y su uso en directorios resultará en un OSError Seguir un enlace simbólico (POSIX) A veces es necesario determinar el objetivo de un enlace simbólico. os.readlink hará esto: Cambiar permisos en un archivo donde mode es el permiso deseado, en octal. makedirs - creación de directorio recursivo Dado un directorio local con los siguientes contenidos: Queremos crear el mismo subdir1, subdir2 bajo un nuevo directorio dir2, que aún no existe. Ejecutando estos resultados en └── dir1 ├── subdir1 └── subdir2
    • 350. 285 os.mkdir("./dir2/subdir1") OSError: [Errno 2] No such file or directory: './dir2/subdir1' OSError: [Errno 17] File exists: './dir2/subdir1' try: os.makedirs("./dir2/subdir1") except OSError: if not os.path.isdir("./dir2/subdir1"): raise try: os.makedirs("./dir2/subdir2") except OSError: if not os.path.isdir("./dir2/subdir2"): raise dir2 solo se crea la primera vez que se necesita, para la creación de subdir1. Si hubiéramos usado os.mkdir en su lugar, habríamos tenido una excepción porque dir2 no habría existido todavía. os.makedirs no le gustará si el directorio de destino ya existe. Si lo volvemos a ejecutar de nuevo: Sin embargo, esto podría solucionarse fácilmente detectando la excepción y comprobando que el directorio se haya creado. │ └── subdir2 └── dir2 ├── subdir1 └── subdir2
    • 351. 286 import gzip import os outfilename = 'example.txt.gz' output = gzip.open(outfilename, 'wb') try: output.write('Contents of the example file go here.\n') finally: output.close() print outfilename, 'contains', os.stat(outfilename).st_size, 'bytes of compressed data' os.system('file -b --mime %s' % outfilename) $ python gzip_write.py application/x-gzip; charset=binary example.txt.gzcontains68bytesofcompresseddata Capítulo 66: Empezando con GZip Introducción Este módulo proporciona una interfaz simple para comprimir y descomprimir archivos al igual que los programas GNU gzip y gunzip. La compresión de datos es proporcionada por el módulo zlib. El módulo gzip proporciona la clase GzipFile que se modela después del objeto File de Python. La clase GzipFile lee y escribe archivos en formato gzip, comprimiendo o descomprimiendo automáticamente los datos para que se parezca a un objeto de archivo normal. Examples Lee y escribe archivos zip de GNU Guárdelo como 1gzip_write.py1. Ejecútelo a través del terminal.
    • 352. 287 from socket import socket, AF_INET, SOCK_DGRAM s = socket(AF_INET, SOCK_DGRAM) msg = ("Hello you there!").encode('utf-8') # socket.sendto() takes bytes as input, hence we must encode the string first. s.sendto(msg, ('localhost', 6667)) Capítulo 67: Enchufes Introducción Muchos lenguajes de programación usan sockets para comunicarse a través de procesos o entre dispositivos. Este tema explica el uso correcto del módulo de sockets en Python para facilitar el envío y la recepción de datos a través de protocolos de red comunes. Parámetros Parámetro Descripción socket.AF_UNIX Unix Socket socket.AF_INET IPv4 socket.AF_INET6 IPv6 socket.SOCK_STREAM TCP socket.SOCK_DGRAM UDP Examples Envío de datos a través de UDP UDP es un protocolo sin conexión. Los mensajes a otros procesos o computadoras se envían sin establecer ningún tipo de conexión. No hay confirmación automática si su mensaje ha sido recibido. UDP se utiliza generalmente en aplicaciones sensibles a la latencia o en aplicaciones que envían transmisiones de toda la red. El siguiente código envía un mensaje a un proceso que escucha en el puerto de host local 6667 usando UDP Tenga en cuenta que no es necesario "cerrar" el socket después del envío, ya que UDP no tiene conexión . Recepción de datos a través de UDP
    • 353. 288 from socket importsocket, AF_INET, SOCK_DGRAM sock = socket(AF_INET, SOCK_DGRAM) sock.bind(('localhost', 6667)) while True: msg, addr = sock.recvfrom(8192) # This is the amount of bytes to read at maximum print("Got message from %s: %s" % (addr, msg)) from socketserver import BaseRequestHandler, UDPServer class MyHandler(BaseRequestHandler): def handle(self): print("Got connection from: %s" % self.client_address) msg, sock = self.request print("It said: %s" % msg) sock.sendto("Got your message!".encode(), self.client_address) # Send reply serv = UDPServer(('localhost', 6667), MyHandler) serv.serve_forever() from socket import socket, AF_INET, SOCK_STREAM s = socket(AF_INET, SOCK_STREAM) s.connect(('localhost', 6667)) # The address of the TCP server listening s.send(b'Hello') s.close() UDPes unprotocolosin conexión.Esto significaquelos paresqueenvían mensajes norequieren establecer una conexión antes de enviar mensajes. socket.recvfrom devuelve una tupla ( msg [el mensaje que recibió el socket], addr [la dirección delremitente]) Un servidor UDP que utiliza únicamente el módulo de socket : A continuación se muestra una implementación alternativa utilizando socketserver.UDPServer : Por defecto, los sockets bloquean. Esto significa que la ejecución del script esperará hasta que el socket reciba datos. Envío de datos a través de TCP El envío de datos a través de Internet es posible mediante múltiples módulos. El módulo de sockets proporciona acceso de bajo nivel a las operaciones subyacentes del sistema operativo responsables de enviar o recibir datos de otras computadoras o procesos. El siguiente código envía la cadena de bytes b'Hello' a un servidor TCP que escucha en el puerto 6667 en el host local y cierra la conexión cuando termina: La salida del zócalo está bloqueando de forma predeterminada, lo que significa que el programa esperará en la conexión y enviará las llamadas hasta que la acción se complete. Para la conexión eso significa que el servidor realmente acepta la conexión. Para enviar, solo significa que el sistema operativo tiene suficiente espacio de almacenamiento para poner en cola los datos que se enviarán más tarde.
    • 354. 289 import argparse import json import socket import threading def handle_client(client_list, conn, address): name = conn.recv(1024) entry = dict(zip(['name', 'address', 'port'], [name, address[0], address[1]])) client_list[name] = entry conn.sendall(json.dumps(client_list)) conn.shutdown(socket.SHUT_RDWR) conn.close() def server(client_list): print "Starting server..." s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('127.0.0.1', 5000)) s.listen(5) while True: (conn, address) = s.accept() t = threading.Thread(target=handle_client, args=(client_list, conn, address)) t.daemon = True t.start() def client(name): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 5000)) s.send(name) data = s.recv(1024) result = json.loads(data) print json.dumps(result, indent=4) def parse_arguments(): parser = argparse.ArgumentParser() parser.add_argument('-c', dest='client', action='store_true') parser.add_argument('-n', dest='name', type=str, default='name') result = parser.parse_args() return result def main(): client_list = dict() Los enchufes siempre deben estar cerrados después de su uso. Servidor de socket TCP multihilo Cuando se ejecuta sin argumentos, este programa inicia un servidor de socket TCP que escucha las conexiones a 127.0.0.1 en el puerto 5000 . El servidor maneja cada conexión en un hilo separado. Cuando se ejecuta con el argumento -c , este programa se conecta al servidor, lee la lista de clientes y la imprime. La lista de clientes se transfiere como una cadena JSON. El nombre del cliente puede especificarse pasando el argumento -n . Al pasar nombres diferentes, se puede observar el efecto en la lista de clientes. client_list.py
    • 355. 290 $ python client_list.py Starting server... $ python client_list.py -c -n name1 { "name1": { "address": "127.0.0.1", "port": 62210, "name": "name1" } } ValueError: Unterminated string starting at: line 1 column 1023 (char 1022) sudo ethtool -K eth1 tx off #!/usr/bin/env python from socket import socket, AF_PACKET, SOCK_RAW s = socket(AF_PACKET, SOCK_RAW) s.bind(("eth1", 0)) # We're putting together an ethernet frame here, # but you could have anything you want instead # Have a look at the 'struct' module for more # flexible packing/unpacking of binary data # and 'binascii' for 32 bit CRC src_addr = "\x01\x02\x03\x04\x05\x06" Salida del servidor Salida de cliente Los buffers de recepción están limitados a 1024 bytes. Si la representación de la cadena JSON de la lista de clientes supera este tamaño, se truncará. Esto hará que se genere la siguiente excepción: Raw Sockets en Linux Primero desactivas la suma de comprobación automática de tu tarjeta de red: Luego envíe su paquete, utilizando un socket SOCK_RAW: args= parse_arguments() if args.client: client(args.name) else: try: server(client_list) except KeyboardInterrupt: print "Keyboard interrupt" if name == ' main ': main()
    • 356. 291 dst_addr = "\x01\x02\x03\x04\x05\x06" payload = ("["*30)+"PAYLOAD"+("]"*30) checksum = "\x1a\x2b\x3c\x4d" ethertype = "\x08\x01" s.send(dst_addr+src_addr+ethertype+payload+checksum)
    • 357. 292 $ pip install virtualenvwrapper $ export WORKON_HOME=~/Envs $ mkdir -p $WORKON_HOME $ source /usr/local/bin/virtualenvwrapper.sh $ printf '\n%s\n%s\n%s' '# virtualenv' 'export WORKON_HOME=~/virtualenvs' 'source /home/salayhin/bin/virtualenvwrapper.sh' >> ~/.bashrc $ source ~/.bashrc $ mkvirtualenv python_3.5 Installing setuptools.......................................... .................................................... .................................................... Capítulo 68: entorno virtual con virtualenvwrapper Introducción Supongamos que necesita trabajar en tres proyectos diferentes. El proyecto A, el proyecto B y el proyecto C. el proyecto A y el proyecto B necesitan Python 3 y algunas bibliotecas requeridas. Pero para el proyecto C necesitas Python 2.7 y bibliotecas dependientes. Así que la mejor práctica para esto es separar esos entornos de proyecto. Para crear un entorno virtual puedes usar la siguiente técnica: Virtualenv, Virtualenvwrapper y Conda Aunque tenemos varias opciones para el entorno virtual, se recomienda virtualenvwrapper. Examples Crear entorno virtual con virtualenvwrapper Supongamos que necesita trabajar en tres proyectos diferentes. El proyecto A, el proyecto B y el proyecto C. el proyecto A y el proyecto B necesitan Python 3 y algunas bibliotecas requeridas. Pero para el proyecto C necesitas Python 2.7 y bibliotecas dependientes. Así que la mejor práctica para esto es separar esos entornos de proyecto. Para crear un entorno virtual puedes usar la siguiente técnica: Virtualenv, Virtualenvwrapper y Conda Aunque tenemos varias opciones para el entorno virtual, se recomienda virtualenvwrapper. Aunque tenemos varias opciones para el entorno virtual, siempre prefiero virtualenvwrapper porque tiene más facilidad que otras.
    • 358. 293 (python_3.5)$ pip install django Downloading/unpacking django Downloading Django-1.1.1.tar.gz (5.6Mb): 5.6Mb downloaded Running setup.py egg_info for package django Installing collected packages: django Running setup.py install for django changing mode of build/scripts-2.6/django-admin.py from 644 to 755 changing mode of /Users/salayhin/Envs/env1/bin/django-admin.py to 755 Successfully installed django (python_3.5)$ lssitepackages Django-1.1.1-py2.6.egg-info easy-install.pth setuptools-0.6.10-py2.6.egg pip-0.6.3-py2.6.egg django setuptools.pth $ deactivate Ahora podemos instalar algún software en el entorno. Podemos ver el nuevo paquete con lssitepackages: Podemos crear múltiples entornos virtuales si queremos. Cambiar entre entornos con workon: Para salir del virtualenv (python_3.6)$ workon python_3.5 (python_3.5)$ echo $VIRTUAL_ENV /Users/salayhin/Envs/env1 (python_3.5)$ ...............................done. virtualenvwrapper.user_scripts Creating /Users/salayhin/Envs/python_3.5/bin/predeactivate virtualenvwrapper.user_scripts Creating /Users/salayhin/Envs/python_3.5/bin/postdeactivate virtualenvwrapper.user_scripts Creating /Users/salayhin/Envs/python_3.5/bin/preactivate virtualenvwrapper.user_scripts Creating /Users/salayhin/Envs/python_3.5/bin/postactivate New python executable in python_3.5/bin/python (python_3.5)$ ls $WORKON_HOME python_3.5 hook.log
    • 359. 294 $ pip install virtualenv Capítulo 69: Entornos virtuales Introducción Un entorno virtual es una herramienta para mantener las dependencias requeridas por diferentes proyectos en lugares separados, mediante la creación de entornos virtuales de Python para ellos. Resuelve el "Proyecto X depende de la versión 1.x, pero, el Proyecto Y necesita el problema 4.x", y mantiene el directorio global de paquetes de sitios limpio y manejable. Esto ayuda a aislar sus entornos para diferentes proyectos entre sí y de las bibliotecas de su sistema. Observaciones Los entornos virtuales son lo suficientemente útiles como para ser usados en cada proyecto. En particular, los entornos virtuales le permiten: 1. Gestionar dependencias sin necesidad de acceso root. 2. Instale diferentes versiones de la misma dependencia, por ejemplo, al trabajar en diferentes proyectos con diferentes requisitos 3. Trabaja con diferentes versiones de python. Examples Creando y utilizando un entorno virtual. virtualenvesunaherramientaparaconstruirentornosPythonaislados.Esteprogramacreauna carpetaquecontienetodoslosejecutablesnecesariosparausarlospaquetesqueunproyectode Python necesitaría. Instalando la herramienta virtualenv Esto solo se requiere una vez. El programa virtualenv puede estar disponible a través de su distribución. En las distribuciones similares a Debian, el paquete se llama python-virtualenv o python3-virtualenv . Alternativamente, puede instalar virtualenv usando pip : Creando un nuevo entorno virtual.
    • 360. 295 $ virtualenv foo $ source foo/bin/activate $ foo\Scripts\activate.bat # Installs 'requests' to foo only, not globally (foo)$ pip install requests (foo)$ pip freeze > requirements.txt (foo)$ pip install -r requirements.txt Esto solo se requiere una vez por proyecto. Al iniciar un proyecto para el que desea aislar dependencias, puede configurar un nuevo entorno virtual para este proyecto: Estocrearáunacarpetafoocontienescriptsdeherramientasyunacopiadelpropiobinariode python .El nombre de la carpeta no es relevante. Una vez que se crea el entorno virtual, es autónomo y no requiere más manipulación con la herramienta virtualenv .Ahora puedes empezar a utilizar el entorno virtual. Activando un entorno virtual existente Para activar un entorno virtual, se requiere algo de shell magic, por lo que su Python es el que está dentro de foo lugar del sistema. Este es el propósito del archivo de activate , que debe fuente en su shell actual: Los usuarios de Windows deben escribir: Una vez que se ha activado un entorno virtual, los archivos binarios de python y pip y todos los scripts instalados por módulos de terceros son los que están dentro de foo . En particular, todos los módulos instalados con pip se implementarán en el entorno virtual, lo que permite un entorno de desarrollo contenido. La activación del entorno virtual también debe agregar un prefijo a su solicitud como se ve en los siguientes comandos. Guardar y restaurar dependencias. Para guardarlos módulos que ha instalado a través de pip , puede enumerar todos esos módulos (y las versiones correspondientes) en un archivo de texto usando el comando freeze . Esto permite a otros instalar rápidamente los módulos de Python necesarios para la aplicación mediante el comando de instalación. El nombre convencional para tal archivo es requirements.txt : Tenga en cuenta quela freeze enumera todos los módulos,incluidas las dependencias transitivas requeridasporlos módulosdenivel superior queinstaló manualmente.Como tal, es posibleque prefieren elaborar el requirements.txt archivo a mano , por poner sólo los módulos de alto nivel
    • 361. 296 (foo)$ deactivate import os mydir = os.path.dirname(os.path.realpath( file )) activate_this = mydir + '/bin/activate_this.py' execfile(activate_this, dict( file =activate_this)) $ pyvenv foo $ source foo/bin/activate que necesita. Salir de un entorno virtual. Si ha terminado de trabajar en el entorno virtual, puede desactivarlo para volver a su shell normal: Usando un entorno virtual en un host compartido A veces no es posible $ source bin/activate un virtualenv, por ejemplo, si está utilizando mod_wsgi en un host compartido osi no tiene acceso a un sistema de archivos, como en Amazon APIGateway oGoogleAppEngine.Para esos casos, puede implementarlas bibliotecasque instaló en su virtualenv local y parchear su sys.path. Luckly virtualenv viene con un script que actualiza tanto su sys.path como su sys.prefix Debe agregar estas líneas al principio del archivo que ejecutará su servidor. Encontraráelarchivobin/activate_this.pyvirtualenvquevirtualenvcreóenelmismodirectorio que está ejecutando y agregará lib/python2.7/site-packages a sys.path Si ustedestábuscandoparautilizar el activate_this.py guión, recuerde quedebedesplegarcon, al menos, el bin y lib/python2.7/site-packages directorios y sus contenidos. Python 3.x 3.3 Entornos virtuales incorporados A partir de Python 3.3, el módulo venv creará entornos virtuales. El comando pyvenv no necesita instalarse por separado: o
    • 362. 297 (<Virtualenv Name) $ which python /<Virtualenv Directory>/bin/python (Virtualenv Name) $ which pip /<Virtualenv Directory>/bin/pip /<Virtualenv Directory>/lib/python2.7/site-packages/ requests==2.10.0 # Install packages from requirements.txt pip install -r requirements.txt #Get a list ofinstalled packages pip freeze # Output list of packages and versions into a requirement.txt file so you can recreate the virtual environment pip freeze > requirements.txt Instalación de paquetes en un entorno virtual Una vez que se haya activado su entorno virtual, cualquier paquete que instale ahora se instalará en virtualenv y no de manera global. Por lo tanto, los nuevos paquetes pueden ser sin necesidad de privilegios de root. Para verificar que los paquetes se están instalando en el virtualenv ejecute el siguiente comando para verificar la ruta del ejecutable que se está utilizando: Cualquierpaquetequeseinstaleutilizandopipseinstalaráenel virtualenvenel siguiente directorio: Alternativamente, puede crear un archivo con los paquetes necesarios. requisitos.txt : Ejecutando: Instalaré la versión 2.10.0 de las requests paquetes. También puede obtener una lista de los paquetes y sus versiones instaladas actualmente en el entorno virtual activo: Alternativamente, no tiene que activar su entorno virtual cada vez que tenga que instalar un paquete. Puede usar directamente el ejecutable pip en el directorio del entorno virtual para instalar paquetes. $ python3 -m venv foo $ source foo/bin/activate
    • 363. 298 virtualenv -p python3 foo virtualenv --python=python3 foo python3 -m venv foo pyvenv foo Puede encontrar más información sobre el uso de pip en el tema PIP . Dado que está instalando sin root en un entorno virtual, esto no es una instalación global en todo el sistema: el paquete instalado solo estará disponible en el entorno virtual actual. Creando un entorno virtual para una versión diferente de python Suponiendo que python y python3 estén instalados, es posible crear un entorno virtual para Python 3, incluso si python3 no es el Python predeterminado: o o o En realidad, puede crear un entorno virtual basado en cualquier versión de Python en funcionamiento de su sistema. Puede consultar diferentes python de trabajo en /usr/bin/ o /usr/local/bin/ (En Linux) O en /Library/Frameworks/Python.framework/Versions/XX/bin/ (OSX), luego descifre la --python y usa eso en la --python o -p al crear un entorno virtual. Gestionar múltiples entornos virtuales con virtualenvwrapper La utilidad virtualenvwrapper simplifica el trabajo con entornos virtuales y es especialmente útil si está tratando con muchos proyectos / entornos virtuales. Enlugar de tener que lidiar con los directorios del entorno virtual, virtualenvwrapper administra por usted, almacenando todoslos entornos virtuales en undirectoriocentral( ~/.virtualenvs por defecto). Instalación Instale virtualenvwrapper con el administrador de paquetes de su sistema. Basado en Debian / Ubuntu: apt-get install virtualenvwrapper $ /<Virtualenv Directory>/bin/pip install requests
    • 364. 299 yum install python-virtualenvrwapper pacman -S python-virtualenvwrapper pip install virtualenvwrapper mkvirtualenv my-project mkvirtualenv --system-site-packages my-project workon my-project mkvirtualenv -a /path/to/my-project my-project workon my-project cd /path/to/my-project Fedora / CentOS / RHEL: Arch Linux: O instálalo desde PyPI usando pip : Bajo Windows, puedes usar virtualenvwrapper-win o virtualenvwrapper-powershell en virtualenvwrapper-powershell lugar. Uso Los entornos virtuales se crean con mkvirtualenv . Todos los argumentosdel comando virtualenv original también son aceptados. o por ejemplo El nuevo entorno virtual se activa automáticamente. En nuevos shells puede habilitar el entorno virtual con workon La ventaja del comando workon comparado con el tradicional . path/to/my-env/bin/activate es que el comando workon funcionará en cualquier directorio; no tiene que recordar en qué directorio está almacenado el entorno virtual particular de su proyecto. Directorios de proyectos Incluso puede especificarundirectoriode proyecto durantelacreacióndelentornovirtualconla opción -a o más adelante con el comandosetvirtualenvproject . o
    • 365. 300 (my-project-env) user@hostname:~$ which python /home/user/my-project-env/bin/python #!/usr/bin/python #!/usr/bin/env python chmod +x myscript.py La configuración de un proyecto hará que el comando workon cambie al proyecto automáticamente y habilite el comando cdproject que le permite cambiar al directorio del proyecto. Paraver unalistade todos los virtualenvsgestionadospor virtualenvwrapper,use lsvirtualenv . Para eliminar un virtualenv, use rmvirtualenv : Cadavirtualenv administradoporvirtualenvwrapperincluye 4scripts debashvacíos: preactivate , postactivate , predeactivate y postdeactivate . Estos sirven como enlaces para ejecutar comandos bash en ciertos puntos del ciclo de vida de virtualenv; por ejemplo, cualquier comando en el script postactivateseejecutará justodespués deque se active virtualenv. Estesería unbuen lugar para establecer variables de entorno especiales, alias o cualquier otra cosa relevante.Los 4 scripts se encuentran en .virtualenvs/<virtualenv_name>/bin/ . Para más detalles lea la documentación de virtualenvwrapper . Descubrir qué entorno virtual está utilizando Si está utilizando el indicador de bash predeterminado en Linux, debería ver el nombre del entorno virtual al inicio de su indicador. Especificando la versión específica de Python para usar en el script en Unix/ Linux Para especificar qué versión de python el shell de Linux debe usar, la primera línea de scripts de Python puede ser una línea shebang, que comienza con #! : Si está en un entorno virtual, entonces python myscript.py Python usará Python de su entorno virtual, pero ./myscript.py usará el intérprete dePython en el #! línea. Para asegurarse de quese utiliza Python del entorno virtual, cambie la primera línea a: Después de especificar la línea shebang, recuerde dar permisos de ejecución al script haciendo lo siguiente: rmvirtualenv my-project setvirtualenvproject
    • 366. 301 sudo pip install virtualfish $ echo "eval (python -m virtualfish)" > ~/.config/fish/config.fish if set -q VIRTUAL_ENV echo -n -s (set_color -b blue white) "(" (basename "$VIRTUAL_ENV") ")" (set_color normal) " " end funcsave fish_prompt vf new my_new_env # Make sure $HOME/.virtualenv exists vf new -p python3 my_new_env Hacerestolepermitirá ejecutar elscript ejecutando./myscript.py (oproporcionará laruta absoluta al script) en lugar de python myscript.py o python3 myscript.py . Usando virtualenv con cáscara de pescado Fish Shell es más amigable, pero es posible que tengas problemas al usar virtualenv o virtualenvwrapper . Alternativamente existe el virtualfish para el rescate. Simplemente siga la secuencia a continuación para comenzar a usar Fish Shell con virtualenv. • Instalar virtualfish en el espacio global • Cargue el módulo virtual de python durante el inicio de shell de peces. • Edite esta función fish_prompt con $ funced fish_prompt --editor vim y agregue las líneas siguientes y cierre el editorvim Nota:Si noestá familiarizado convim,simplementesuministre asueditorfavorito como este $ funced fish_prompt --editor nano o $ funced fish_prompt --editor gedit • Guardar cambios utilizando funcsave • Para crear un nuevo entorno virtual usa vf new • Si desea crear un nuevo entorno python3, especifíquelo mediante el indicador -p • Para cambiar entre entornos virtuales, use vf deactivate y vf activate another_env Enlaces oficiales: • https://github.com/adambrenecki/virtualfish • http://virtualfish.readthedocs.io/en/latest/ Realización de entornos virtuales utilizando Anaconda.
    • 367. 302 conda create --name <envname> python=<version> # Linux, Mac source activate <envname> source deactivate # Windows activate <envname> deactivate conda env list conda env remove -n <envname> import sys sys.prefix sys.real_prefix Una poderosa alternativa a virtualenv es Anaconda : un administrador de paquetes multiplataforma, similar a pip , con características para crear y eliminar rápidamente entornos virtuales. Después de instalar Anaconda, aquí hay algunos comandos para comenzar: Crear un entorno donde <envname> en un nombre arbitrario para su entorno virtual, y <version> es una versión específica de Python que desea configurar. Activa y desactiva tu entorno. o Ver una lista de entornos creados. Eliminar un entorno Encuentra más comandos y características en la documentación oficial de conda . Comprobando si se ejecuta dentro de un entorno virtual A veces, el indicador de comandos de la shell no muestra el nombre del entorno virtual y quiere estar seguro de si está en un entorno virtual o no. Ejecuta el intérprete de python y prueba: • Fuera de un entorno virtual, sys.prefix apuntará a la instalación de python del sistema y sys.real_prefix no está definido.
    • 368. 303 • Dentrode unentorno virtual,sys.prefixapuntaráa lainstalaciónde pythondel entorno virtual y sys.real_prefix apuntará a la instalación de python delsistema. Para los entornos virtuales creados con el módulo venv de la biblioteca estándar , no hay sys.real_prefix . En su lugar, compruebe si sys.base_prefix es el mismo que sys.prefix .
    • 369. 304 foo = raw_input("Put a message here that asks the user for input") foo = input("Put a message here that asks the user for input") print("This string will be displayed in the output") # This string will be displayed in the output print("You can print \n escape characters too.") # You can print escape characters too. print "This string will be displayed in the output" # This string will be displayed in the output print "You can print \n escape characters too." # You can print escape characterstoo. Capítulo 70: Entrada y salida básica Examples Usando input () y raw_input () Python 2.x 2.3 raw_input esperará a que el usuario ingrese texto y luego devuelva el resultado como una cadena. En el ejemplo anterior, foo almacenará cualquier entrada que proporcione el usuario. Python 3.x 3.0 input esperará a que el usuario ingrese texto y luego devuelva el resultado como una cadena. En el ejemplo anterior, foo almacenará cualquier entrada que proporcione el usuario. Usando la función de impresión Python 3.x 3.0 En Python 3, la funcionalidad de impresión tiene la forma de una función: Python 2.x 2.3 En Python 2, la impresión fue originalmente una declaración, como se muestra a continuación. Nota: el uso from future import print_function en Python 2 permitirá a los usuarios usar la función print() igual que el código de Python 3. Esto solo está disponible en Python 2.6 y superior.
    • 370. 305 def input_number(msg, err_msg=None): while True: try: return float(raw_input(msg)) except ValueError: if err_msg is not None: print(err_msg) def input_number(msg, err_msg=None): while True: try: return float(input(msg)) except ValueError: if err_msg is not None: print(err_msg) user_number = input_number("input a number: ", "that's not a number!") user_number = input_number("input a number: ") print "Hello,", print "World!" # Hello, World! print("Hello, ", end="\n") print("World!") # Hello, # World! Función para pedir al usuario un número Y para usarlo: O, si no desea un "mensaje de error": Imprimir una cadena sin una nueva línea al final Python 2.x 2.3 En Python 2.x, para continuar una línea con la print , finalice la declaración de print con una coma. Se agregará automáticamente un espacio. Python 3.x 3.0 EnPython 3.x, la función de print tiene un parámetro end opcional que es lo que se imprimeal finaldelacadenadada.Pordefectoesuncarácterdenuevalínea,porloqueesequivalentea esto: Pero podrías pasar en otras cuerdas.
    • 371. 306 import sys sys.stdout.write("Hello, ") sys.stdout.write("World!") # Hello, World! import sys for line in sys.stdin: print(line) $ cat myfile | python myprogram.py Si desea más control sobre la salida, puede usar sys.stdout.write : Leer de stdin Los programas de Python pueden leer desde las tuberías de Unix . Aquí hay un ejemplo simple de cómo leer desde stdin : Tengaencuentaquesys.stdinesunasecuencia.Estosignificaqueelfor-loopsoloterminará cuando la secuencia haya finalizado. Ahora puede canalizar la salida de otro programa a su programa python de la siguiente manera: En este ejemplo, cat myfile puede ser cualquier comando de Unix que salga a stdout . Alternativamente, usar el módulo fileinput puede ser útil: Entrada desde un archivo La entrada también se puede leer desde archivos. Los archivos se pueden abrir utilizando la función incorporada open . Usar un with <command> as <name> sintaxis with <command> as <name> (llamado 'Administrador de contexto') hace queel uso de open y el manejo del archivo sea súper fácil: import fileinput for line in fileinput.input(): process(line) print("Hello, ", end="") print("World!") # Hello, World! print("Hello, ",end="<br>") print("World!") # Hello, <br>World! print("Hello, ", end="BREAK") print("World!") # Hello, BREAKWorld!
    • 372. 307 # let's create an example file: with open('shoppinglist.txt', 'w') as fileobj: fileobj.write('tomato\npasta\ngarlic') with open('shoppinglist.txt', 'r') as fileobj: #thismethodmakes a list where each line # of the file is an element in the list lines = fileobj.readlines() print(lines) # ['tomato\n', 'pasta\n', 'garlic'] with open('shoppinglist.txt', 'r') as fileobj: # here we read the whole content into one string: content = fileobj.read() # get a list of lines, just like int the previous example: lines = content.split('\n') print(lines) # ['tomato', 'pasta', 'garlic'] with open('shoppinglist.txt', 'r') as fileobj: # this method reads line by line: lines = [] for line in fileobj: lines.append(line.strip()) Esto asegura que cuando la ejecución del código deja el bloque, el archivo se cierre automáticamente. Los archivos se pueden abrir en diferentes modos. En el ejemplo anterior, el archivo se abre como de solo lectura. Para abrir un archivo existente para lectura solamente use r .Si quieres leerese archivo como bytes usa rb .Para adjuntar datos a un archivo existente use aarchivo. Use w para crearun archivoosobrescribir cualquierarchivoexistentedel mismonombre.Puedesusar r+ para abrir un archivo para leer y escribir. El primer argumento de open() es el nombre del archivo, el segundo es el modo.Si el modo se deja en blanco, el valor predeterminado será r . Si el tamaño del archivo es pequeño, es seguro leer todo el contenido del archivo en la memoria. Si el archivo es muy grande, a menudo es mejor leer línea por línea o por fragmentos, y procesar la entrada en el mismo bucle. Para hacer eso: Alleerarchivos,tengaencuentaloscaracteresdesaltodelíneaespecíficosdelsistema operativo. Aunque for line in fileobj los for line in fileobj automáticamente, siempre es seguro llamar a strip() en las líneas leídas, como se muestra arriba. Los archivos fileobj ( fileobj en los ejemplos anteriores) siempre apuntan a una ubicación específica en el archivo. Cuando se abren porprimera vez, el identificador de archivo apunta al principio del archivo, que es la posición 0 .El identificador de archivo puede mostrar su posición actual con tell : with open('somefile.txt', 'r') as fileobj: # write code here using fileobj
    • 373. 308 content = fileobj.read() end = fileobj.tell() print('This file was %u characters long.' % end) # This file was 22 characters long. fileobj.close() fileobj = open('shoppinglist.txt', 'r') fileobj.seek(7) pos = fileobj.tell() print('We are at character #%u.' % pos) # reads the next 4 characters # starting at the current position next4 = fileobj.read(4) # what we got? print(next4) # 'cucu' # where we are now? pos = fileobj.tell() print('We are at %u.' % pos) # We are at 11, as we was at 7, and read 4 chars. fileobj.close() with open('shoppinglist.txt', 'r') as fileobj: print(type(fileobj.read())) #<class'str'> with open('shoppinglist.txt', 'rb') as fileobj: print(type(fileobj.read())) # <class 'bytes'> Al leer todo el contenido, la posición del manejador de archivos se señalará al final del archivo: La posición del manejador de archivos se puede configurar para lo que sea necesario: También puede leer cualquier longitud del contenido del archivo durante una llamada determinada. Para hacer esto pasa un argumento para read() . Cuando se llama a read() sin ningúnargumento, se leerá hasta el final del archivo.Si pasa un argumento,leerá ese número de bytes o caracteres, dependiendo del modo ( rb y r respectivamente): Para demostrar la diferencia entre caracteres y bytes: fileobj = open('shoppinglist.txt', 'r') pos = fileobj.tell() print('We are at %u.' % pos) # We are at 0.
    • 374. 309 # Print the working directory import os print os.getcwd() # C:\Python27\Scripts # Set the working directory os.chdir('C:/Users/general1/Documents/simple Python files') print os.getcwd() # C:\Users\general1\Documents\simple Python files # load pandas import pandas as pd # read a csv data file named 'small_dataset.csv' containing 4 lines and 3 variables my_data = pd.read_csv("small_dataset.csv") my_data my_data.shape # (4, 3) # number of rows and columns in data set my_data.shape[0] # 4 # number of rows in data set my_data.shape[1] # 3 # number of columns in data set # Python uses 0-based indexing. The first row or column in a data set is located # at position 0. In R the first row or column in a data set islocated # at position 1. # Select the first two rows my_data[0:2] Capítulo 71: Entrada, subconjunto y salida de archivos de datos externos utilizando Pandas Introducción Esta sección muestra el código básico para leer, sububicar y escribir archivos de datos externos utilizando pandas. Examples Código básico para importar, subcontratar y escribir archivos de datos externos mediante Pandas # x y z # 0 1 2 3 # 1 4 5 6 # 2 7 8 9 # 3 10 11 12 # x y z #0 1 2 3
    • 375. 310 #1 4 5 6 # Select the second and third rows my_data[1:3] # Select the third row my_data[2:3] # Select the first two elements of the first column my_data.iloc[0:2, 0:1] # x # 0 1 # 1 4 # Select the first element of the variables y and z my_data.loc[0, ['y', 'z']] # y 2 # z 3 # Select the first three elements of the variables y and z my_data.loc[0:2, ['y', 'z']] # Write the first three elements of the variables y and z # to an external file. Here index = 0means do not write row names. my_data2 = my_data.loc[0:2, ['y', 'z']] my_data2.to_csv('my.output.csv', index = 0) # x y z # 1 4 5 6 # 2 7 8 9 # x y z #2 7 8 9 # y z # 0 2 3 # 1 5 6 # 2 8 9
    • 376. 311 pip install enum34 from enum import Enum class Color(Enum): red = 1 green = 2 blue = 3 print(Color.red) # Color.red print(Color(1)) # Color.red print(Color['red']) # Color.red class Color(Enum): red = 1 green = 2 blue = 3 [c for c in Color] # [<Color.red: 1>, <Color.green: 2>, <Color.blue: 3>] Capítulo 72: Enumerar Observaciones Las enumeraciones se agregaron a Python en la versión 3.4 por PEP 435 . Examples Creación de una enumeración (Python 2.4 a 3.3) Las enumeraciones se han cargado de Python 3.4 a Python 2.4 a través de Python 3.3. Puede obtener este backport enum34 desde PyPI. La creación de una enumeración es idéntica a cómo funciona en Python 3.4+ Iteración Las enumeraciones son iterables:
    • 377. 312 alist = [0, 1, 2] for index, value in enumerate(alist): alist.pop(index) print(alist) # Out: [1] # Iteration #1 index = 0 alist = [0, 1, 2] alist.pop(0) # removes '0' # Iteration #2 index = 1 alist = [1, 2] alist.pop(1) # removes'2' # loop terminates, but alist is not empty: alist = [1] alist = [1,2,3,4,5,6,7] for index, item in reversed(list(enumerate(alist))): # delete all even items if item % 2 == 0: Capítulo 73: Errores comunes Introducción Python es un lenguaje destinado a ser claro y legible sin ambigüedades ni comportamientos inesperados. Desafortunadamente, estos objetivos no son alcanzables en todos los casos, y es por eso que Python tiene algunos casos de esquina en los que podría hacer algo diferente de lo que esperabas. Esta sección le mostrará algunos problemas que puede encontrar al escribir código Python. Examples Cambiando la secuencia sobre la que estás iterando Un bucle for repite en una secuencia, por lo que alterar esta secuencia dentro del bucle podría generar resultados inesperados (especialmente al agregar o eliminar elementos): Nota: list.pop() se está utilizando para eliminar elementos de la lista. El segundo elemento no se eliminó porque la iteración pasa por los índices en orden. El bucle anterior se repite dos veces, con los siguientes resultados: Este problema surge porque los índices cambian mientras se iteran en la dirección del índice creciente. Para evitar este problema, puede recorrer el bucle hacia atrás :
    • 378. 313 alist = [0, 1, 2] for index, value in enumerate(alist): # break to avoid infinite loop: if index == 20: break alist.insert(index, 'a') print(alist) # Out (abbreviated): ['a', 'a', ..., 'a', 'a', 0, 1, 2] alist = [1,2,3,4] for item in alist: if item % 2 == 0: item = 'even' print(alist) # Out: [1,2,3,4] alist = [1,2,3,4] for index, item in enumerate(alist): if item % 2 == 0: alist[index] = 'even' print(alist) # Out: [1, 'even', 3, 'even'] Al recorrer el bucle que comienza al final, a medida que se eliminan (o agregan) los elementos, no afecta a los índices de los elementos que aparecen anteriormente en la lista. Por lo tanto, este ejemplo eliminará correctamente todos los elementos que sean pares de alist . Un problema similar surge cuando se insertan o agregan elementos a una lista sobre la que está iterando , lo que puede dar lugar a un bucle infinito: Sin la condición de break , el bucle insertaría 'a' siempre que la computadora no se quede sin memoriayelprogramapuedacontinuar.Enunasituacióncomoesta,generalmenteseprefiere crearuna nuevalista y agregar elementos alanuevalista a medida que recorre lalistaoriginal. Cuando se utiliza un bucle for , no puede modificar los elementos de la lista con la variable de marcador de posición : Enel ejemploanterior,cambiar el item no cambia realmente nada en la lista original .Debe usar el índice de alist[2] ( alist[2] ), y enumerate() funciona bien para esto: Un while de bucle podría ser una mejor elección en algunos casos: Si va a eliminar todos los elementos de la lista: zlist = [0, 1, 2] while zlist: alist.pop(index) print(alist) # Out: [1, 3, 5, 7]
    • 379. 314 zlist = [] zlist = [0, 1, 2] x = 1 while len(zlist) > x: print(zlist[0]) zlist.pop(0) print('After: zlist =', zlist) # Out: 0 # 1 # After: zlist = [2] zlist = [1,2,3,4,5] i = 0 while i < len(zlist): if zlist[i] % 2 == 0: zlist.pop(i) else: i += 1 print(zlist) # Out: [1, 3, 5] zlist = [1,2,3,4,5] z_temp = [] Aunque simplemente restablecer zlist logrará el mismo resultado; El ejemplo anterior también se puede combinar con len() para detenerse después de un cierto punto, o para eliminar todos los elementos excepto x en la lista: O para recorrer una lista mientras elimina elementos que cumplen una determinada condición (en este caso, eliminar todos los elementos pares): Observe que no incrementa i después de eliminar un elemento. Al eliminar el elemento en zlist[i],el índicedel siguiente elementoha disminuidoen uno,porloque al marcar zlist[i]con el mismo valor para i en la siguiente iteración, estará verificando correctamente el siguiente elemento en la lista . Una forma contraria de pensar en eliminar elementos no deseados de una lista, es agregar elementos deseados a una nueva lista . El ejemplo siguiente es una alternativa a este último while ejemplo de bucle: print(zlist[0]) zlist.pop(0) print('After: zlist =', zlist) # Out: 0 # 1 # 2 # After: zlist = []
    • 380. 315 zlist = [1,2,3,4,5] [item for item in zlist if item % 2 != 0] # Out: [1, 3, 5] def foo(li=[]): li.append(1) print(li) foo([2]) # Out: [2, 1] foo([3]) # Out: [3, 1] foo() # Out: [1] As expected... foo() # Out: [1, 1] Not as expected... def foo(li=None): if not li: li = [] li.append(1) print(li) foo() # Out: [1] foo() Aquí estamos canalizando los resultados deseados en una nueva lista. De manera opcional, podemos reasignar la lista temporal a la variable original. Con esta tendencia de pensamiento, puede invocar una de las funciones más elegantes y potentes de Python, listas de comprensión , que elimina las listas temporales y se desvía de la ideología de mutación de listas / índices in situ anteriormente discutida. Argumento predeterminado mutable Este código se comporta como se espera, pero ¿y si no pasamos un argumento? Esto se debe a que los argumentos predeterminados de las funciones y los métodos se evalúan en el momento de ladefinición en lugardel tiempo de ejecución.Así que solo tenemos una sola instancia de la lista li . La forma de evitarlo es usar solo tipos inmutables para los argumentos predeterminados: for item in zlist: ifitem % 2 != 0: z_temp.append(item) zlist = z_temp print(zlist) # Out: [1, 3, 5]
    • 381. 316 x = [] foo(li=x) # Out: [1] foo(li="") # Out: [1] foo(li=0) # Out: [1] def foo(li=None): if li is None: li = [] li.append(1) print(li) foo() # Out: [1] li = [[]] * 3 print(li) # Out: [[], [], []] li[0].append(1) print(li) # Out: [[1], [1], [1]] li = [] element = [[]] li=element+element+element print(li) Si bien es una mejora y, if not li se evalúa correctamente como False , muchos otros objetos tambiénlohacen,comolas secuenciasdelongitudcero.Los siguientesargumentosde ejemplo pueden causar resultados no deseados: El enfoque idiomático es verificar directamente el argumento en contra del objeto None : Lista de multiplicación y referencias comunes. Considere el caso de crear una estructura de lista anidada multiplicando: A primera vista, podríamos pensar que tenemos una lista que contiene 3 listas anidadas diferentes. Intentemos adjuntar 1 al primero: 1 obtuve adjunta a todas las listas de li . Larazónesque[[]]* 3nocreaunalistde3listdiferentes.Másbien,creaunalistcontiene 3referenciasalmismoobjetodelist.Comotal,cuandoagregamosali[0]elcambioesvisible en todos los subelementos de li . Esto es equivalente a: # Out: [1]
    • 382. 317 li = [[]] * 3 print([id(inner_list) for inner_list in li]) # Out: [6830760, 6830760, 6830760] li = [[] for _ in range(3)] print([id(inner_list) for inner_list in li]) # Out: [6331048, 6331528, 6331488] >>> li = [] >>> li.append([]) >>> li.append([]) >>> li.append([]) >>> for k in li: print(id(k)) ... 4315469256 4315564552 4315564808 for i in range(len(tab)): print(tab[i]) for elem in tab: print(elem) for i, elem in enumerate(tab): Estosepuedecorroboraraúnmássiimprimimoslasdireccionesdememoriadelalistcontenida usando id : La solución es crear las listas internas con un bucle: En lugar de crear una list única y luego hacer 3 referencias a ella, ahora creamos 3 listas distintas diferentes. Esto, de nuevo, puede verificarse usando la función id : También puedes hacer esto. Hace que se cree una nueva lista vacía en cada llamada append . No utilice el índice para recorrer una secuencia. No hagas Hacer for automatizará la mayoría de las operaciones de iteración para usted. Use enumerar si realmente necesita tanto el índice como el elemento . # Out: [[], [], []] element.append(1) print(li) # Out: [[1], [1], [1]]
    • 383. 318 if (var == True): # this will execute if var is True or 1, 1.0, 1L if (var != True): # this will execute if var is neither True nor 1 if (var == False): # this will execute if var is False or 0 (or 0.0, 0L, 0j) if (var == None): # only execute if var is None if var: # execute if var is a non-empty string/list/dictionary/tuple, non-0, etc if not var: # execute if var is "", {}, [], (), 0, None, etc. if var is True: # only execute if var is boolean True, not 1 if var is False: # only execute if var is boolean False, not 0 if var is None: # same as var == None if os.path.isfile(file_path): file = open(file_path) else: # do something try: file = open(file_path) except OSError as e: # do something with open(file_path) as file: Tenga cuidado al usar "==" para verificar si es verdadero o falso No marque si puede, solo hágalo y maneje el error Los pitonistas usualmente dicen "es más fácil pedir perdón que permiso". No hagas Hacer: O incluso mejor con Python 2.6+ : Es mucho mejor porque es mucho más genérico. Puede aplicar try/except a casi cualquier cosa. print((i, elem))
    • 384. 319 def foo(name): if isinstance(name, str): print(name.lower()) def bar(listing): if isinstance(listing, list): listing.extend((1, 2, 3)) return ", ".join(listing) def foo(name) : print(str(name).lower()) def bar(listing) : l =list(listing) l.extend((1, 2, 3)) return ",".join(l) class Father: pass class Child(Father): pass No necesita preocuparse por lo que debe hacer para evitarlo, solo debe preocuparse por el error que está arriesgando. No comprobar contra tipo Python se escribe dinámicamente, porlotanto,verificarel tipo hacequepierdas flexibilidad.En su lugar, utilicela escritura de patocomprobandoel comportamiento.Si espera una cadena enuna función, use str() para convertir cualquier objeto en una cadena. Si espera una lista, use list() para convertir cualquier iterable en una lista. No hagas Hacer: Usandola última forma, foo aceptará cualquierobjeto. bar aceptará cadenas, tuplas, conjuntos, listas y mucho más. Barato SECO. No mezclar espacios y pestañas Usa el objeto como primer padre Esto es complicado, pero te morderá a medida que tu programa crezca. Hay clases antiguas y nuevas en Python 2.x Los viejos son, bueno, viejos. Carecen de algunas características, y pueden tener un comportamiento incómodo conla herencia.Para ser utilizable, cualquiera de su clase debe ser del "nuevo estilo". Para ello, hazlo heredar del object . No hagas Hacer:
    • 385. 320 class Car(object): color = "red" wheels = [Wheel(), Wheel(), Wheel(), Wheel()] class Car(object): def init (self): self.color = "red" self.wheels = [Wheel(), Wheel(), Wheel(), Wheel()] >>> -8 is (-7 - 1) False >>> -3 is (-2 - 1) True >>> (255 + 1) is (255 + 1) En Python 3.x todas las clases son de estilo nuevo, por lo que no necesitas hacerlo. No inicialice los atributos de clase fuera del método init A las personas que vienen de otros idiomas les resulta tentador porque eso es lo que haces en Java o PHP. Escribe el nombre de la clase, luego enumera sus atributos y les asigna un valor predeterminado. Parece funcionar en Python, sin embargo, esto no funciona como piensas. Al hacerlo, se configurarán los atributos de clase (atributos estáticos), luego, cuando intente obtener el atributo de objeto, le dará su valor a menos que esté vacío. En ese caso devolverá los atributos de la clase. Implica dos grandes peligros: • Si se cambia el atributo de clase, entonces se cambia el valor inicial. • Si configura un objeto mutable como un valor predeterminado, obtendrá el mismo objeto compartido en todas las instancias. No (a menos que quieras estática): Hacer Identidad entera y de cadena Python utiliza el almacenamiento en caché interno para un rango de enteros para reducir la sobrecarga innecesaria de su creación repetida. En efecto, esto puede llevar a un comportamiento confuso al comparar identidades enteras: y, usando otro ejemplo: class Father(object): pass class Child(Father): pass
    • 386. 321 >>> 'python' is 'py' + 'thon' True >>> 'this is not a common string' is 'this is not' + ' a common string' False >>> 'this is not a common string' == 'this is not' + ' a common string' True ¿Esperar lo? PodemosverquelaoperacióndeidentidadisTrueparaalgunosenteros(-3,256)peronopara otros ( -8 , 257 ). Paraser másespecíficos,losenterosenelrango[-5, 256]sealmacenanencaché internamente durante el inicio del intérprete y solo se crean una vez. Como tales, son idénticos y la comparación de sus identidades con is rinde True ; los enteros fuera de este rango son (generalmente) creados sobre la marcha y sus identidades se comparan con False . Este es un error común ya que este es un rango común para las pruebas, pero a menudo, el código falla en el proceso posterior de estadificación (o peor aún, en la producción) sin una razón aparente después de funcionar perfectamente en el desarrollo. Lasolución es comparar siempre los valores utilizando el operador deigualdad ( == ) y no el operador de identidad ( is ). Python también mantiene referencias a los usados comúnmente cuerdas y pueden resultar en un comportamiento de manera similar confuso cuando la comparación de identidades (es decir, utilizando is ) de cadenas. La cadena 'python' se usa comúnmente, por lo que Python tiene un objeto que usan todas las referencias a la cadena 'python' . Para cadenas poco comunes, la comparación de identidad falla incluso cuando las cadenas son iguales. Entonces, al igual que la regla para enteros, siempre compare valores de cadena utilizando el operador de igualdad ( == ) y no el operador de identidad ( is ). Accediendo a los atributos de int literals. Es posible que hayas oído que todo en Python es un objeto, incluso literales. Esto significa, por ejemplo, que 7 es un objeto, lo que significa que tiene atributos. Por ejemplo, uno de estos atributos es el bit_length . Devuelve la cantidad de bits necesarios para representar el valor al que se solicita. True >>> (256 + 1) is (256 + 1) False
    • 387. 322 # parenthesis (7).bit_length() # a space 7 .bit_length() 7.2.as_integer_ratio() # Out: (8106479329266893, 1125899906842624) if a == 3 or b == 3 or c == 3: if a or b or c == 3: # Wrong if a == 3 or b == 3 or c == 3: # Right Way if any([a == 3, b == 3, c == 3]): # Right Al ver que el código anteriorfunciona, podría pensarintuitivamente que 7.bit_length() también funcionaría,soloparadescubrirquegeneraunSyntaxError.¿Porqué?porqueelintérpretedebe diferenciarentreunaccesodeatributoyunnúmeroflotante(porejemplo, 7.2o7.bit_length()). No puede, y es por eso que se levanta una excepción. Hay algunas formas de acceder a los atributos de los literales int : El uso de dos puntos (como este 7..bit_length() ) no funciona en este caso, porque crea un literal float y los flotantes no tienen el método bit_length() . Esteproblemanoexistealaccederalosatributos delosliteralesfloat, yaqueelintérpreteeslo suficientemente "inteligente" para saber que un literal float no puede contener dos . , por ejemplo: Encadenamiento de u operador Al probar para cualquiera de varias comparaciones de igualdad: es tentador abreviar esto a Estoestámal;eloperador ortieneunaprioridadmenorque==,porloquelaexpresiónse evaluarácomoif(a) or(b) or(c ==3):Laformacorrectaesverificandoexplícitamentetodas las condiciones: Alternativamente, la función any() incorporada se puede usar en lugar de encadenados or operadores: O, para hacerlo más eficiente: x = 7 x.bit_length() # Out: 3
    • 388. 323 if 3 in (a, b, c): # Right if a == 1 or 2 or 3: if a in (1, 2, 3): # script.py import sys print(sys.argv[0]) print(sys.argv) $ python script.py => script.py => ['script.py'] $ python script.py fizz => script.py => ['script.py', 'fizz'] $ python script.py fizz buzz => script.py => ['script.py', 'fizz', 'buzz'] myDict = {'first': 1, 'second': 2, 'third': 3} print(myDict) # Out: {'first': 1, 'second': 2, 'third': 3} O, para hacerlo más corto: Aquí, usamos el operador in para probar si el valor está presente en una tupla que contiene los valores con los que queremos comparar. Del mismo modo, es incorrecto escribir que debe ser escrito como sys.argv [0] es el nombre del archivo que se está ejecutando El primer elemento de sys.argv[0] es el nombre del archivo python que se está ejecutando. Los elementos restantes son los argumentos del script. Los diccionarios están desordenados. Puede esperar que un diccionario de Python se ordene por claves como, por ejemplo, un C ++ std::map , pero este no es el caso: if any(x == 3 for x in (a, b, c)): # Right
    • 389. 324 from collections import OrderedDict oDict = OrderedDict([('first', 1), ('second', 2), ('third', 3)]) print([k for k in oDict]) # Out: ['first', 'second', 'third'] def func(**kw): print(kw.keys()) func(a=1, b=2, c=3, d=4, e=5) dict_keys(['a', 'b', 'c', 'd', 'e']) # expected order import math from threading import Thread def calc_fact(num): math.factorial(num) num = 600000 t = Thread(target=calc_fact, daemon=True, args=[num]) print("About to calculate: {}!".format(num)) t.start() print("Calculating...") Python no tiene ninguna clase incorporada que ordene automáticamente sus elementos por clave. Sinembargo, si la ordenación no es obligatoriay solo deseaque sudiccionario recuerde el orden de inserción de sus pares clave / valor, puede usar collections.OrderedDict : Tenga en cuenta que inicializar un OrderedDict con un diccionario estándar no ordenará el diccionario por usted. Todo lo que hace esta estructura es preservar el orden de inserción de la clave. La implementación de los diccionarios se cambió en Python 3.6 para mejorar su consumo de memoria. Un efecto secundario de esta nueva implementación es que también conserva el orden de los argumentos de palabras clave que se pasan a una función: Python 3.x 3.6 Advertencia : tenga en cuenta que " el aspecto de preservar el orden de esta nueva implementación se considera un detalle de implementación y no se debe confiar en él " , ya que puede cambiar en el futuro. Bloqueo global de intérprete (GIL) y bloqueo de hilos Se ha escrito mucho sobre GIL de Python . A veces puede causar confusión cuando se trata de aplicaciones de subprocesos múltiples (no confundir con multiproceso). Aquí hay un ejemplo: print([k for k in myDict]) # Out: ['second', 'third', 'first']
    • 390. 325 i = 0 a = [i for i in range(3)] print(i) # Outputs 2 def calc_fact(num): """ A slow version of factorial in native Python """ res = 1 while num >= 1: res = res * num num -= 1 return res def calc_fact(num): sleep(0.001) math.factorial(num) i = 0 a = [i for i in range(3)] print(i) # Outputs 0 Esperaría ver el Calculating... impreso inmediatamente después de comenzar el hilo, ¡queríamos que el cálculo se realizara en un nuevo hilo después de todo! Pero en realidad, usted ve que se imprime una vez que se completa el cálculo. Esto se debe a que el nuevo hilo se basa en una función C ( math.factorial ) que bloqueará la GIL mientras se ejecuta. Hay un par de maneras de evitar esto. El primero es implementar tu función factorial en Python nativo. Esto permitirá que el hilo principal tome el control mientras estás dentro de tu bucle. El inconveniente es que esta solución será mucho más lenta, ya que ya no estamos utilizando la función C. También puede sleep durante un período de tiempo antes de comenzar su ejecución. Nota: esto no permitirá que su programa interrumpa el cálculo que ocurre dentro de la función C, pero permitirá que su hilo principal continúe después del inicio, que es lo que puede esperar. Fugas variables en listas de comprensión y para bucles. Considere la siguiente lista de comprensión Python 2.x 2.7 Esto ocurre solo en Python 2 debido a que la comprensión de la lista "filtra" la variable de control de bucle en el ámbito circundante ( fuente ). Este comportamiento puede provocar errores difíciles de encontrar y se ha corregido en Python 3 . Python 3.x 3.0 Del mismo modo, para los bucles no tienen ámbito privado para su variable de iteración t.join() print("Calculated")
    • 391. 326 def xyz(): return a, b t = xyz() my_var = 'bla'; api_key = 'key'; ...lots of code here... params = {"language": "en", my_var: api_key} { "language": "en", "my_var": "key" } Este tipo de comportamiento ocurre tanto en Python 2 como en Python 3. Para evitar problemas con las variables con fugas, use nuevas variables en la lista de comprensión y para los bucles, según corresponda. Retorno múltiple La función xyz devuelve dos valores a y b: El código que llama a xyz almacena el resultado en una variable, asumiendo que xyz devuelve solo un valor: Valordetesenrealidadunatupla(a,b)porloquecualquieracciónentsuponiendoquenoes una tupla puede fallarprofundoen el código con un un errorinesperado sobre tuplas. TypeError: el tipo tuple no define ... el método La solución sería hacer: ¡Los principiantes tendrán problemas para encontrar el motivo de este mensaje al solo leer el mensaje de error de la tupla! Teclas JSON pitónicas Siestásacostumbrado aJavaScript,laevaluacióndevariables enlosdiccionarios dePythonno será lo que esperas que sea. Esta declaración en JavaScript daría como resultado el objeto params siguiente manera: a, b = xyz() i = 0 for i in range(3): pass print(i) # Outputs 2
    • 392. 327 { "language": "en", "bla": "key" } En Python, sin embargo, daría como resultado el siguiente diccionario: my_var se evalúa y su valor se utiliza como clave.
    • 393. 328 import csv Capítulo 74: Escribiendo a CSV desde String o List Introducción Escribir en un archivo .csv no es diferente a escribir en un archivo regular en la mayoría de los casos, y es bastante sencillo. De la mejor manera posible, cubriré el enfoque más fácil y eficiente del problema. Parámetros Parámetro Detalles abierto ( "/ ruta /" , "modo") Especifique la ruta a su archivo CSV abierto (ruta, "modo" ) Especifique el modo para abrir el archivo en (lectura, escritura, etc.) csv.writer ( archivo , delimitador) Pase el archivo CSV abierto aquí csv.writer (archivo, delimitador = '' ) Especificar carácter o patrón delimitador Observaciones open( path, "wb") "wb" - Modo de escritura. El parámetro b en "wb" que hemos utilizado, es necesario solo si desea abrirlo en modo binario, que solo se necesita en algunos sistemas operativos como Windows. csv.writer ( csv_file, delimiter=',' ) Aquíeldelimitadorquehemosutilizadoes,porquequeremosquecadaceldadedatosenuna fila,contenga el nombre,el apellidoyla edad respectivamente.Ya que nuestralista está dividida a lo largo de , también, resulta bastante conveniente para nosotros. Examples Ejemplo básico de escritura
    • 394. 329 def append_to_csv(input_string): with open("fileName.csv", "a") as csv_file: csv_file.write(input_row + "\n") Anexando una cadena como nueva línea en un archivo CSV #------ We will write to CSV in this function ------------ def csv_writer(data, path): #Open CSV file whose path we passed. with open(path, "wb") as csv_file: writer = csv.writer(csv_file, delimiter=',') for line in data: writer.writerow(line) #---- Define our list here, and call function ------------ if name == " main ": """ data = our list that we want to write. Split it so we get a list of lists. """ data = ["first_name,last_name,age".split(","), "John,Doe,22".split(","), "Jane,Doe,31".split(","), "Jack,Reacher,27".split(",") ] # Path to CSV file we want to write to. path = "output.csv" csv_writer(data, path)
    • 395. 330 @route("/stream") def stream(): def event_stream(): while True: if message_to_send: yield "data: {}\n\n".format(message_to_send)" return Response(event_stream(), mimetype="text/event-stream") import asyncio import sse class Handler(sse.Handler): @asyncio.coroutine def handle_request(self): yield from asyncio.sleep(2) self.send('foo') yield from asyncio.sleep(2) self.send('bar', event='wakeup') start_server = sse.serve(Handler, 'localhost', 8888) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever() Capítulo 75: Eventos enviados de Python Server Introducción Server Sent Events (SSE) es una conexión unidireccional entre un servidor y un cliente (generalmente un navegador web) que permite al servidor "enviar" información al cliente. Se parece mucho a los websockets y las encuestas largas. La principal diferencia entre SSE y websockets es que SSE es unidireccional, solo el servidor puede enviar información al cliente, mientras que al igual que con websockets, ambos pueden enviarse información entre ellos. Generalmente, se considera que SSE es mucho más simple de usar / implementar que websockets. Examples Frasco SSE Asyncio SSE Este ejemplo utiliza la biblioteca SSE de asyncio: https://github.com/brutasse/asyncio-sse
    • 396. 331 class WrongInputException(Exception): pass def convert2number(random_input): try: my_input = int(random_input) except ValueError: raise WrongInputException("Expected an integer!") return my_input import unittest class ExceptionTestCase(unittest.TestCase): Capítulo 76: Examen de la unidad Observaciones Hayvariasherramientasdepruebadeunidad paraPython.Estetemadedocumentación describe el módulo de unittest básico. Otras herramientas de prueba incluyen py.test y nosetests . Esta documentaciónde pythonsobrepruebas comparavariasde estasherramientas sinprofundizar. Examples Pruebas de excepciones Los programas lanzan errores cuando, por ejemplo, se da una entrada incorrecta. Debido a esto, uno debe asegurarse de que se produce un error cuando se da una entrada incorrecta real. Por eso necesitamos verificar una excepción exacta, para este ejemplo usaremos la siguiente excepción: Esta excepción se genera cuando se proporciona una entrada incorrecta, en el siguiente contexto donde siempre esperamos un número como entrada de texto. Para verificar si se ha generado una excepción, usamos assertRaises para verificar esa excepción. assertRaises se puede utilizar de dos maneras: 1. Usando la llamada de función regular. El primer argumento toma el tipo de excepción, el segundo un llamable (generalmente una función) y el resto de los argumentos se pasan a este llamable. 2. Usar una cláusula with , dando solo el tipo de excepción a la función.Esto tiene la ventaja de que se puede ejecutar más código, pero se debe usar con cuidado ya que múltiples funcionespuedenusarlamismaexcepción,quepuedeserproblemática.Unejemplo: con self.assertRaises (WrongInputException): convert2number ("no es un número") Este primero se ha implementado en el siguiente caso de prueba:
    • 397. 332 def multiply(a, b): return a * b from custom_math import multiply def multiples_of(integer, *args, num_multiples=0, **kwargs): """ :rtype: list """ multiples = [] for x in range(1, num_multiples + 1): """ Passing in args and kwargs here will only raise TypeError if values were passed to multiples_of function, otherwise they are ignored. This way we can test that multiples_of is used correctly. This is here for an illustration of how create_autospec works. Not recommended for production code. """ multiple = multiply(integer,x, *args, **kwargs) multiples.append(multiple) return multiples También puede ser necesario verificar si hay una excepción que no debería haberse lanzado. Sin embargo, una prueba fallará automáticamente cuando se lance una excepción y, por lo tanto, puede que no sea necesaria en absoluto. Solo para mostrar las opciones, el segundo método de prueba muestra un caso sobre cómo se puede verificar que no se produzca una excepción. Básicamente, esto es capturar la excepción y luego fallar la prueba usando el método de fail . Funciones de simulación con unittest.mock.create_autospec Una forma de simular una función es utilizar la función create_autospec , que create_autospec un objeto de acuerdo con sus especificaciones. Con las funciones, podemos usar esto para asegurarnos de que se llamen adecuadamente. Con una función multiply en custom_math.py : Y una función multiples_of en process_math.py : Podemos probar multiples_of solo burlándose de multiply . El siguiente ejemplo utiliza la prueba de unidad de la biblioteca estándar de Python, pero esto también se puede usar con otros marcos de prueba, como pytest o nose: def test_wrong_input_string(self): self.assertRaises(WrongInputException, convert2number, "not a number") def test_correct_input(self): try: result = convert2number("56") self.assertIsInstance(result, int) except WrongInputException: self.fail()
    • 398. 333 import unittest class SomeTest(unittest.TestCase): def setUp(self): super(SomeTest, self).setUp() self.mock_data = [1,2,3,4,5] def test(self): self.assertEqual(len(self.mock_data), 5) def tearDown(self): super(SomeTest, self).tearDown() self.mock_data = [] if name == 'main ': unittest.main() Configuración de prueba y desmontaje dentro de un unittest.TestCase Avecesqueremosprepararuncontextoparacadapruebaqueseejecutará.ElmétododesetUp seejecuta antesdecada prueba enlaclase.tearDown se ejecutaalfinaldecada prueba.Estos métodossonopcionales.RecuerdequelosTestCasesamenudoseusanenherenciamúltiple cooperativa, porloquedebetener cuidadodellamarsiempresuperenestosmétodosparaque también se tearDown métodos setUp y tearDown la clase base. La implementación básica de TestCase proporciona TestCase vacíos de setUp y tearDown para que puedan llamarse sin generar excepciones: Tenga en cuenta que en python2.7 +, también existe el método addCleanup que registra las funciones que deben llamarse después de ejecutarla prueba. Adiferencia de tearDown que solo se llama si setUp tiene éxito, las funciones registradas a través de addCleanup se addCleanup incluso en el caso de una excepción no controlada en setUp . Como ejemplo concreto, con frecuencia se puedevereste métodoeliminando varios simulacros que se registraron mientras seejecutabala prueba: from unittest.mock import create_autospec import unittest # we import the entire module so we can mock out multiply import custom_math custom_math.multiply = create_autospec(custom_math.multiply) from process_math import multiples_of class TestCustomMath(unittest.TestCase): def test_multiples_of(self): multiples = multiples_of(3, num_multiples=1) custom_math.multiply.assert_called_with(3, 1) def test_multiples_of_with_bad_inputs(self): with self.assertRaises(TypeError) as e: multiples_of(1, "extra arg", num_multiples=1) # this should raise a TypeError
    • 399. 334 def division_function(dividend, divisor): return dividend / divisor class MyTestCase(unittest.TestCase): def test_using_context_manager(self): with self.assertRaises(ZeroDivisionError): x = division_function(1, 0) class MyTestCase(unittest.TestCase): def test_using_context_manager(self): with self.assertRaises(ZeroDivisionError) as ex: x = division_function(1, 0) self.assertEqual(ex.message, 'integer division or modulo by zero') def division_function(dividend, divisor): """ Otra ventaja de registrar las limpiezas de esta manera es que le permite al programador colocar el código de limpieza al lado del código de configuración y lo protege en caso de que un subclase olvide llamar super en tearDown . Afirmación de excepciones Puede probar que una función produce una excepción con la prueba de unidad incorporada a través de dos métodos diferentes. Usando un administrador de contexto Esto ejecutará el código dentro del administrador de contexto y, si tiene éxito, fallará la prueba porque no se generó la excepción. Si el código genera una excepción del tipo correcto, la prueba continuará. También puede obtener el contenido de la excepción generada si desea ejecutar aserciones adicionales en su contra. Al proporcionar una función de llamada import unittest importsome_module class SomeOtherTest(unittest.TestCase): def setUp(self): super(SomeOtherTest, self).setUp() # Replace `some_module.method` with a `mock.Mock` my_patch = mock.patch.object(some_module, 'method') my_patch.start() # When the test finishes running, put the original method back. self.addCleanup(my_patch.stop)
    • 400. 335 import unittest class SimplisticTest(unittest.TestCase): def test_basic(self): self.assertTrue(1 + 1 == 2) self.assertTrue(1 + 1 == 3) self.assertEqual(1 + 1, 3) ====================================================================== FAIL: test ( main .TruthTest) La excepción para verificar debe ser el primer parámetro, y una función que se puede llamar debe pasarse como el segundo parámetro. Cualquier otro parámetro especificado se pasará directamente a la función que se está llamando, lo que le permite especificar los parámetros que activan la excepción. Eligiendo aserciones dentro de unitests Mientras Python tiene una assert comunicado , el marco de la unidad de pruebas Python tiene mejores afirmaciones especializados para las pruebas: son más informativos en los fracasos, y no dependen del modo de depuración de la ejecución. Quizás la aserción más simple es assertTrue , que se puede usar así: Esto funcionará bien, pero reemplazando la línea anterior con fallará. La afirmación assertTrue es bastante probable que sea la afirmación más general, ya que cualquier cosa probada puede assertTrue como una condición booleana, pero a menudo hay mejores alternativas. Cuando se prueba la igualdad, como arriba, es mejor escribir Cuando el primero falla, el mensaje es Dividing two numbers. :type dividend: int :type divisor: int :raises: ZeroDivisionError if divisor is zero (0). :rtype: int """ return dividend / divisor class MyTestCase(unittest.TestCase): def test_passing_function(self): self.assertRaises(ZeroDivisionError, division_function, 1, 0)
    • 401. 336 ====================================================================== FAIL: test ( main .TruthTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "stuff.py", line 6, in test self.assertEqual(1 + 1, 3) AssertionError: 2 != 3 pip install pytest mkdir tests touch tests/test_docker.py from subprocess import Popen, PIPE # this Popen is monkeypatched with the fixture `all_popens` pero cuando este último falla, el mensaje es que es más informativo (en realidad evaluó el resultado del lado izquierdo). Puede encontrar la lista de afirmaciones en la documentación estándar. En general, es una buenaideaelegirlaafirmaciónqueseajustemásespecíficamentealacondición.Porlotanto, como se muestra arriba, para afirmar que 1 + 1 == 2 es mejor usar assertEqual que assertTrue . De manera similar, para afirmar que a is None , es mejor usar assertIsNone que assertEqual . Tenga en cuenta también que las afirmaciones tienen formas negativas. Por assertEqual tanto, assertEqual tiene su contraparte negativa assertNotEqual , y assertIsNone tiene su contraparte negativa assertIsNotNone . Una vez más, usar las contrapartes negativas cuando sea apropiado, dará lugar a mensajes de error más claros. Pruebas unitarias con pytest instalando pytest: preparando las pruebas: Funciones para probar en docker_something/helpers.py : ---------------------------------------------------------------------- Traceback (most recent call last): File "stuff.py", line 6, in test self.assertTrue(1 + 1 == 3) AssertionError: False is not true
    • 402. 337 import os from tempfile import NamedTemporaryFile import pytest from subprocess import Popen, PIPE from docker_something import helpers copy_file_to_docker = helpers.copy_file_to_docker docker_exec_something = helpers.docker_exec_something class MockBytes(): '''Usedtocollectbytes ''' all_read = [] all_write = [] all_close = [] def read(self, *args, **kwargs): # print('read', args, kwargs, dir(self)) self.all_read.append((self, args, kwargs)) def write(self, *args, **kwargs): # print('wrote', args, kwargs) self.all_write.append((self, args, kwargs)) def close(self, *args, **kwargs): # print('closed', self, args, kwargs) self.all_close.append((self, args, kwargs)) def get_all_mock_bytes(self): return self.all_read, self.all_write, self.all_close La prueba importa test_docker.py : burlándose de un archivo como objeto en test_docker.py : def copy_file_to_docker(src, dest): try: result = Popen(['docker','cp', src, 'something_cont:{}'.format(dest)], stdout=PIPE, stderr=PIPE) err = result.stderr.read() if err: raise Exception(err) except Exception as e: print(e) return result def docker_exec_something(something_file_string): fl = Popen(["docker", "exec", "-i", "something_cont", "something"], stdin=PIPE, stdout=PIPE, stderr=PIPE) fl.stdin.write(something_file_string) fl.stdin.close() err = fl.stderr.read() fl.stderr.close() if err: print(err) exit() result = fl.stdout.read() print(result)
    • 403. 338 @pytest.fixture def all_popens(monkeypatch): '''This fixture overrides / mocks the builtin Popen and replaces stdin, stdout, stderr with a MockBytes object note: monkeypatch is magically imported ''' all_popens = [] class MockPopen(object): def init (self, args, stdout=None, stdin=None, stderr=None): all_popens.append(self) self.args = args self.byte_collection = MockBytes() self.stdin = self.byte_collection self.stdout = self.byte_collection self.stderr = self.byte_collection pass monkeypatch.setattr(helpers, 'Popen', MockPopen) return all_popens def test_docker_install(): p = Popen(['which', 'docker'], stdout=PIPE, stderr=PIPE) result = p.stdout.read() assert 'bin/docker' in result def test_copy_file_to_docker(all_popens): result = copy_file_to_docker('asdf', 'asdf') collected_popen = all_popens.pop() mock_read, mock_write, mock_close = collected_popen.byte_collection.get_all_mock_bytes() assert mock_read assert result.args == ['docker', 'cp', 'asdf', 'something_cont:asdf'] def test_docker_exec_something(all_popens): docker_exec_something(something_file_string) collected_popen = all_popens.pop() mock_read, mock_write, mock_close = collected_popen.byte_collection.get_all_mock_bytes() assert len(mock_read) == 3 something_template_stdin = mock_write[0][1][0] these = [os.environ['USER'], os.environ['password_prod'], 'table_name_here', 'test_vdm', 'col_a', 'col_b', '/tmp/test.tsv'] assert all([x in something_template_stdin for x in these]) py.test -k test_docker_install tests py.test -k test_copy_file_to_docker tests py.test -k test_docker_exec_something tests Parches de mono con pytest en test_docker.py : Ejemplos de pruebas, deben comenzar con el prefijo test_ en el archivo test_docker.py : ejecutando las pruebas una a la vez:
    • 404. 339 py.test -k test_ tests ejecutando todas las pruebas en la carpeta de tests :
    • 405. 340 def even_the_odds(odds): if odds % 2 != 1: raise ValueError("Did not get an odd number") return odds + 1 try: x = 5 / 0 except ZeroDivisionError as e: # `e` is the exception object print("Got a divide by zero! The exception was:", e) # handle exceptional case x = 0 Capítulo 77: Excepciones Introducción Los errores detectados durante la ejecución se denominan excepciones y no son incondicionalmentefatales.Lamayoríadelasexcepcionesnosonmanejadasporlosprogramas; es posible escribir programas que manejen excepciones seleccionadas. Hay características específicas enPython para lidiar con las excepciones y la lógica de excepciones.Además, las excepcionestienenunajerarquía de tiposenriquecidos, todosheredados del tipo BaseException . Sintaxis • levantar excepción • elevar # re-elevar una excepción que ya ha sido planteada • generar excepción de causa # Python 3 - establecer causa de excepción • generar excepción desde Ninguna # Python 3 - suprimir todo el contexto de excepción • tratar: • excepto [tipos de excepción] [ como identificador ] : • más: • finalmente: Examples Levantando excepciones Si su código encuentra una condición que no sabe cómo manejar, como un parámetro incorrecto, debe generar la excepción apropiada. Atrapar excepciones Utilicetry...except:paradetectarexcepciones.Debeespecificarunaexcepcióntanprecisacomo pueda:
    • 406. 341 >>> ZeroDivisionError. bases (<class 'ArithmeticError'>,) try: 5 / 0 except ArithmeticError: print("Got arithmetic error") resource = allocate_some_expensive_resource() try: do_stuff(resource) except SomeException as e: log_error(e) raise # re-raise the error finally: free_expensive_resource(resource) try: 5 / 0 except ZeroDivisionError: print("Got an error") La clase de excepción que se especifica, en este caso, ZeroDivisionError , captura cualquier excepción que sea de esa clase o de cualquier subclase de esa excepción. Por ejemplo, ZeroDivisionError es una subclase de ArithmeticError : Y así, lo siguiente seguirá ZeroDivisionError : Ejecutando código de limpieza con finalmente A veces, es posible que desee que ocurra algo, independientemente de la excepción que haya ocurrido, por ejemplo, si tiene que limpiar algunos recursos. Elbloquefinallydeunacláusuladetryocurriráindependientementedesi seprodujeron excepciones. Estepatróna menudo se maneja mejor conlosadministradoresdecontexto (usandola declaración with ). Re-elevando excepciones A veces desea capturar una excepción solo para inspeccionarla, por ejemplo, para fines de registro. Después de la inspección, desea que la excepción continúe propagándose como lo hizo antes. En este caso, simplemente use la instrucción raise sinparámetros. finally: print "The END" # it runs no matter what execute.
    • 407. 342 try: 5 / 0 except ZeroDivisionError as e: raise ZeroDivisionError("Got an error", e) >>> try: 5 / 0 except ZeroDivisionError as e: raise ValueError("Division failed") from e Traceback (most recent call last): File "<stdin>", line 2, in<module> ZeroDivisionError: division by zero The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<stdin>", line 4, in <module> ValueError: Division failed Sin embargo, tenga en cuenta que alguien que se encuentre más arriba en la pila de personas que llaman todavía puede detectar la excepción y manejarla de alguna manera. La salida realizada podría ser una molestia en este caso porque ocurrirá en cualquier caso (capturado o no capturado). Por lo tanto, podría ser una mejor idea plantear una excepción diferente, que contenga su comentario sobre la situación, así como la excepción original: Pero esto tiene el inconveniente de reducir la traza de excepción exactamente a este raise mientras que la raise sin argumento conserva la traza de excepción original. EnPython 3 puedes mantenerla pila original usando la sintaxis de raise -from : Cadena de excepciones con aumento de En el proceso de manejar una excepción, es posible que desee plantear otra excepción. Por ejemplo, si obtiene un IOError mientras lee un archivo, es posible que desee plantear un error específico de la aplicación para que se presente a los usuarios de su biblioteca. Python 3.x 3.0 Puede encadenar excepciones para mostrar cómo procedió el manejo de las excepciones: Jerarquía de excepciones El manejo de excepciones se produce en función de una jerarquía de excepciones, determinada por la estructura de herencia de las clases de excepciones. Por ejemplo, IOError y OSError son subclases de EnvironmentError . El código que captura un raise ZeroDivisionError("Got an error") from e raise
    • 408. 343 IOError nodetectaráunOSError .Sinembargo,elcódigoqueatrapaunEnvironmentError detectará tanto IOError s como OSError s. La jerarquía de las excepciones incorporadas: Python 2.x 2.3 BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIteration +-- StandardError | +-- BufferError | +-- ArithmeticError | | +-- FloatingPointError | | +-- OverflowError | | +-- ZeroDivisionError | +-- AssertionError | +-- AttributeError | +-- EnvironmentError | | +--IOError | | +-- OSError | | +-- WindowsError(Windows) | | +-- VMSError (VMS) | +-- EOFError | +--ImportError | +-- LookupError | | +-- IndexError | | +-- KeyError | +-- MemoryError | +-- NameError | | +-- UnboundLocalError | +-- ReferenceError | +-- RuntimeError | | +-- NotImplementedError | +-- SyntaxError | | +-- IndentationError | | +-- TabError | +-- SystemError | +-- TypeError | +-- ValueError | +-- UnicodeError | +-- UnicodeDecodeError | +-- UnicodeEncodeError | +-- UnicodeTranslateError +-- Warning +-- DeprecationWarning +-- PendingDeprecationWarning +-- RuntimeWarning +-- SyntaxWarning +-- UserWarning +-- FutureWarning +-- ImportWarning +-- UnicodeWarning +-- BytesWarning Python 3.x 3.0
    • 409. 344 BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIteration +-- StopAsyncIteration +-- ArithmeticError | +-- FloatingPointError | +-- OverflowError | +-- ZeroDivisionError +-- AssertionError +-- AttributeError +-- BufferError +-- EOFError +-- ImportError +-- LookupError | +-- IndexError | +-- KeyError +-- MemoryError +-- NameError | +-- UnboundLocalError +-- OSError | +-- BlockingIOError | +-- ChildProcessError | +-- ConnectionError | | +-- BrokenPipeError | | +-- ConnectionAbortedError | | +-- ConnectionRefusedError | | +-- ConnectionResetError | +-- FileExistsError | +-- FileNotFoundError | +-- InterruptedError | +-- IsADirectoryError | +-- NotADirectoryError | +-- PermissionError | +-- ProcessLookupError | +-- TimeoutError +-- ReferenceError +-- RuntimeError | +-- NotImplementedError | +-- RecursionError +-- SyntaxError | +-- IndentationError | +-- TabError +-- SystemError +-- TypeError +-- ValueError | +-- UnicodeError | +-- UnicodeDecodeError | +-- UnicodeEncodeError | +-- UnicodeTranslateError +-- Warning +-- DeprecationWarning +-- PendingDeprecationWarning +-- RuntimeWarning +-- SyntaxWarning +-- UserWarning +-- FutureWarning +-- ImportWarning +-- UnicodeWarning
    • 410. 345 >>> def failing_function(): ... raise ValueError('Example error!') >>> failing_function() Traceback (most recent call last): File "<stdin>", line 1, in<module> File "<stdin>", line 2, in failing_function ValueError: Example error! >>> try: ... failing_function() ... except ValueError: ... print('Handledtheerror') Handled the error >>> try: ... failing_function() ... except ValueError as e: ... print('Caught exception', repr(e)) Caught exception ValueError('Example error!',) class FooException(Exception): pass try: raise FooException("insert description here") Las excepciones son objetos también Las excepciones son solo objetos de Python normales que heredan de la BaseException . Una secuenciadecomandos dePython puede usarla instrucción raise para interrumpirla ejecución, lo que hace que Python imprima un seguimiento de pila de la pila de llamadas en ese punto y una representación de la instancia de excepción. Por ejemplo: que dice que un ValueError con el mensaje 'Example error!' fue planteado por nuestro failing_function() , que fue ejecutado en el intérprete. El código de llamada puede elegir manejar cualquier excepción de todo tipo que una llamada pueda generar: Puede obtener los objetos de excepción asignándolos en la parte except... del código de manejo de excepciones: Puede encontrar una lista completa de las excepciones de Python incorporadas junto con sus descripciones en la Documentación de Python: https://docs.python.org/3.5/library/exceptions.html . Y aquí está la lista completa organizada jerárquicamente: Jerarquía de excepciones . Creación de tipos de excepción personalizados Crea una clase heredada de Exception : +-- BytesWarning +-- ResourceWarning
    • 411. 346 class NegativeError(ValueError): pass def foo(x): # function that only accepts positive values of x if x < 0: raise NegativeError("Cannot process negative numbers") ... #rest offunction body try: result = foo(int(input("Enter a positive integer: "))) # raw_input inPython 2.x except NegativeError: print("You entered a negative number!") else: print("The result was " + str(result)) try: very_difficult_function() except Exception: # log / try to reconnect / exit gratiously finally: print "The END" # it runs no matter what execute. try: even_more_difficult_function() except: pass # do whatever needed u otro tipo de excepción: No atrapes todo! Aunque a menudo es tentador atrapar todas las Exception : O incluso todo (que incluye BaseException y todos sus hijos, incluida la Exception ): En la mayoría de los casos es una mala práctica. Es posible que SystemExit más de lo previsto, como SystemExit , KeyboardInterrupt y MemoryError , cada uno de los cuales generalmente debe manejarsede maneradiferentealoserroreshabituales del sistemaolalógica.Tambiénsignifica queno hay una comprensión clara dequépuedehacer mal el códigointerno y cómo recuperarse adecuadamente de esa condición.Si está detectando cada error, no sabrá qué error ocurrió o cómo solucionarlo. Esto se conoce más comúnmente como "enmascaramiento de errores" y debe evitarse. Deje que su programa se bloquee en lugar de fallar silenciosamente o incluso peor, fallando en un nivel más profundo de ejecución. (Imagina que es un sistema transaccional) Por lo general, estas construcciones se usan en el nivel más externo del programa, y registrarán los detalles del error para que el error se pueda corregir, o el error se pueda manejar más except FooException: print("A FooException was raised.")
    • 412. 347 try: d = {} a = d[1] b = d.non_existing_field except (KeyError, AttributeError) as e: print("A KeyError or an AttributeError exception has been caught.") try: d = {} a = d[1] b = d.non_existing_field except KeyError as e: print("A KeyError has occurred. Exception message:", e) except AttributeError as e: print("An AttributeError has occurred. Exception message:", e) while True: try: nb = int(input('Enter a number: ')) break except ValueError: print('This is not a number, try again.') específicamente. Atrapando múltiples excepciones Hay algunas maneras de atrapar múltiples excepciones . Laprimeraescreandounatupladelostiposdeexcepciónquedeseacapturarymanejardela misma manera. Este ejemplo hará que el código ignore las excepciones KeyError y AttributeError . Sidesea manejardiferentesexcepcionesde diferentesmaneras,puedeproporcionarunbloque de excepción separado para cada tipo. En este ejemplo, todavía KeyError y AttributeError , pero manejamos las excepciones de diferentesmaneras. Ejemplos prácticos de manejo de excepciones. Entrada del usuario Imaginaquequieresqueunusuarioingreseunnúmeroatravésdeunainput .Deseaasegurarse de que la entrada es un número. Puedes usar try / except de esto: Python 3.x 3.0 Nota: Python 2.x usaría raw_input en raw_input lugar; la input la función existe en Python 2.x pero tiene una semántica diferente. En el ejemplo anterior, la input también aceptaría expresiones como 2 + 2 que se evalúan como un número.
    • 413. 348 d = [{7: 3}, {25: 9}, {38: 5}] for i in range(len(d)): do_stuff(i) try: dic = d[i] i += dic[i] except KeyError: i += 1 try: data = {1: 'one', 2: 'two'} print(data[1]) except KeyError as e: print('key not found') else: raise ValueError() # Output: one # Output: ValueError try: ... except ...: ... else: if ...: Si la entrada no se pudo convertir en un entero, se ValueError un ValueError . Puedes atraparlo con except . Si se plantea no es una excepción, break salta fuera del bucle. Después del bucle, nb contiene un entero. Los diccionarios Imagine que está iterando sobre una lista de enteros consecutivos, como el range(n) , y tiene una lista de diccionarios d que contiene información sobre cosas que hacer cuando encuentra algunos enteros en particular, por ejemplo, omita los d[i] siguientes . Se KeyError un KeyError cuando intente obtener un valor de un diccionario para una clave queno existe. Más El código en un bloque else solo se ejecutará si el código en el bloque try no genera excepciones.Esto es útil si tiene algún código que no desea ejecutar si selanza una excepción, pero no quiere que se detecten excepciones lanzadas por ese código. Por ejemplo: Tengaencuentaqueestetipo deelse: nosepuedecombinarcon if inicia la cláusulaelse en un elif.Siustedtieneunsiguienteifquenecesitaparamantenerseconsangríadebajodeesa else: :
    • 414. 349 ... elif ...: ... else: ...
    • 415. 350 print "This line is ok" print "This line isn't ok" print("This line is ok") print("This line isn't ok") print "This line is ok" print "This line isn't ok" Capítulo 78: Excepciones del Commonwealth Introducción Aquí en Stack Overflow a menudo vemos duplicados que hablan de los mismos errores: "ImportError: No module named '??????' , SyntaxError: invalid syntax o NameError: name '???' is not defined .Esteesunesfuerzo parareducirlos yparateneralguna documentaciónconlacual enlazar. Examples IndentationErrors (o indentation SyntaxErrors) En la mayoría de los otros idiomas, la sangría no es obligatoria, pero en Python (y otros idiomas: versiones anteriores de FORTRAN, Makefiles, Whitespace (lenguaje esotérico), etc.) no es el caso, lo que puede ser confuso si viene de otro idioma. si estaba copiando el código de un ejemplo a su propio, o simplemente si es nuevo. IndentationError / SyntaxError: sangría inesperada Esta excepción se produce cuando el nivel de sangrado aumenta sin razón. Ejemplo No hay razón para aumentar el nivel aquí: Python 2.x 2.0 2.7 Python 3.x 3.0 Aquí hay dos errores: el último y que la sangría no coincide con ningún nivel de sangría. Sin embargo solo se muestra una: Python 2.x 2.0 2.7
    • 416. 351 print("This line is ok") print("This line isn't ok") def foo(): print "This should be part of foo()" print "ERROR!" print "This is not a part of foo()" print("This line is ok") print("This line isn't ok") if ok: doStuff() def foo(): pass Python 3.x 3.0 IndentationError / SyntaxError: unindent no coincide con ningún nivel de sangría externa Parece que no te diste por completo. Ejemplo Python 2.x 2.0 2.7 Python 3.x 3.0 Error Tabulación: Se esperaba un bloque tabulado Después de dos puntos (y luego una nueva línea) el nivel de sangrado tiene que aumentar. Este error surge cuando eso no sucedió. Ejemplo Nota:Useelpasspalabraclave(quenohaceabsolutamentenada)parasimplementeponerun if , else , except , class , method o definition pero no diga lo que sucederá si la condición de llamadaes verdadera(perohágalo mástarde,oenel caso deexcept : simplementenohacer nada):
    • 417. 352 def foo(): if ok: return "Two != Four != Tab" return "i dont care i do whatever i want" def foo(a): return a foo(a,b,c,d) #And a,b,c,d are defined def foo(a,b,c,d): return a += b + c + d foo(a) #And a is defined IndentationError: uso incoherente de tabulaciones y espacios en sangría Ejemplo Cómo evitar este error No uses pestañas. Se desalienta por PEP8 , la guía de estilo para Python. 1. Configure su editor para usar 4 espacios para la sangría. 2. Haga una búsqueda y reemplace para reemplazar todas las pestañas con 4 espacios. 3. Asegúrese de que su editor esté configurado para mostrar las pestañas en 8espacios, para que pueda darse cuenta fácilmente de ese error y corregirlo. Vea esta pregunta si desea aprender más. TypeErrors Estas excepciones se producen cuando el tipo de algún objeto debe ser diferente TypeError: [definición / método] toma? argumentos posicionales pero? se le dio Se llamó a una función o método con más (o menos) argumentos que los que puede aceptar. Ejemplo Si se dan más argumentos: Si se dan menos argumentos:
    • 418. 353 set1, tuple1 = {1,2}, (3,4) a = set1 + tuple1 b = 400 + 'foo' c = ["a","b"] - [1,2] d = 1 + 1.0 Nota : si desea usar un número desconocido de argumentos, puede usar *args o **kwargs . Ver * args y ** kwargs TypeError: tipo (s) de operando no compatibles para [operando]: '???' y '???' Algunos tipos no se pueden operar juntos, dependiendo del operando. Ejemplo Por ejemplo: + se usa para concatenar y agregar, pero no puede usar ninguno de ellos para ambos tipos. Por ejemplo, al intentar crear un set concatenando ( + ing)'set1' y 'tuple1' el error. Código: Algunos tipos (por ejemplo: int y string ) usan ambos + pero para diferentes cosas: O puede que ni siquiera se utilicen para nada: Pero puedes, por ejemplo, agregar un float a un int : Error de tecleado: '???' El objeto no es iterable / subscriptible: Paraqueunobjeto sea iterable,puede tomaríndices secuencialesdesdecero hasta quelos índices ya no sean válidos y se IndexError un IndexError (más técnicamente: debe tener un método iter que devuelveun iterator , o que defina un método getitem que sílo mencionado anteriormente). Ejemplo Aquí estamos diciendo que la bar es el elemento cero de 1. Tonterías:
    • 419. 354 amount = 10 for x in amount: print(x) foo = "notAFunction" foo() foo # This variable is not defined bar() # This function is not defined baz() def baz(): pass Esta es una versión más discreta: En este ejemplo for intenta establecer x a amount[0] , el primer elemento en un iterable pero no puede porque cantidad es un int: Error de tecleado: '???' el objeto no es llamable Está definiendo una variable y llamándola más tarde (como lo que hace con una función o método) Ejemplo NameError: name '???' no está definido Se genera cuando intenta utilizar una variable, método o función que no está inicializada (al menos no antes). En otras palabras, se genera cuando no se encuentra un nombre local o global solicitado. Es posible que haya escrito mal el nombre del objeto o se haya olvidado de import algo. También tal vez esté en otro ámbito. Los cubriremos con ejemplos separados. Simplemente no está definido en ninguna parte en el código Es posible que haya olvidado inicializarlo, especialmente si es una constante. Tal vez se define más adelante: foo = 1 bar = foo[0]
    • 420. 355 #needs import math def sqrt(): x = float(input("Value: ")) return math.sqrt(x) Local → Enclosed → Global → Built-in. for i in range(4): d = i * 2 print(d) def noaccess(): for i in range(4): d = i * 2 noaccess() print(d) assert condition O no fue import Los alcances de Python y la Regla LEGB: La llamada Regla de LEGB habla sobre los alcances de Python. Su nombre se basa en los diferentes ámbitos, ordenados por las prioridades correspondientes: • L ocal: Variables no declaradas globalmente o asignadas en una función. • E nclosing: Variables definidas en una función que está envuelta dentro de otra función. • Ondoparael: Las variables declaradas globales, o asignados en el nivel superior de un archivo. • B uilt-in: variables preasignadas en el módulo de nombres incorporado. Como ejemplo: d es accesible porque el bucle for no marca un nuevo ámbito, pero si lo hiciera, tendríamos un error y su comportamiento sería similar a: Python dice NameError: name 'd' is not defined Otros errores AssertError Laassert declaración existe en casi todos los lenguajes deprogramación. Cuando tulo hagas:
    • 421. 356 div = float(raw_input("Divisors of: ")) for x in xrange(1,div+1): #includes the number itself but not zero if div/x == div//x: print x, "is a divisor of", div div = float(raw_input("Divisors of: ")) for x in xrange(div+1): #includes the number itself and zero if div/x == div//x: print x, "is a divisor of", div assert condition, message if debug : if not condition: raise AssertionError(message) div = int(input("Divisors of: ")) for x in range(div+1): #includes the number itself and zero if div/x == div//x: print(x, "is a divisor of", div) o: Es equivalente a esto: Las aserciones pueden incluir un mensaje opcional, y puedes deshabilitarlas cuando hayas terminado la depuración. Nota : la depuración de la variable incorporada es Verdadero en circunstancias normales, Falso cuando se solicita la optimización (opción de línea de comando -O). Las asignaciones a depuración son ilegales. El valor de la variable incorporada se determina cuando se inicia el intérprete. Teclado interrumpir Se produjo un error cuando el usuario presiona la tecla de interrupción, normalmente Ctrl + C o del . ZeroDivisionError 1/0 calcular 1/0 que no está definido. Vea este ejemplo para encontrar los divisores de un número: Python 2.x 2.0 2.7 Python 3.x 3.0 ZeroDivisionError porque el bucle for asigna ese valor a x . En su lugar debería ser: Python 2.x 2.0 2.7
    • 422. 357 >>> print "hello world" File "<stdin>", line 1 print "hello world" ^ SyntaxError: invalid syntax div = int(input("Divisors of: ")) for x in range(1,div+1): #includes the number itself but not zero if div/x == div//x: print(x, "is a divisor of", div) def my_print(): x = (1 + 1 print(x) File "<input>", line 3 print(x) ^ SyntaxError: invalid syntax print("hello world") # Note this is valid for both Py2 & Py3 Python 3.x 3.0 Error de sintaxis en buen código La gran mayoría de las veces que un SyntaxError que apunta a una línea sin interés significa que hay un problema en la línea anterior (en este ejemplo, es un paréntesis que falta): Devoluciones La razón más común para este problema son paréntesis / paréntesis que no coinciden, como muestra el ejemplo. Hay una advertencia importante para las declaraciones impresas en Python 3: Python 3.x 3.0 Debido a que la declaración de print fuereemplazada con la función print() , entonces usted quiere:
    • 423. 358 import logging logger = logging.getLogger() handler = logging.StreamHandler() formatter = logging.Formatter( '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) logger.setLevel(logging.DEBUG) logger.debug('this is a %s test', 'debug') 2016-07-26 18:53:55,332 root DEBUG this is a debug test [loggers] keys=root [handlers] keys=stream_handler [formatters] keys=formatter [logger_root] level=DEBUG handlers=stream_handler Capítulo 79: Explotación florestal Examples Introducción al registro de Python Este módulo define funciones y clases que implementan un sistema flexible de registro de eventos para aplicaciones y bibliotecas. El beneficio clave de tener la API de registro proporcionada por un módulo de biblioteca estándar es que todos los módulos de Python pueden participar en el registro, por lo que el registro de su aplicación puede incluir sus propios mensajes integrados con mensajes de módulos de terceros. Entonces, comencemos: Ejemplo de configuración directamente en el código Ejemplo de salida: Ejemplo de configuración a través de un archivo INI Suponiendo que el archivo se llama logging_config.ini. Más detalles sobre el formato de archivo se encuentran en la sección de configuración de registro del tutorial de registro .
    • 424. 359 import logging from logging.config import fileConfig fileConfig('logging_config.ini') logger = logging.getLogger() logger.debug('often makes a very good meal of %s', 'visiting tourists') import logging from logging.config import dictConfig logging_config = dict( version = 1, formatters = { 'f': {'format': '%(asctime)s %(name)-12s %(levelname)-8s %(message)s'} }, handlers = { 'h': {'class':'logging.StreamHandler', 'formatter': 'f', 'level': logging.DEBUG} }, root = { 'handlers': ['h'], 'level': logging.DEBUG, }, ) dictConfig(logging_config) logger = logging.getLogger() logger.debug('often makes a very good meal of %s', 'visiting tourists') >>> import logging >>> logging.basicConfig() >>> try: ... raise Exception('foo') Luego use logging.config.fileConfig() en el código: Ejemplo de configuración a través de un diccionario A partir de Python 2.7, puede usar un diccionario con detalles de configuración. PEP 391 contiene una lista de los elementos obligatorios y opcionales en el diccionario de configuración. Excepciones de registro Si desea registrar excepciones, puede y debe hacer uso del método logging.exception(msg) : [handler_stream_handler] class=StreamHandler level=DEBUG formatter=formatter args=(sys.stderr,) [formatter_formatter] format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s
    • 425. 360 >>> try: ... raise Exception('foo') ... except Exception as e: ... logging.exception(e) ... ERROR:root:foo Traceback (most recent call last): File "<stdin>", line 2, in<module> Exception: foo >>> try: ... raise Exception(u'föö') ... except Exception as e: ... logging.exception(e) ... Traceback (most recent call last): File "/.../python2.7/logging/ init .py", line 861, in emit msg = self.format(record) File "/.../python2.7/logging/ init .py", line 734, in format return fmt.format(record) File "/.../python2.7/logging/ init .py", line 469, in format s = self._fmt % record. dict UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-2: ordinal not in range(128) Logged from file <stdin>, line 4 No pase la excepción como argumento: Como logging.exception(msg) espera un msg arg, es un error común para aprobar la excepción en el registro de llamadas de esta manera: Si bien puede parecer que esto es lo correcto al principio, en realidad es problemático debido a la forma en que las excepciones y las distintas codificaciones funcionan juntas en el módulo de registro: Intentarregistraruna excepción que contengacaracteresUnicode,de esta manera fallará miserablemente .Ocultaráel seguimientode piladelaexcepciónoriginal al anularlacon una nueva que se logging.exception(e) durante el formateo de su logging.exception(e) . Obviamente, en su propio código, podría estar al tanto de la codificación en las excepciones. Sin embargo, las bibliotecas de terceros pueden manejar esto de una manera diferente. Uso Correcto: Si en lugar de la excepción simplemente pasa un mensaje y deja que Python haga su magia, funcionará: ERROR:root:bar Traceback (most recent call last): File "<stdin>", line 2, in <module> Exception: foo ... logging.exception('bar') ... ...except:
    • 426. 361 logging.debug('exception occurred', exc_info=1) logging.info('exception occurred', exc_info=1) logging.warning('exception occurred', exc_info=1) >>> try: ... raise Exception(u'föö') ... except Exception as e: ... logging.exception('received this exception: %r' % e) ... ERROR:root:received this exception: Exception(u'f\xf6\xf6',) Traceback (most recent call last): File "<stdin>", line 2, in <module> Exception: f\xf6\xf6 Como puede ver, en realidad no usamos e en ese caso, la llamada alogging.exception(...) formatea mágicamente la excepción más reciente. Registro de excepciones con niveles de registro que no sean ERROR Si desea registrar una excepción con un nivel de registro diferente al ERROR, puede usar el argumento exc_info de los registradores predeterminados: Accediendo al mensaje de la excepción. Tenga en cuenta que las bibliotecas podrían generar excepciones con los mensajes como Unicode o (utf-8 si tiene suerte) de cadenas de bytes. Si realmente necesita acceder a un texto de excepción, la única forma confiable, que siempre funcionará, es usar repr(e) o el formato de cadena %r : >>> try: ... raise Exception(u'föö') ... except Exception as e: ... logging.exception('bar') ... ERROR:root:bar Traceback (most recent call last): File "<stdin>", line 2, in <module> Exception: f\xf6\xf6
    • 427. 362 math.sqrt(-10) import cmath cmath.sqrt(4) # 2+0j cmath.sqrt(-4) # 2j Capítulo 80: Exposiciónción Sintaxis • valor1 ** valor2 • pow (valor1, valor2 [, valor3]) • value1 . pow (value2 [, value3]) • valor2 . rpow (valor1) • operator.pow (valor1, valor2) • operador . pow (valor1, valor2) • math.pow (value1, value2) • math.sqrt (valor1) • math.exp (value1) • cmath.exp (valor1) • math.expm1 (value1) Examples Raíz cuadrada: math.sqrt () y cmath.sqrt Elmódulo math contienelafunción math.sqrt()quepuedecalcularlaraízcuadradadecualquier número (que se puede convertir en un float ) y el resultado siempre será un float : import math math.sqrt(9) # 3.0 math.sqrt(11.11) # 3.3331666624997918 math.sqrt(Decimal('6.25')) # 2.5 La función math.sqrt() genera un ValueError si el resultado seríacomplex : ValueError: error de dominio matemático math.sqrt(x) es más rápido que math.pow(x, 0.5) o x ** 0.5 pero la precisión de los resultados es lamisma.El módulocmathesextremadamentesimilaral módulo math ,exceptoporelhechode quepuede calcular números complejos y todos sus resultados tienen la formade a+bi.También puede usar .sqrt() : ¿Quépasaconlaj?jeselequivalentealaraízcuadradade-1.Todoslosnúmerossepueden
    • 428. 363 pow(2, 3) # 8 2 ** 3 # 8 2 ** -3 # Out: 0.125 (result is a float) (-2) ** (0.5) # also (-2.) ** (0.5) # Out: (8.659560562354934e-17+1.4142135623730951j) (result is complex) operator. pow (4, 3) # 64 # 16 import operator operator.pow(4, 2) # in-place power operation isn't supported by immutable classes like int, float, complex: # val1. ipow (val2) # 16 # 16 val1, val2 = 4, 2 val1. pow (val2) val2. rpow (val1) poner en la forma a+ bi, o en este caso, a+ bj. a es la parte real del número como el 2 en 2+0j . Comonotieneunaparteimaginaria,bes0.brepresentapartedelaparteimaginariadelnúmero como el 2 en 2j . Como no hay una parte real en esto, 2j también puede escribirse como 0 + 2j . Exposiciónción utilizando builtins: ** y pow () Exponenciación se puede utilizar mediante el uso de la orden interna pow -Función o el ** operador: Para la mayoría de las operaciones aritméticas (todas en Python 2.x), el tipo de resultado será el del operando más amplio. Esto no es cierto para ** ; Los siguientes casos son excepciones a esta regla: • Base: int , exponente: int < 0 : • Esto también es válido para Python 3.x. • Antes de Python 2.2.0, esto ValueError un ValueError . • Base: int < 0 o float < 0 , exponente: float !=int • Antes de Python 3.0.0, esto ValueError un ValueError . El módulo operator contiene dos funciones que son equivalentes al operador ** : o uno podría llamar directamente al método pow : Exposiciónción utilizando el módulo matemático: math.pow () El módulo math contiene otra función math.pow() . La diferencia con el operador incorporado pow() -
    • 429. 364 import math math.pow(2, 2) # 4.0 math.pow(-2., 2) # 4.0 math.pow(2, 2+0j) function o ** es que el resultado es siempre un float : Lo que excluye los cálculos con entradas complejas: TypeError: no se puede convertir complejo a flotar y cálculos que conducirían a resultados complejos: ValueError: error de dominio matemático Función exponencial: math.exp () y cmath.exp () Tanto el módulo math como el módulo cmath contienen el número de Euler: e, y usarlo con la función pow() incorporada o el operador ** funciona principalmente como math.exp() : import math math.e ** 2 # 7.3890560989306495 math.exp(2) # 7.38905609893065 import cmath cmath.e ** 2 # 7.3890560989306495 cmath.exp(2) # (7.38905609893065+0j) Sinembargo,elresultadoesdiferente yusarlafunciónexponencial directamente es más confiable que la exponenciación math.e con base math.e : print(math.e ** 10) # 22026.465794806703 print(math.exp(10)) # 22026.465794806718 print(cmath.exp(10).real) # difference starts he # re 22026.465794806718 ------------------- ^ Función exponencial menos 1: math.expm1 () El módulo math contiene la función expm1() que puede calcular la expresión math.e ** x - 1 para x muy pequeña con mayor precisión que math.exp(x) o cmath.exp(x) permitiría: import math print(math.e ** 1e-3 - 1) # 0.0010005001667083846 print(math.exp(1e-3) - 1) # 0.0010005001667083846 print(math.expm1(1e-3)) # # 0.0010005001667083417 ------------------^ math.pow(-2, 0.5)
    • 430. 365 print(math.e ** 1e-15 - 1) # 1.1102230246251565e-15 print(math.exp(1e-15) - 1) # 1.1102230246251565e-15 print(math.expm1(1e-15)) # 1.0000000000000007e-15 # ^------------------- def planks_law(lambda_, T): from scipy.constants import h, k, c # If no scipy installed hardcode these! return 2 * h * c ** 2 / (lambda_ ** 5 * math.expm1(h * c / (lambda_ * k * T))) def planks_law_naive(lambda_, T): from scipy.constants import h, k, c # If no scipy installed hardcode these! return 2 * h * c ** 2 / (lambda_ ** 5 * (math.e ** (h * c / (lambda_ * k * T)) - 1)) planks_law(100, 5000) # 4.139080074896474e-19 planks_law_naive(100, 5000) # 4.139080073488451e-19 # ^---------- planks_law(1000, 5000) # 4.139080128493406e-23 planks_law_naive(1000, 5000) # 4.139080233183142e-23 # ^------------ class Integer(object): def init (self, value): self.value = int(value) # Cast to an integer def repr (self): return '{cls}({val})'.format(cls=self. class . name , val=self.value) def pow (self, other, modulo=None): if modulo is None: print('Using pow ') return self. class (self.value ** other) else: print('Using pow with modulo') return self. class (pow(self.value, other, modulo)) def float (self): print('Using float ') return float(self.value) def complex (self): print('Using complex ') return complex(self.value, 0) Para x muy pequeño la diferencia se hace más grande: La mejora es significativa en la computación científica. Por ejemplo, la ley de Planck contiene una función exponencial menos 1: Métodos mágicos y exponenciales: incorporados, matemáticos y matemáticos. Suponiendo que tienes una clase que almacena valores puramente enteros: Usando la función pow incorporada o el operador ** siempre llama a pow :
    • 431. 366 # Prints: Using pow with modulo Integer(2). pow (3, 4) # Integer(0) # Prints: Using pow with modulo pow(Integer(2), 3, 4) # Integer(0) import math math.pow(Integer(2), 0.5) # 1.4142135623730951 # Prints: Using float # Prints: Using complex del Integer. complex # Deleting complex method - instances cannot be cast to complex cmath.exp(Integer(2)) # (7.38905609893065+0j) # Prints: Using float # (7.38905609893065+0j) import cmath cmath.exp(Integer(2)) del Integer. float # Deleting complex method math.sqrt(Integer(2)) # also cmath.exp(Integer(2)) pow(3, 4, 17) # 13 El segundo argumento del método pow () solo se puede suministrar usando la función builtinpow pow() o llamando directamente al método: Mientras que las funciones math siempre lo convierten en un float y usan el cálculo de flotación: cmath funciones intentan convertirlo en complex pero también pueden retroceder a float si no hay una conversión explícita a complex : Ni math ni cmath funcionarán si también float () el float () : TypeError: se requiere un flotador Exponenciación modular: pow () con 3 argumentos. Al suministrar pow() con 3 argumentos pow(a, b, c) evalúa la exponenciación modular a b mod c : operator. pow (Integer(3), 3) # Integer(27) # Prints: Using pow # Integer(8) # Integer(1) # Integer(5) Integer(2) ** 2 # Integer(4) # Prints: Using pow Integer(2) ** 2.5 # Prints: Using pow pow(Integer(2), 0.5) # Prints: Using pow operator.pow(Integer(2), 3) # Prints: Using pow
    • 432. 367 def modular_inverse(x, p): """Find a such as a·x ≡ 1 (mod p), assuming p is prime.""" return pow(x, p-2, p) [modular_inverse(x, 13) for x in range(1,13)] # Out: [1, 7, 9, 10, 8, 11, 2, 5, 3, 4, 6, 12] >>> x = 3 >>> y = x ** 3 >>> y 27 >>> z = y ** (1.0 / 3) >>> z 3.0 >>> z == x True x = 2 ** 100 cube = x ** 3 Para los tipos incorporados, el uso de exponenciación modular solo es posible si: • El primer argumento es unint • El segundo argumento es un int >= 0 • El tercer argumento es un int != 0 Estas restricciones también están presentes en Python 3.x Por ejemplo, uno puede usar la forma de 3 argumentos de pow para definir una función inversa modular : Raíces: raíz nth con exponentes fraccionarios Si bien la función math.sqrt se proporciona para el caso específico de raíces cuadradas, a menudo es conveniente usar el operador de exponenciación ( ** ) con exponentes fraccionarios para realizar operaciones de raíz nth, como las raíces cúbicas. La inversa de una exponenciación es la exponenciación por el recíproco del exponente. Entonces, si puedes calcular un número colocándolo en el exponente de 3, puedes encontrar la raíz cúbica de un número poniéndolo en el exponente de 1/3. Cálculo de grandes raíces enteras A pesar de que Python admite de forma nativa grandes enteros, tomar la raíz n de números muy grandes puede fallar en Python. # 81 # 13 # steps: 3 ** 4 81 % 17 # equivalent unoptimized expression: 3 ** 4 % 17 # 13
    • 433. 368 def nth_root(x, n): # Start with some reasonable bounds around the nth root. upper_bound = 1 while upper_bound ** n <= x: upper_bound *= 2 lower_bound = upper_bound // 2 # Keep searching for a better result as long as the bounds make sense. while lower_bound < upper_bound: mid = (lower_bound + upper_bound) // 2 mid_nth = mid ** n if lower_bound < mid and mid_nth < x: lower_bound = mid elif upper_bound > mid and mid_nth > x: upper_bound = mid else: # Found perfect nth root. return mid return mid + 1 x = 2 ** 100 cube = x ** 3 root = nth_root(cube, 3) x == root # True OverflowError: largo int demasiado grande para convertirlo en flotante Cuando trate con enteros tan grandes, necesitará usar una función personalizada para calcular la enésima raíz de un número. root = cube ** (1.0 /3)
    • 434. 369 Capítulo 81: Expresiones Regulares (Regex) Introducción Python hace que las expresiones regulares estén disponibles a través del módulo re . Lasexpresiones regularessoncombinacionesdecaracteresqueseinterpretancomoreglaspara hacer coincidir subcadenas. Por ejemplo, la expresión 'amount\D+\d+' coincidirá con cualquier cadenacompuestaporlaamountpalabramásunnúmerointegral,separadosporunoomásno dígitos, como: amount=100 , amount is 3 , amount is equal to: 33 , etc. Sintaxis • Expresiones regulares directas • re.match (patrón, cadena, marca = 0) # Fuera: coincide con el patrón al principio de la cadena o Ninguno • re.search (patrón, cadena, marca = 0) # Fuera: coincide con el patrón dentro de la cadena o Ninguno • re.findall (pattern, string, flag = 0) # Out: lista de todas las coincidencias de pattern en string o [] • re.finditer (patrón, cadena, flag = 0) # Out: igual que re.findall, pero devuelve el objeto iterador • re.sub (patrón, reemplazo, cadena, marca = 0) # Out: cadena con reemplazo (cadena o función) en lugar de patrón • Expresiones regulares precompiladas • precompiled_pattern = re.compile (patrón, flag = 0) • precompiled_pattern.match (string) # Out: coincide al principio de string o Ninguno • precompiled_pattern.search (string) # Out: coincide en cualquier lugar con string o None • precompiled_pattern.findall (string) # Out: lista de todas las subcadenas coincidentes • precompiled_pattern.sub (cadena / patrón / función, cadena) # Fuera: cadena reemplazada Examples Coincidiendo con el comienzo de una cadena El primer argumento de re.match() es la expresión regular, el segundo es la cadena que debe
    • 435. 370 import re pattern = r"123" string = "123zzb" re.match(pattern, string) # Out: <_sre.SRE_Match object; span=(0, 3), match='123'> match = re.match(pattern, string) match.group() # Out: '123' # matches '\\t123' pattern = r"\\t123" re.match(pattern, string).group() string = "\\t123zzb" # here the backslash is escaped, so there's no tab, just '\' and 't' pattern = "\\t123" # this will match \t (escaping the backslash) followed by 123 re.match(pattern, string).group() # no match re.match(pattern, "\t123zzb").group() # matches '\t123' match = re.match(r"(123)", "a123zzb") match is None # Out: True match = re.search(r"(123)", "a123zzb") match.group() # Out: '123' coincidir: Puede observar que la variable de patrón es una cadena con el prefijo r , que indica que la cadena es un literal de cadena sin formato. Una cadena prima literal tiene una sintaxis ligeramente diferente de una cadena literal, es decir, una barra invertida \ en un medio literal de cadena en bruto "sólo una barra invertida" y no hay necesidad de duplicar los juegos de escapar "secuencias de escape", tales como saltos de línea ( \n),tabulaciones(\t),espaciosenblanco(\),feedsdeformularios(\r),etc.Enlosliterales decadena normales, cada barrainvertida debeduplicarse paraevitarque se tome como el inicio de una secuencia deescape. Por lo tanto, r"\n" es una cadena de 2 caracteres: \ y n . Los patrones Regex también usan barras invertidas, por ejemplo, \d refiere a cualquier carácter dedígito.Podemos evitartenerque doble escape de nuestras cadenas ( "\\d" ) mediante el uso de cadenas sin formato (r"\d" ). Por ejemplo: Lacoincidenciase realizadesde el principiodelacadena solamente.Siquieres hacer coincidiren cualquier lugar, usa re.search en re.search lugar:
    • 436. 371 pattern = r"(your base)" sentence = "All your base are belong to us." match = re.search(pattern, sentence) match.group(1) # Out: 'your base' match = re.search(r"(belong.*)", sentence) match.group(1) # Out: 'belong to us.' match = re.search(r"^123", "123zzb") match.group(0) # Out: '123' match = re.search(r"^123", "a123zzb") match is None # Out: True match = re.search(r"123$", "zzb123") match.group(0) # Out: '123' match = re.search(r"123$", "123zzb") match is None # Out: True match = re.search(r"^123$", "123") match.group(0) # Out: '123' match.group() # Group without argument returns the entire match found # Out: '123' match.group(0) # Specifying 0 gives the same result as specifying no argument # Out: '123' buscando Labúsquedaserealizaencualquierpartedelacadenaadiferenciadere.match .También puedes usar re.findall . También puede buscar al principio de la cadena (use ^ ), al final de la cadena (use $ ), o ambos (use ambos ^ y $ ): Agrupamiento La agrupación se realiza entre paréntesis. El group() llamada group() devuelve una cadena formada por los subgrupos paréntesis coincidentes.
    • 437. 372 # Out: ('phone', '672-123-456-9910') m.group(1, 2) # Multiple arguments give us a tuple. # Out: '672-123-456-9910' m.group(2) # The second parenthesized subgroup. m.group(1) # The first parenthesized subgroup. # Out: 'phone' # Out: 'This is a phone number 672-123-456-9910' m.group(0) # The entire match as a string # Out: 'This is a phone number 672-123-456-9910' m.group() # The entire match as a string sentence= "Thisis a phonenumber 672-123-456-9910" pattern = r".*(phone).*?([\d-]+)" match = re.match(pattern, sentence) match.groups() # The entire match as a list of tuples of the paranthesized subgroups # Out: ('phone', '672-123-456-9910') match = re.search(r'My name is (?P<name>[A-Za-z ]+)', 'My name is John Smith') match.group('name') # Out: 'John Smith' match.group(1) # Out: 'John Smith' re.match(r'(\d+)(\+(\d+))?', '11+22').groups() # Out: ('11', '+22', '22') También se pueden proporcionar argumentos a group() para obtener un subgrupo en particular. De la documentación : Si hay un solo argumento, el resultado es una sola cadena; Si hay varios argumentos, el resultado es una tupla con un elemento por argumento. Al llamar a groups() por otro lado, devuelve una lista de tuplas que contienen los subgrupos. Grupos nombrados Crea un grupo de captura al que se puede hacer referencia por nombre y por índice. Grupos no capturadores Usar (?:) crea un grupo, pero el grupo no se captura. Esto significa que puede usarlo como grupo, pero no contaminará su "espacio grupal".
    • 438. 373 match = re.search(r'[b]', 'a[b]c') match.group() # Out: 'b' match = re.search(r'\[b\]', 'a[b]c') match.group() # Out: '[b]' re.escape('a[b]c') # Out: 'a\\[b\\]c' match = re.search(re.escape('a[b]c'), 'a[b]c') match.group() # Out: 'a[b]c' username = 'A.C.' # suppose this came from the user re.findall(r'Hi {}!'.format(username), 'Hi A.C.! Hi ABCD!') # Out: ['Hi A.C.!', 'Hi ABCD!'] re.findall(r'Hi {}!'.format(re.escape(username)), 'Hi A.C.! Hi ABCD!') # Out: ['Hi A.C.!'] re.sub(r"t[0-9][0-9]", "foo", "my name t13 is t44 what t99 ever t44") # Out: 'my name foo is foo what foo ever foo' Este ejemplo coincide con 11+22 u 11 , pero no con 11+ . Esto se debe a que el signo + y el segundo término están agrupados. Por otro lado, el signo + no es capturado. Escapar de personajes especiales Loscaracteresespeciales(comoloscorchetesdelaclasedecaracteres[ y] continuación)nose corresponden literalmente: Al escapar de los caracteres especiales, pueden emparejarse literalmente: La función re.escape() se puede utilizar para hacer esto por usted: La función re.escape() escapa a todos los caracteres especiales, por lo que es útil si está componiendo una expresión regular basada en la entrada del usuario: Reemplazo Los reemplazos se pueden hacer en cadenas usando re.sub . Reemplazo de cuerdas re.match(r'(\d+)(?:\+(\d+))?', '11+22').groups() # Out: ('11', '22')
    • 439. 374 re.sub(r"t([0-9])([0-9])", r"t\2\1", "t13 t19 t81 t25") # Out: 't31 t91 t18 t52' re.sub(r"t([0-9])([0-9])", r"t\g<2>\g<1>", "t13 t19 t81 t25") # Out: 't31 t91 t18 t52' items = ["zero", "one", "two"] re.sub(r"a\[([0-3])\]", lambda match: items[int(match.group(1))], "Items: a[0], a[1], something, a[2]") # Out: 'Items: zero, one, something, two' re.findall(r"[0-9]{2,3}", "some 1 text 12 is 945 here 4445588899") # Out: ['12', '945', '444', '558', '889'] results = re.finditer(r"([0-9]{2,3})", "some 1 text 12 is 945 here 4445588899") print(results) # Out: <callable-iterator object at 0x105245890> for result in results: print(result.group(0)) ''' Out: 12 945 444 558 889 ''' import re Usando referencias de grupo Los reemplazos con un pequeño número de grupos se pueden hacer de la siguiente manera: Sin embargo, si crea una ID de grupo como '10', esto no funciona : \10 se lee como 'ID número 1 seguido de 0'. Por lo tanto, debe ser más específico y usar la notación \g<i> : Usando una función de reemplazo Encontrar todos los partidos no superpuestos Tengaencuentaquelarantesde "[0-9]{2,3}" lediceapythonqueinterpretelacadenacomo está; como una cadena "sinprocesar". Tambiénpuedeusarre.finditer()quefunciona dela misma manera quere.findall() pero devuelve uniterador con objetos SRE_Match lugar de una lista de cadenas: Patrones precompilados
    • 440. 375 import re precompiled_pattern = re.compile(r"(.*\d+)") matches = precompiled_pattern.match("The answer is 41!") print(matches.group(1)) # Out: The answer is 41 matches = precompiled_pattern.match("Or was it 42?") print(matches.group(1)) # Out: Or was it 42 import re def is_allowed(string): characherRegex = re.compile(r'[^a-zA-Z0-9.]') string = characherRegex.search(string) return not bool(string) print (is_allowed("abyzABYZ0099")) # Out: 'True' print (is_allowed("#*@#$%^")) # Out: 'False' La compilación de un patrón permite su reutilización posterior en un programa. Sin embargo, tenga en cuenta que Python almacena en caché las expresiones utilizadas recientemente ( docs , SO answer ), por lo que "los programas que usan solo unas pocas expresiones regulares a la vez no tienen que preocuparse de compilar expresiones regulares" . Se puede utilizar con re.match (). Comprobación de caracteres permitidos Si desea comprobar que una cadena contiene solo un determinado conjunto de caracteres, en este caso az, AZ y 0-9, puede hacerlo así: También puede adaptar la línea de expresión de [^a-zA-Z0-9.] [^a-z0-9.] , Por ejemplo, para no permitir letras en mayúsculas. Crédito parcial: http://stackoverflow.com/a/1325265/2697955 Dividir una cadena usando expresiones regulares También puedes usar expresiones regulares para dividir una cadena. Por ejemplo, precompiled_pattern = re.compile(r"(\d+)") matches = precompiled_pattern.search("The answer is 41!") matches.group(1) # Out: 41 matches = precompiled_pattern.search("Or was it 42?") matches.group(1) # Out: 42
    • 441. 376 m = re.search("b", "ABC") m is None # Out: True m = re.search("b", "ABC", flags=re.IGNORECASE) m.group() # Out: 'B' m =re.search("a.b", "A\nBC", flags=re.IGNORECASE) m is None # Out: True m = re.search("a.b", "A\nBC", flags=re.IGNORECASE|re.DOTALL) m.group() # Out: 'A\nB' Banderas Para algunos casos especiales, necesitamos cambiar el comportamiento de la Expresión regular, esto se hace usando indicadores. Los indicadores se pueden establecer de dos maneras, a través de la palabra clave de flags o directamente en la expresión. Bandera de palabras clave Debajo de un ejemplo para re.search pero funciona para la mayoría de las funciones en el módulo re . Banderas comunes Bandera Breve descripción re.IGNORECASE ,re.I Hace que el patrón ignore el caso. re.DOTALL , re.S Hace . combina todo, incluyendo nuevas líneas re.MULTILINE , re.M Hace ^ coincida con el comienzo de una línea y $ el final de una línea re.DEBUG Activa la información de depuración Para la lista completa de todas las banderas disponibles verifique los documentos Banderas en linea De la documentación : (?iLmsux) import re data = re.split(r'\s+', 'James 94 Samantha 417 Scarlett 74') print( data ) # Output: ['James', '94', 'Samantha', '417', 'Scarlett', '74']
    • 442. 377 import re text = 'You can try to find anant in this string' pattern = 'an?\w' # find 'an' either with or without a following word character for match in re.finditer(pattern, text): # Start index of match (integer) sStart = match.start() # Final index of match (integer) sEnd = match.end() # Complete match (string) sGroup = match.group() # Print match print('Match "{}" found at: [{},{}]'.format(sGroup, sStart,sEnd)) Match "an" found at: [5,7] Match "an" found at: [20,22] Match "ant" found at: [23,26] An apple a day keeps the doctor away (I eat an apple everyday). (Una o más letras del conjunto 'i', 'L', 'm', 's', 'u', 'x'.) El grupo coincide con la cadena vacía; las letras establecen los indicadores correspondientes: re.I (ignorar mayúsculas y minúsculas), re.L (dependiente del entorno local), re.M (multilínea), re.S (punto corresponde a todos), re.U (dependiente de Unicode) y re.X (verbose), para toda la expresión regular. Esto es útil si desea incluir las banderas como parte de la expresión regular, en lugar de pasar un argumento de bandera a la función re.compile (). Tenga en cuenta que el indicador (? X) cambia la forma en que se analiza la expresión. Debe usarse primero en la cadena de expresión o después de uno o más caracteres de espacio en blanco. Si hay caracteres que no son espacios en blanco antes de la bandera, los resultados no están definidos. Iterando sobre los partidos usando `re.finditer` Puede usar re.finditer para iterar sobre todas las coincidencias en una cadena. Esto le proporciona (en comparación con re.findall información adicional, como información sobre la ubicación de coincidencia en la cadena (índices): Resultado: Unir una expresión solo en lugares específicos A menudo, usted quiere hacer coincidir una expresión solo en lugares específicos (dejándolos intactos en otros, es decir). Considera la siguiente oración: Aquí, la "manzana" aparece dos veces, lo que se puede resolver con los llamados verbos de
    • 443. 378 import regex as re string = "An apple a day keeps the doctor away (I eat an apple everyday)." rx = re.compile(r''' \([^()]*\) (*SKIP)(*FAIL) # match anything in parentheses and "throw it away" | # or apple # match an apple ''', re.VERBOSE) apples = rx.findall(string) print(apples) # only one forget_this | or this | and this as well | (but keepthis) control de seguimiento inverso que son compatibles con el módulo de regex más nuevo. La idea es: Con nuestro ejemplo de manzana, esto sería: Esto coincide con "manzana" solo cuando se puede encontrar fuera de los paréntesis. Así es como funciona: • Mientras miradeizquierda a derecha ,el motorde expresiones regulares consume todoa la izquierda, (*SKIP) actúa como una "afirmación de siempre verdadera". Después, falla correctamente en (*FAIL) y retrocede. • Ahora llega al punto de (*SKIP) de derecha a izquierda (también conocido como retroceso) en el que está prohibido ir más hacia la izquierda. En su lugar, se le dice al motor que tire cualquier cosa a la izquierda y salte al punto donde se invocó (*SKIP) .
    • 444. 379 #include <Python.h> #include <stdio.h> #if PY_MAJOR_VERSION >= 3 #define IS_PY3K #endif static PyObject *hello_greet(PyObject *self, PyObject *args) { const char *input; if (!PyArg_ParseTuple(args, "s", &input)) { return NULL; } printf("%s", input); Py_RETURN_NONE; } static PyMethodDef HelloMethods[] = { { "greet", hello_greet, METH_VARARGS, "Greet the user" }, { NULL, NULL, 0, NULL } }; #ifdef IS_PY3K static struct PyModuleDef hellomodule = { PyModuleDef_HEAD_INIT, "hello", NULL, -1, HelloMethods }; PyMODINIT_FUNC PyInit_hello(void) { return PyModule_Create(&hellomodule); } #else PyMODINIT_FUNC inithello(void) { (void) Py_InitModule("hello", HelloMethods); } #endif Capítulo 82: Extensiones de escritura Examples Hola mundo con extensión C ElsiguientearchivofuentedeC(quellamaremoshello.c parapropósitosdedemostración) produceunmódulodeextensiónllamadohello quecontieneunafunciónsimplegreet() : Para compilar el archivo con el compilador gcc , ejecute el siguiente comando en su terminal favorito: gcc /path/to/your/file/hello.c -o /path/to/your/file/hello Paraejecutarlafuncióngreet()queescribimosanteriormente,creeunarchivoenelmismo directorio y hello.py
    • 445. 380 PyObject *fobj; int fd = PyObject_AsFileDescriptor(fobj); if (fd < 0){ return NULL; } int fd; /* Existing file descriptor */ PyObject *fobj = PyFile_FromFd(fd, "filename","r",-1,NULL,NULL,NULL,1); #include <boost/python/module.hpp> #include <boost/python/list.hpp> #include <boost/python/class.hpp> #include <boost/python/def.hpp> // Return a hello world string. std::string get_hello_function() { return "Hello world!"; } // hello classthat can return a list of count hello world strings. class hello_class { public: // Taking the greeting message in the constructor. hello_class(std::string message) : _message(message) {} // Returns the message count times in a python list. boost::python::list as_list(int count) { Pasando un archivo abierto a C Extensions Pase un objeto de archivo abierto de Python a código de extensión C. Puede convertir el archivo a un descriptor de archivo entero usando la función PyObject_AsFileDescriptor : Para convertir un descriptor de archivo entero de nuevo en un objeto de Python, use PyFile_FromFd . Extensión C usando c ++ y Boost Este es un ejemplo básico de una extensión C que usa C ++ y Boost . Código C ++ Código C ++ puesto en hello.cpp: hello.greet("Hello!") # runs the greet() function with "Hello!" as an argument import hello # imports the compiled library
    • 446. 381 sudo apt-get install gcc libboost-dev libpython3.4-dev gcc -shared -o hello.so -fPIC -I/usr/include/python3.4 hello.cpp -lboost_python-py34 - lboost_system -l:libpython3.4m.so import hello print(hello.get_hello()) h = hello.Hello("World hello!") print(h.as_list(3)) Hello world! ['World hello!', 'World hello!', 'World hello!'] Para compilar esto en un módulo de python, necesitarás los encabezados de python y las bibliotecas boost. Este ejemplo se hizo en Ubuntu 12.04 usando python 3.4 y gcc. Boost es compatible con muchas plataformas. En el caso de Ubuntu, los paquetes necesarios se instalaron usando: Compilando el archivo fuente en un archivo .so que luego se puede importar como un módulo siempre que esté en la ruta de acceso de python: El código de python en el archivo example.py: Entonces python3 example.py dará el siguiente resultado: boost::python::list res; for (int i = 0; i < count; ++i) { res.append(_message); } return res; } private: std::string _message; }; // Defining a python module naming it to "hello". BOOST_PYTHON_MODULE(hello) { // Here you declare what functions and classes that should be exposed on the module. // The get_hello_function exposed to python as a function. boost::python::def("get_hello", get_hello_function); // The hello_class exposed to python as a class. boost::python::class_<hello_class>("Hello", boost::python::init<std::string>()) .def("as_list", &hello_class::as_list) ; }
    • 447. 382 escritura
    • 448. 383 import datetime dt = datetime.datetime.strptime("2016-04-15T08:27:18-0500", "%Y-%m-%dT%H:%M:%S%z") import dateutil.parser dt = dateutil.parser.parse("2016-04-15T08:27:18-0500") datetime.datetime(2016, 4, 15, 8, 27, 18, tzinfo=tzoffset(None, -18000)) import datetime today = datetime.date.today() print('Today:', today) yesterday = today - datetime.timedelta(days=1) print('Yesterday:', yesterday) tomorrow = today + datetime.timedelta(days=1) print('Tomorrow:', tomorrow) Capítulo 83: Fecha y hora Observaciones Python proporciona métodos integrados y bibliotecas externas para crear, modificar, analizar y manipular fechas y horas. Examples Análisis de una cadena en un objeto de fecha y hora compatible con la zona horaria Python 3.2+ admite el formato %z al analizar una cadena en un objeto de datetime y datetime . +HHMM UTC en la forma +HHMM o -HHMM (cadena vacía si el objeto es ingenuo). Python 3.x 3.2 ParaotrasversionesdePython,puedeusarunabibliotecaexternacomodateutil,quehaceque el análisis de una cadena con zona horaria en un objeto de datetime y datetime sea rápido. La variable dt ahora es un objeto de datetime y datetime con el siguiente valor: Aritmética de fecha simple Las fechas no existen de forma aislada. Es común que necesite encontrar la cantidad de tiempo entre las fechas o determinar cuál será la fecha de mañana. Esto se puede lograr usando objetos timedelta
    • 449. 384 Today: 2016-04-15 Yesterday: 2016-04-14 Tomorrow: 2016-04-16 Difference between tomorrow and yesterday: 2 days, 0:00:00 import datetime # Date object today = datetime.date.today() new_year = datetime.date(2017, 01, 01) #datetime.date(2017, 1, 1) # Time object noon = datetime.time(12, 0, 0) #datetime.time(12, 0) # Current datetime now = datetime.datetime.now() # Datetime object millenium_turn = datetime.datetime(2000, 1, 1, 0, 0, 0) #datetime.datetime(2000, 1, 1, 0, 0) # subtraction of noon from today noon-today Traceback (most recent call last): File "<stdin>", line 1, in<module> TypeError:unsupportedoperandtype(s)for-:'datetime.time' and'datetime.date' However, it is straightforward to convert between types. # Do this instead print('Time since the millenium at midnight: ', datetime.datetime(today.year, today.month, today.day) - millenium_turn) # Or this print('Time since the millenium at noon: ', datetime.datetime.combine(today, noon) - millenium_turn) import datetime Esto producirá resultados similares a: Uso básico de objetos datetime El módulo datetime contiene tres tipos principales de objetos: fecha, hora y fecha y hora. Las operaciones aritméticas para estos objetos solo se admiten dentro del mismo tipo de datos y realizar una aritmética simple con instancias de diferentes tipos resultará en un error de tipo. Iterar sobre fechas Aveces desea iterar en un rango de fechas desde una fecha de inicio hasta una fecha de finalización. Puedes hacerlo usando la biblioteca datetime y el objeto timedelta : print('Time between tomorrow and yesterday:', tomorrow - yesterday)
    • 450. 385 2016-07-21 2016-07-22 2016-07-23 2016-07-24 2016-07-25 2016-07-26 2016-07-27 from dateutil import tz from dateutil.parser import parse ET = tz.gettz('US/Eastern') CT = tz.gettz('US/Central') MT = tz.gettz('US/Mountain') PT = tz.gettz('US/Pacific') us_tzinfos = {'CST': CT, 'CDT': CT, 'EST': ET, 'EDT': ET, 'MST': MT, 'MDT': MT, 'PST': PT, 'PDT': PT} dt_est = parse('2014-01-02 04:00:00 EST', tzinfos=us_tzinfos) dt_pst = parse('2016-03-11 16:00:00 PST', tzinfos=us_tzinfos) dt_est # datetime.datetime(2014, 1, 2, 4, 0, tzinfo=tzfile('/usr/share/zoneinfo/US/Eastern')) dt_pst Lo que produce: Analizar una cadena con un nombre de zona horaria corto en un objeto de fecha y hora con fecha horaria Al usar la biblioteca dateutil como en el ejemplo anterior en el análisis de las marcas de tiempo dateutil en la zona horaria , también es posible analizar las marcas de tiempo con un nombre de zona horaria "corto" especificado. Para fechas formateadas con nombres de zonas horarias cortas o abreviaturas, que generalmente son ambiguas (p. Ej., CST, que podrían ser la Hora estándar central, la Hora estándar de China, la Hora estándar de Cuba, etc.) o puede encontrar más información aquí o no necesariamente están disponibles en una base de datos estándar , es necesario especificar una asignación entre la abreviatura de zona horaria y el objeto tzinfo . Después de ejecutar esto: # The size of each step in days day_delta = datetime.timedelta(days=1) start_date = datetime.date.today() end_date = start_date + 7*day_delta for i in range((end_date - start_date).days): print(start_date + i*day_delta)
    • 451. 386 from dateutil.parser import parse import pytz EST = pytz.timezone('America/New_York') dt = parse('2014-02-03 09:17:00 EST', tzinfos={'EST': EST}) dt.tzinfo # Will be in Local Mean Time! # <DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD> dt_fixed = dt.tzinfo.localize(dt.replace(tzinfo=None)) dt_fixed.tzinfo # Now it's EST. # <DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>) from datetime import datetime, timedelta, timezone JST = timezone(timedelta(hours=+9)) dt = datetime(2015, 1, 1, 12, 0, 0, tzinfo=JST) print(dt) # 2015-01-01 12:00:00+09:00 print(dt.tzname()) # UTC+09:00 dt = datetime(2015, 1, 1, 12, 0, 0, tzinfo=timezone(timedelta(hours=9), 'JST')) print(dt.tzname) # 'JST' Vale la pena señalar que si utiliza una zona horaria de pytz con este método, no se localizará correctamente: Esto simplemente adjunta la zona horaria de pytz a la fecha y hora: Siutilizaestemétodo,probablementedeberíavolveralocalize laparteingenuadelafechay hora después del análisis: Construyendo tiempos de datos conscientes de la zona horaria Por defecto, todos los objetos de datetime y datetime son ingenuos. Para que sean conscientes de la zona horaria, debe adjuntar un objeto tzinfo , que proporciona el desplazamiento UTC y la abreviatura de la zona horaria en función de la fecha y la hora. Zonas horarias de compensación Para las zonas horarias que son un desplazamiento fijo de UTC, en Python 3.2+, el módulo datetime proporciona la clase de timezone , una implementación concreta de tzinfo , que toma un timedelta y un parámetro de nombre (opcional): Python 3.x 3.2 Para versiones de Python anteriores a 3.2, es necesario usar una biblioteca de terceros, como # datetime.datetime(2016, 3, 11, 16, 0, tzinfo=tzfile('/usr/share/zoneinfo/US/Pacific'))
    • 452. 387 from datetime import datetime, timedelta from dateutil import tz JST = tz.tzoffset('JST', 9 * 3600) # 3600 seconds per hour dt = datetime(2015, 1, 1, 12, 0, tzinfo=JST) print(dt) # 2015-01-01 12:00:00+09:00 print(dt.tzname) # 'JST' from datetime import datetime from dateutil import tz local = tz.gettz() # Local time PT = tz.gettz('US/Pacific') # Pacific time dt_l = datetime(2015, 1, 1, 12, tzinfo=local) # I am in EST dt_pst = datetime(2015, 1, 1, 12, tzinfo=PT) dt_pdt = datetime(2015, 7, 1, 12, tzinfo=PT) # DST is handled automatically print(dt_l) # 2015-01-01 12:00:00-05:00 print(dt_pst) # 2015-01-01 12:00:00-08:00 print(dt_pdt) # 2015-07-01 12:00:00-07:00 from datetime import datetime, timedelta dateutil. dateutilproporciona unaclaseequivalente, tzoffset, que(apartir delaversión 2.5.3) toma argumentos de la forma dateutil.tz.tzoffset(tzname, offset) , donde el offset se especifica en segundos: Python 3.x 3.2 Python 2.x 2.7 Zonas con horario de verano. Para las zonas con horario de verano, las bibliotecas estándar de Python no proporcionan una clase estándar, por lo que es necesario utilizar una biblioteca de terceros. pytz y dateutil son bibliotecas populares que proporcionan clases de zona horaria. Además de las zonas horarias estáticas, dateutil proporciona clases de zonas dateutil que utilizan el horario de verano (consulte la documentación del módulo tz ).Puede usar el método tz.gettz()para obtener un objeto de zona horaria, que luego se puede pasar directamente al constructor de datetime : PRECAUCIÓN : A partir de la versión 2.5.3, dateutil no maneja dateutil ambiguos correctamente, ysiempreseestableceráde formapredeterminadaenlafechaposterior.Nohay formadeconstruir unobjetoconunadateutilrepresente lazona horaria,porejemplo, 2015-11-01 1:30 EDT-4 , ya que esto es durante una transición de horario deverano. Todosloscasosdebordesemanejan correctamente cuandoseusapytz , perolas zonas horariasdepytz nosedebenpytzdirectamentealaszonashorariasa travésdel constructor.En su lugar, se debe adjuntar una zona horaria de pytz usando el método de localize la zona horaria:
    • 453. 388 dt_new = dt_pdt + timedelta(hours=3) # This should be 2:30 AM PST print(dt_new) # 2015-11-01 03:30:00-07:00 dt_corrected = PT.normalize(dt_new) print(dt_corrected) # 2015-11-01 02:30:00-08:00 from dateutil.parser import parse dt = parse("Today isJanuary 1, 2047 at 8:21:00AM",fuzzy=True) print(dt) from datetime import datetime from dateutil import tz utc = tz.tzutc() local = tz.tzlocal() utc_now = datetime.utcnow() utc_now # Not timezone-aware. utc_now = utc_now.replace(tzinfo=utc) utc_now # Timezone-aware. local_now = utc_now.astimezone(local) local_now # Converted to local time. Tenga en cuenta que si realiza aritmética de fecha y hora en una pytz horaria de pytz -aware, debe realizarlos cálculos en UTC (si desea un tiempo transcurrido absoluto), o debe llamar a normalize() en el resultado: Análisis de fecha y hora difuso (extracción de fecha y hora de un texto) Es posible extraer una fecha de un texto usando el analizador de dateutil en un modo "borroso", donde los componentes de la cadena que no se reconocen como parte de una fecha se ignoran. dt ahora es un objeto datetime y vería datetime.datetime(2047, 1, 1, 8, 21) impreso. Cambio entre zonas horarias Para cambiar entre zonas horarias, necesita objetos de fecha y hora que tengan en cuenta la zona horaria. import pytz PT = pytz.timezone('US/Pacific') dt_pst = PT.localize(datetime(2015, 1, 1, 12)) dt_pdt = PT.localize(datetime(2015, 11, 1, 0, 30)) print(dt_pst) # 2015-01-01 12:00:00-08:00 print(dt_pdt) # 2015-11-01 00:30:00-07:00
    • 454. 389 str(datetime.datetime(2016, 7, 22, 9, 25, 59, 555555)) # '2016-07-22 09:25:59.555555' str(datetime.datetime(2016, 7, 22, 9, 25, 59, 0)) # '2016-07-22 09:25:59' import iso8601 iso8601.parse_date('2016-07-22 09:25:59') # datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>) iso8601.parse_date('2016-07-22 09:25:59+03:00') # datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<FixedOffset '+03:00' ...>) iso8601.parse_date('2016-07-22 09:25:59Z') # datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>) iso8601.parse_date('2016-07-22T09:25:59.000111+03:00') # datetime.datetime(2016, 7, 22, 9, 25, 59, 111, tzinfo=<FixedOffset '+03:00' ...>) iso8601.parse_date('2016-07-22T09:25:59', default_timezone=None) # datetime.datetime(2016, 7, 22, 9, 25, 59) iso8601.parse_date('2016- 07-22T09:25:59Z', default_timezone=None) # datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>) Análisis de una marca de tiempo ISO 8601 arbitraria con bibliotecas mínimas Python solo tiene soporte limitado para analizar las marcas de tiempo ISO 8601. Para strptime necesitasaberexactamenteenquéformatoseencuentra.Comocomplicación,laclasificaciónde una datetime y datetime es una marca de tiempo ISO 8601, con espacio como separador y fracción de 6 dígitos: pero si la fracción es 0, no se genera ninguna parte fraccionaria Peroestas2formasnecesitanunformatodiferenteparastrptime.Además,strptime'doesnot support at all parsing minute timezones that have a : in it, thus can be parsed, but the standard format2016-07-2209:25:59+0300canbeparsed,butthestandardformat2016-07-2209:25:59 +03: 00` no puedo. Hay una biblioteca de un solo archivo llamada iso8601 que analiza correctamente las marcas de tiempo ISO 8601 y solo ellas. Admite fracciones y zonas horarias, y el separador en T todo con una sola función: Si no se establece una zona horaria, iso8601.parse_date se establece de iso8601.parse_date predeterminadaenUTC.Lazonapredeterminadasepuedecambiar conel argumentodepalabra clave default_zone . En particular, si esto es None lugar del predeterminado, entonces las marcas de tiempo que no tienen una zona horaria explícita se devuelven como tiempos de referencia ingenuos: Convertir la marca de tiempo a datetime El módulo datetime puede convertir una timestamp de timestamp POSIX en un objeto datetime ITC.
    • 455. 390 import time from datetime import datetime seconds_since_epoch=time.time() #1469182681.709 utc_date=datetime.utcfromtimestamp(seconds_since_epoch) #datetime.datetime(2016, 7, 22, 10, 18, 1, 709000) import calendar from datetime import date def monthdelta(date, delta): m, y = (date.month+delta) % 12, date.year + ((date.month)+delta-1) // 12 if not m: m = 12 d = min(date.day, calendar.monthrange(y, m)[1]) return date.replace(day=d,month=m, year=y) next_month = monthdelta(date.today(), 1) #datetime.date(2016, 10, 23) import datetime import dateutil.relativedelta d = datetime.datetime.strptime("2013-03-31", "%Y-%m-%d") d2 = d - dateutil.relativedelta.relativedelta(months=1) #datetime.datetime(2013, 2, 28, 0, 0) from datetime import datetime, timedelta now = datetime.now() then = datetime(2016, 5, 23) # datetime.datetime(2016, 05, 23, 0, 0, 0) delta = now-then print(delta.days) # 60 print(delta.seconds) # 40826 La época es el 1 de enero de 1970 a medianoche. Restar meses de una fecha con precisión Usando el módulo de calendar Usando el módulo dateutils Calcular las diferencias de tiempo timedelta módulo timedelta es útil para calcular las diferencias entre los tiempos: Especificar el tiempo es opcional al crear un nuevo objeto de datetime delta es de tipo timedelta Para obtener n día después y n día antes de la fecha podríamos usar:
    • 456. 391 def get_n_days_after_date(date_format="%d %B %Y", add_days=120): date_n_days_after = datetime.datetime.now() + timedelta(days=add_days) return date_n_days_after.strftime(date_format) def get_n_days_before_date(self, date_format="%d %B %Y", days_before=120): date_n_days_ago = datetime.datetime.now() - timedelta(days=days_before) return date_n_days_ago.strftime(date_format) from datetime import datetime datetime.now().isoformat() # Out: '2016-07-31T23:08:20.886783' from datetime import datetime from dateutil.tz import tzlocal datetime.now(tzlocal()).isoformat() # Out: '2016-07-31T23:09:43.535074-07:00' from datetime import datetime from dateutil.tz import tzlocal datetime.now(tzlocal()).replace(microsecond=0).isoformat() # Out: '2016-07-31T23:10:30-07:00' día después de la fecha: n día anterior a la fecha: Obtener una marca de tiempo ISO 8601 Sin zona horaria, con microsegundos. Con zona horaria, con microsegundos. Con zona horaria, sin microsegundos. Consulte ISO 8601 para obtener más información sobre el formato ISO 8601.
    • 457. 392 names = ['Fred', 'Wilma', 'Barney'] def long_name(name): return len(name) > 5 filter(long_name, names) # Out: ['Barney'] [name for name in names if len(name) > 5] # equivalent list comprehension # Out: ['Barney'] from itertools import ifilter ifilter(long_name, names) # as generator (similar to python 3.x filter builtin) Capítulo 84: Filtrar Sintaxis • filtro (función, iterable) • itertools.ifilter (función, iterable) • future_builtins.filter (función, iterable) • itertools.ifilterfalse (función, iterable) • itertools.filterfalse (función, iterable) Parámetros Parámetro Detalles función llamable que determina la condición o None luego use la función de identidad para el filtrado ( solo de posición ) iterable iterable que será filtrado ( solo posicional ) Observaciones Enla mayoríadelos casos, una expresión de comprensióno generador es más legible, más potente y más eficiente que filter() o ifilter() . Examples Uso básico del filtro. Para filter descartan elementos de una secuencia en función de algunos criterios: Python 2.x 2.0
    • 458. 393 # Besides the options for older python 2.x versions there is a future_builtin function: from future_builtins import filter filter(long_name, names) # identical to itertools.ifilter # Out: <itertools.ifilter at 0x3eb0ba8> # Out: <filter at 0x1fc6e443470> list(filter(long_name, names)) # cast to list # Out: ['Barney'] (name for name in names if len(name) > 5) # equivalent generator expression # Out: <generator object <genexpr> at 0x000001C6F49BF4C0> filter(long_name, names) # returns a generator list(filter(None, [1, 0, 2, [], '', 'a'])) # discards 0, [] and '' # Out: [1, 2, 'a'] [i for i in [1, 0, 2, [], '', 'a'] if i] # equivalent list comprehension (i for i in [1, 0, 2, [], '', 'a'] if i) # equivalent generator expression #notrecommendedin real use but keepsthe example short: from itertools import ifilter as filter from future_builtins import filter Python 2.x 2.6 Python 3.x 3.0 Filtro sin función Si el parámetro de la función es None , se utilizará la función de identidad: Python 2.x 2.0.1 Python 3.x 3.0.0 Filtrar como comprobación de cortocircuito. filter(3.xpitón)yifilter(Python2.x)devuelveungenerador,asíquepuedesermuyútil cuando se crea un ensayo de cortocircuito como or o and : Python 2.x 2.0.1 Python 2.x 2.6.1 # Out: <itertools.ifilter at 0x4197e10> list(ifilter(long_name, names)) # equivalent to filter with lists # Out: ['Barney'] (name for name in names if len(name) > 5) # equivalent generator expression # Out: <generator object <genexpr> at 0x0000000003FD5D38>
    • 459. 394 # not recommended in real use but keepsthe example valid for python 2.x and python 3.x from itertools import ifilterfalse as filterfalse car_shop = [('Toyota', 1000), ('rectangular tire', 80), ('Porsche', 5000)] def find_something_smaller_than(name_value_tuple): print('Check {0}, {1}$'.format(*name_value_tuple) return name_value_tuple[1] < 100 next(filter(find_something_smaller_than, car_shop)) # Print: Check Toyota, 1000$ # Check rectangular tire,80$ # Out: ('rectangular tire', 80) from itertools import filterfalse # Usage without function (None): list(filterfalse(None, [1, 0, 2, [], '', 'a'])) # discards 1, 2, 'a' # Out: [0, [], ''] # Usage with function names = ['Fred', 'Wilma', 'Barney'] def long_name(name): return len(name) > 5 list(filterfalse(long_name, names)) # Out: ['Fred', 'Wilma'] # Short-circuit useage with next: car_shop = [('Toyota', 1000), ('rectangular tire', 80), ('Porsche', 5000)] def find_something_smaller_than(name_value_tuple): print('Check {0}, {1}$'.format(*name_value_tuple) return name_value_tuple[1] < 100 next(filterfalse(find_something_smaller_than, car_shop)) # Print: Check Toyota, 1000$ # Out: ('Toyota', 1000) Para encontrar el primer elemento que es más pequeño que 100: La next función proporciona el siguiente elemento (en este caso, primero) y es, por lo tanto, la razón por la que es un cortocircuito. Función complementaria: filterfalse, ifilterfalse Hayunafuncióncomplementaria para el filter en elmódulo itertools : Python 2.x 2.0.1 Python 3.x 3.0.0 quefuncionaexactamenteigualqueelfilter delgeneradorperomantienesololoselementos que son False :
    • 460. 395 # Using an equivalent generator: car_shop = [('Toyota', 1000), ('rectangular tire', 80), ('Porsche', 5000)] generator = (car for car in car_shop if not car[1] < 100) next(generator)
    • 461. 396 foo = 1 bar = 'bar' baz = 3.14 print('{}, {} and {}'.format(foo, bar, baz)) # Out: "1, bar and 3.14" print('{0}, {1}, {2}, and {1}'.format(foo, bar, baz)) Capítulo 85: Formato de cadena Introducción Cuando se almacenan y transforman datos para que los humanos los vean, el formato de cadena puede ser muy importante. Python ofrece una amplia variedad de métodos de formato de cadenas que se describen en este tema. Sintaxis • "{}". formato (42) ==> "42" • "{0}". Formato (42) ==> "42" • "{0: .2f}". Formato (42) ==> "42.00" • "{0: .0f}". Formato (42.1234) ==> "42" • "{answer}". formato (no_answer = 41, respuesta = 42) ==> "42" • "{answer: .2f}". format (no_answer = 41, answer = 42) ==> "42.00" • "{[clave]}". formato ({'clave': 'valor'}) ==> "valor" • "{[1]}". Formato (['cero', 'uno', 'dos']) ==> "uno" • "{answer} = {answer}". formato (respuesta = 42) ==> "42 = 42" • '' .join (['stack', 'overflow']) ==> "stack overflow" Observaciones • Debería visitar PyFormat.info para una introducción / explicación muy completa y suave de cómo funciona. Examples Conceptos básicos de formato de cadena Puedes usar str.format para formatear la salida. Los pares de corchetes se reemplazan con argumentos en el orden en que se pasan los argumentos: Los índices también se pueden especificar dentro de los corchetes. Los números corresponden a los índices de los argumentos pasados a la función str.format (basado en 0).
    • 462. 397 print("X value is: {x_val}. Y value is: {y_val}.".format(x_val=2, y_val=3)) # Out: "X value is: 2. Y value is: 3." class AssignValue(object): def init (self, value): self.value = value my_value=AssignValue(6) print('My value is: {0.value}'.format(my_value)) # "0" is optional # Out: "My value is: 6" my_dict = {'key': 6, 'other_key': 7} print("My other keyis: {0[other_key]}".format(my_dict)) # "0" is optional # Out: "My other key is: 7" my_list = ['zero', 'one', 'two'] print("2nd element is: {0[2]}".format(my_list)) # "0" is optional # Out: "2nd element is: two" '{:~^20}'.format('centered') # Out: '~~~~~~centered~~~~~~' t = (12, 45, 22222, 103, 6) print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*t) # Out: 12 22222 45 22222 103 22222 6 22222 Los argumentos con nombre también se pueden utilizar: Se puede hacer referencia a los atributos de los objetos cuando se pasan a str.format : Las claves del diccionario se pueden utilizar también: Lo mismo se aplica a los índices de lista y tupla: Nota: Además de str.format , Python también proporciona el operador de módulo % también conocido como operador de formateo o interpolación de cadenas (ver PEP 3101 ), para el formato de cadenas. str.format es un sucesor de % y ofrece una mayor flexibilidad, por ejemplo, al facilitar la realización de múltiples sustituciones. Además de los índices de argumentos, también puede incluir una especificación de formato dentro de los corchetes. Esta es una expresión que sigue reglas especiales y debe ser precedido por dos puntos ( : ). Consulte la documentación para obtener una descripción completa de la especificación de formato. Un ejemplo de especificación de formato es la directiva de alineación :~^20 ( ^ significa alineación central, ancho total 20, relleno con ~ carácter): format permite un comportamiento no posible con % , por ejemplo, la repetición de argumentos: # Out: "1, bar, 3.14, and bar" print('{0}, {1}, {2}, and {3}'.format(foo, bar, baz)) # Out: index out of range error
    • 463. 398 number_list = [12,45,78] print map('the number is {}'.format, number_list) #Out:['the numberis 12', 'the numberis 45', 'the numberis 78'] from datetime import datetime,timedelta once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0) delta = timedelta(days=13, hours=8, minutes=20) gen = (once_upon_a_time + x * delta for x in xrange(5)) print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen)) '{:~<9s}, World'.format('Hello') # 'Hello~~~~, World' '{:~>9s}, World'.format('Hello') # '~~~~Hello, World' '{:~^9s}'.format('Hello') # '~~Hello~~' '{:0=6d}'.format(-123) # '-00123' Como el format es una función, se puede usar como un argumento en otras funciones: #Out: 2010-07-01 12:00:00 # 2010-07-14 20:20:00 # 2010-07-28 04:40:00 # 2010-08-10 13:00:00 # 2010-08-23 21:20:00 Alineación y relleno. Python 2.x 2.6 El métodoformat() sepuedeusarparacambiarlaalineación delacadena. Tienesquehacerlo con una expresión de formato del formulario :[fill_char][align_operator][width] donde align_operator es uno de los siguientes: • < obliga al campo aalinearse ala izquierda dentrodel width . • > obliga al campoa alinearse aladerechadentro del width . • ^ obliga al campo a centrarse dentro de la width . • = obliga a que el relleno se coloque después del signo (solo tipos numéricos). fill_char (si se omite, el valor predeterminado es el espacio en blanco) es el carácter utilizado para el relleno. Nota: puede obtener los mismos resultados utilizando las funciones de cadena ljust() , rjust() , center() , zfill() , sin embargo, estas funciones están en desuso desde la versión 2.5. Formato literales (f-string)
    • 464. 399 >>> foo = 'bar' >>> f'Foo is {foo}' 'Foo is bar' >>> f'{foo:^7s}' ' bar ' >>> price = 478.23 >>> f"{f'${price:0.2f}':*>20s}" '*************$478.23' >>> def fn(l, incr): ... result = l[0] ... l[0] += incr ... return result ... >>> lst = [0] >>>f'{fn(lst,2)}{fn(lst,3)}' '0 2' >>>f'{fn(lst,2)}{fn(lst,3)}' '5 7' >>> lst [10] >>> from datetime import datetime >>> 'North America: {dt:%m/%d/%Y}. ISO: {dt:%Y-%m-%d}.'.format(dt=datetime.now()) 'North America: 07/21/2016. ISO: 2016-07-21.' Las cadenas de formato literal se introdujeron en PEP 498 (Python3.6 y versiones posteriores), lo que le permite anteponer f al comienzo de un literal de cadena para aplicar efectivamente el .format con todas las variables en el alcance actual. Esto también funciona con cadenas de formato más avanzadas, incluida la alineación y la notación de puntos. Nota:Laf''nodenotauntipoparticularcomob''parabytes ouu''paraunicode enpython2.El formateo se aplica inmediatamente, lo que resulta en una agitación normal. Las cadenas de formato también se pueden anidar : Las expresiones en una cadena-f se evalúan en orden de izquierda a derecha. Esto es detectable solo si las expresiones tienen efectos secundarios: Formato de cadena con fecha y hora Cualquier clase puede configurar su propia sintaxis de formato de cadena a través del método format .UntipoenlabibliotecaestándardePythonquehaceunusoprácticodeestoesel tipo datetime , donde se pueden usar códigos de formato similares a strftime directamente dentro de str.format : Se puede encontrar una lista completa de la lista de formateadores de fecha y hora en la
    • 465. 400 person = {'first': 'Arthur', 'last': 'Dent'} '{p[first]} {p[last]}'.format(p=person) # 'Arthur Dent' class Person(object): first = 'Zaphod' last = 'Beeblebrox' '{p.first} {p.last}'.format(p=Person()) # 'Zaphod Beeblebrox' >>> '{0:.0f}'.format(42.12345) '42' >>> '{0:.1f}'.format(42.12345) '42.1' >>> '{0:.3f}'.format(42.12345) '42.123' >>> '{0:.5f}'.format(42.12345) '42.12345' >>> '{0:.7f}'.format(42.12345) '42.1234500' >>>'{:.3f}'.format(42.12345) '42.123' >>>'{answer:.3f}'.format(answer=42.12345) '42.123' >>> '{0:.3e}'.format(42.12345) '4.212e+01' >>> '{0:.0%}'.format(42.12345) '4212%' documentación oficial . Formato utilizando Getitem y Getattr Cualquier estructura de datos que admita getitem puede tener su estructura anidada formateada: A los atributos de los objetos se puede acceder usando getattr() : Formato flotante Lo mismo vale para otra forma de referenciar: Los números de punto flotante también se pueden formatear en notación científica o como porcentajes:
    • 466. 401 >>> s = 'Hello' >>> a, b, c = 1.12345, 2.34567, 34.5678 >>> digits = 2 >>> '{0}! {1:.{n}f}, {2:.{n}f}, {3:.{n}f}'.format(s, a, b, c, n=digits) 'Hello! 1.12, 2.35, 34.57' >>> '{0:x}'.format(10) # base 16, lowercase - Hexadecimal 'a' >>> '{0:X}'.format(10) # base 16, uppercase - Hexadecimal 'A' >>> '{:o}'.format(10) # base 8 - Octal '12' >>> '{:b}'.format(10) # base 2 - Binary '1010' >>> '{0:#b}, {0:#o}, {0:#x}'.format(42) # With prefix '0b101010, 0o52, 0x2a' >>> '8 bit: {0:08b}; Three bytes: {0:06x}'.format(42) # Add zero padding '8 bit: 00101010; Three bytes: 00002a' >>> r, g, b = (1.0, 0.4, 0.0) >>> '#{:02X}{:02X}{:02X}'.format(int(255 * r), int(255 * g), int(255 * b)) '#FF6600' >>> '{:x}'.format(42.0) Traceback (most recent call last): File "<stdin>", line 1, in<module> También puede combinar las notaciones {0} y {name} . Esto es especialmente útil cuando desea redondear todas las variables a un número de decimales preespecificado con 1 declaración : Formato de valores numéricos El método .format() puede interpretar un número en diferentes formatos, tales como: >>> '{:c}'.format(65) 'A' # Unicode character >>> '{:d}'.format(0x0a) '10' # base 10 >>> '{:n}'.format(0x0a) '10' # base 10 using current locale for separators Formato de enteros a diferentes bases (hex, oct, binario) Use el formato para convertir una tupla flotante RGB en una cadena hexadecimal de color: Solo se pueden convertir enteros:
    • 467. 402 object. format (self, format_spec) # Example in Python 2 - but can be easily applied to Python 3 class Example(object): def init (self,a,b,c): self.a, self.b, self.c = a,b,c def format (self, format_spec): """ Implement special semantics for the 's' format specifier """ # Reject anything that isn't an s if format_spec[-1] != 's': raise ValueError('{} format specifier not understood for this object', format_spec[:-1]) # Output in this example will be (<a>,<b>,<c>) raw = "(" + ",".join([str(self.a), str(self.b), str(self.c)]) + ")" # Honor the format language by using the inbuilt string format # Since we know the original format_spec ends in an 's' # we can take advantage of the str.format method with a # string argument we constructed above return "{r:{f}}".format( r=raw, f=format_spec ) inst = Example(1,2,3) print "{0:>20s}".format(inst) # out : (1,2,3) # Note how the right align and field width of 20 has been honored. Formato personalizado para una clase Nota: Todo lo siguiente se aplica al método str.format , así como a la función de format . En el texto de abajo, los dos sonintercambiables. Para cada valor que se pasa a la función de format , Python busca un método format para ese argumento. Por lo tanto, su propia clase personalizada puede tener su propio método format para determinar cómo la función de format mostrará y formateará su clase y sus atributos. Esto es diferente al método str , ya que en el método format puede tener en cuenta el idioma del formato, incluida la alineación, el ancho del campo, etc. e incluso (si lo desea) implementar sus propios especificadores de formato y sus propias extensiones de lenguaje de formato. 1 Por ejemplo : Nota: Si su clase personalizada no tiene un método format personalizado y se format una instancia de la clase a la función de format , Python2 siempre usará el valor de retorno del método str o el método repr para determinar qué imprimir (y si no ValueError: Unknown format code 'x' for object of type 'float'
    • 468. 403 >>> '{:.>10}'.format('foo') '.......foo' >>>'{:.>{}}'.format('foo',10) '....... foo' '{:{}{}{}}'.format('foo', '*', '^', 15) '******foo******' >>> data = ["a", "bbbbbbb", "ccc"] >>> m = max(map(len, data)) >>> for d in data: ... print('{:>{}}'.format(d, m)) a bbbbbbb ccc existe ninguno, entonces se utilizará la repr predeterminada), y deberá usar el especificador de formato s para formatearesto.ConPython3 , para pasar su clase personalizada a la función de format , necesitará definir el método format en su clase personalizada. Formateo anidado Algunos formatos pueden tomar parámetros adicionales, como el ancho de la cadena con formato o la alineación: También se pueden proporcionar como parámetros para format anidando más {} dentro de {} : Enelúltimo ejemplo,la cadenade formato'{:{}{}{}}'se modificaa '{:*^15}'(esdecir,"centroy pad con * a una longitud total de 15") antes de aplicarla a la cadena real 'foo' para ser formateada de esa manera. Esto puede ser útil en casos en que los parámetros no se conocen de antemano, por ejemplo al alinear datos tabulares: Acolchado y cuerdas truncantes, combinadas. Digamos que quieres imprimir variables en una columna de 3 caracteres. Nota: doblando { y } se les escapa. :{a:>3.3}: :{a:3.3}: combined {{:>3.3}} {{:3.3}} :{e:.3}: truncate {{:.3}} :{a:3}: s = """ pad {{:3}}
    • 469. 404 >>> data = {'first': 'Hodor', 'last': 'Hodor!'} >>> '{first} {last}'.format(**data) 'Hodor Hodor!' >>> '{first} {last}'.format_map(data) 'Hodor Hodor!' >>> '{first} {last}'.format(first='Hodor', last='Hodor!') 'Hodor Hodor!' Salida: pad {:3} :1 : truncate {:.3} :555: combined {:>3.3} : 1: {:3.3} :1 : {:3.3} :333: {:3.3} :555: Marcadores de posición nombrados Las cadenas de formato pueden contener marcadores de posición con nombre que se interpolan usando argumentos de palabras clave para dar format . Usando un diccionario (Python 2.x) Usando un diccionario (Python 3.2+) str.format_map permiteusardiccionariossintenerquedescomprimirlosprimero.Tambiénseusa la clase de data (que podría ser un tipo personalizado) en lugar de un dict recién llenado. Sin un diccionario: print (s.format(a="1"*1, c="3"*3, e="5"*5)) :{c:3.3}: :{e:3.3}: {{:3.3}} {{:3.3}} """
    • 470. 405 from datetime import datetime a = datetime(2016,10,06,0,0,0) b =datetime(2016,10,01,23,59,59) a-b # datetime.timedelta(4, 1) (a-b).days # 4 (a-b).total_seconds() # 518399.0 from datetime import datetime datetime_string = 'Oct 1 2016, 00:00:00' datetime_string_format = '%b %d %Y, %H:%M:%S' datetime.strptime(datetime_string, datetime_string_format) # datetime.datetime(2016, 10, 1, 0, 0) from datetime import datetime datetime_for_string = datetime(2016,10,1,0,0) datetime_string_format = '%b %d %Y, %H:%M:%S' datetime.strftime(datetime_for_string,datetime_string_format) # Oct 01 2016, 00:00:00 Capítulo 86: Formato de fecha Examples Tiempo entre dos fechas Analizando la cadena al objeto datetime Utiliza códigos de formato estándar C Salida de objetos de fecha y hora a cadena Utiliza códigos de formato estándar C
    • 471. 406 list(map(abs, [-1,-2,-3])) # [1, 2,3] [abs(i) for i in [-1,-2,-3]] # [1, 2, 3] import operator alist = [1,2,3] list(map(operator.add, alist, alist)) # [2, 4, 6] [i + j for i, j in zip(alist, alist)] # [2, 4,6] Capítulo 87: Función de mapa Sintaxis • mapa (función, iterable [, * additional_iterables]) • future_builtins.map (función, iterable [, * additional_iterables]) • itertools.imap (función, iterable [, * additional_iterables]) Parámetros Parámetro Detalles función función de mapeo (debe tomar tantos parámetros como haya iterables) ( solo de posición ) iterable la función se aplica a cada elemento de lo iterable ( solo posicional ) * vea iterable, pero tantos como desee ( opcional , solo posicional ) adicional_iterables Observaciones Todo lo que se puede hacer con el map también se puede hacer con comprehensions : Aunque necesitarías zip si tienes múltiples iterables: Las comprensiones de listas son eficientes y pueden ser más rápidas que el map en muchos casos, así que pruebe los tiempos de ambos enfoques si la velocidad es importante para usted. Examples Uso básico de map, itertools.imap y future_builtins.map La función de mapa es la más simple entre las incorporaciones de Python utilizadas para la programación funcional. map() aplica una función específica a cada elemento en un iterable:
    • 472. 407 map(len, names) # map() returns a list # Out: [4, 5, 6] from itertools import imap imap(len, names) # itertools.imap() returns a generator # Out: <itertools.imap at 0x405ea20> from future_builtins import map # contains a Python 3.x compatible map() map(len, names) # see below # Out: <itertools.imap instance at 0x3eb0a20> map(len, names) # map in Python 3.x is a class; its instances are iterable # Out: <map object at 0x00000198B32E2CF8> list(map(len, names)) # Out: [4, 5, 6] [len(item) for item in names] # equivalent to Python 2.x map() # Out: [4, 5, 6] (len(item) for item in names) # equivalent to Python 3.x map() # Out: <generator object <genexpr> at 0x00000195888D5FC0> list(map(abs, (1, -1, 2, -2, 3, -3))) # the call to `list` is unnecessary in 2.x # Out: [1, 1, 2, 2, 3, 3] map(lambda x:x*2, [1, 2, 3, 4, 5]) # Out: [2, 4, 6, 8, 10] Python 3.x 3.0 Seincluyeun map compatibleconPython3enel módulofuture_builtins: Python 2.x 2.6 Alternativamente, en Python 2 se puede usar imap de itertools para obtener un generador Python 2.x 2.3 Elresultadosepuedeconvertirexplícitamenteenunalist paraeliminarlasdiferenciasentre Python 2 y 3: map() puede reemplazarse por una lista equivalente de comprensión o expresión de generador : Mapeando cada valor en una iterable Por ejemplo, puedes tomar el valor absoluto de cada elemento: Función anónima también soporte para mapear una lista: names = ['Fred', 'Wilma', 'Barney']
    • 473. 408 def average(*args): return float(sum(args)) / len(args) # cast to float - only mandatory for python 2.x list(map(average, measurement1, measurement2, measurement3)) # Out: [102.0, 110.0, 95.0, 100.0] def to_percent(num): return num * 100 list(map(to_percent, [0.95, 0.75, 1.01, 0.1])) # Out: [95.0, 75.0, 101.0, 10.0] from functools import partial from operator import mul rate = 0.9 # fictitious exchange rate, 1 dollar = 0.9 euros dollars = {'under_my_bed': 1000, 'jeans': 45, 'bank': 5000} sum(map(partial(mul, rate), dollars.values())) # Out: 5440.5 def median_of_three(a, b, c): return sorted((a, b, c))[1] list(map(median_of_three, measurement1, measurement2)) list(map(median_of_three, measurement1, measurement2, measurement3, measurement3)) o convirtiendo valores decimales a porcentajes: o convertir dólares a euros (dado un tipo de cambio): functools.partial es una forma conveniente de corregir los parámetros de las funciones para que puedan usarse con map lugar de usar lambda o crear funciones personalizadas. Mapeo de valores de diferentes iterables. Por ejemplo, calculando el promedio de cada elemento i -ésimo de múltiples iterables: measurement1 = [100, 111, 99, 97] measurement2 = [102, 117, 91, 102] measurement3 = [104, 102, 95, 101] Hay diferentes requisitos si se pasa más de un iterable al map dependiendo de la versión de python: • La función debe tener tantos parámetros como sean iterables: TypeError: median_of_three () falta 1 argumento posicional requerido: 'c' TypeError: median_of_three () toma 3 argumentos posicionales pero se dieron 4
    • 474. 409 from itertools import imap from future_builtins import map as fmap # Different name to highlight differences import operator measurement1 = [100, 111, 99, 97] measurement2 = [102, 117] # Calculate difference between elements list(map(operator.sub, measurement1, measurement2)) import operator from itertools import imap measurement1 = [100, 111, 99, 97] measurement2 = [102, 117] # Calculate difference between elements list(imap(operator.sub, measurement1, measurement2)) # Out: [-2, -6] list(imap(operator.sub, measurement2, measurement1)) # Out: [2, 6] import operator measurement1 = [100, 111, 99, 97] measurement2 = [102, 117] # Calculate difference between elements list(map(operator.sub, measurement1, measurement2)) # Out: [-2, -6] list(map(operator.sub, measurement2, measurement1)) # Out: [2, 6] Python 2.x 2.0.1 • map : el mapeo se repite siempre y cuando un iterable aún no esté completamente consumido, pero no asuma None de los iterables totalmente consumidos: TypeError: tipo (s) de operando no compatibles para -: 'int' y 'NoneType' • itertools.imap y future_builtins.map : la asignación se detiene tan pronto como se detiene una iterable: Python 3.x 3.0.0 • La asignación se detiene tan pronto como se detiene una iterable: Transposición con mapa: uso de "Ninguno" como argumento de función (solo python 2.x) image = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    • 475. 410 list(map(None, *image)) insects = ['fly', 'ant', 'beetle', 'cankerworm'] f = lambda x: x + ' is an insect' print(list(map(f, insects))) # the function defined by f is executed on each item of the iterable insects list(map(None, *image)) # Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)] list(fmap(None, *image)) # Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)] list(imap(None, *image)) # Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)] image2 = [[1, 2, 3], [4, 5], [7, 8, 9]] list(map(None, *image2)) # Out: [(1, 4, 7), (2, 5, 8), (3, None, 9)] list(fmap(None, *image2)) # Out: [(1, 4, 7), (2, 5, 8)] list(imap(None, *image2)) # Out: [(1, 4, 7), (2, 5, 8)] # Fill missing values with None # ignore columns with missing values # dito Python 3.x 3.0.0 TypeError: el objeto 'NoneType' no se puede llamar Pero hay una solución para tener resultados similares: Series y mapeo paralelo map () es una función incorporada, lo que significa que está disponible en todas partes sin la necesidad de usar una declaración de 'importación'. Está disponible en todas partes, como print () Si observa el Ejemplo 5, verá que tuve que usar una declaración de importación antes de que pudiera usar una impresión bonita (pprint de importación). Así pprint no es una función incorporada Mapeo en serie En este caso, cada argumento de lo iterable se suministra como argumento a la función de mapeo en orden ascendente. Esto surge cuando solo tenemos un iterable para mapear y la función de mapeo requiere un solo argumento. Ejemplo 1 resultados en def conv_to_list(*args): return list(args) list(map(conv_to_list, *image)) # Out: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
    • 476. 411 print(list(map(len, insects))) # the len function is executed each item in the insect list [3, 3, 6, 10] carnivores = ['lion', 'tiger', 'leopard', 'arctic fox'] herbivores = ['african buffalo', 'moose', 'okapi', 'parakeet'] omnivores = ['chicken', 'dove', 'mouse', 'pig'] def animals(w, x, y, z): return '{0}, {1}, {2}, and {3} ARE ALL ANIMALS'.format(w.title(), x, y, z) # Too many arguments # observe here that map is trying to pass one item each from each of the four iterables to len. This leads len to complain that # it is being fed too many arguments print(list(map(len, insects, carnivores, herbivores, omnivores))) TypeError: len() takes exactly one argument (4 given) # Too few arguments # observe here that map is suppose to execute animal on individual elements of insects one-byone. But animals complain when # it only gets one argument, whereas it was expecting four. print(list(map(animals, insects))) TypeError: animals() missing 3 required positional arguments: 'x', 'y', and 'z' # here map supplies w, x, y, z with one value from across the list Ejemplo 2 resultados en Mapeo paralelo En este caso, cada argumento de la función de mapeo se extrae de todos los iterables (uno de cada iterable) en paralelo. Por lo tanto, el número de iterables suministrados debe coincidir con el número de argumentos requeridos por la función. Ejemplo 3 resultados en Ejemplo 4 resultados en Ejemplo 5 ['fly is an insect', 'ant is an insect', 'beetle is an insect', 'cankerworm is an insect']
    • 477. 412 ['Fly, lion, african buffalo, and chicken ARE ALL ANIMALS', 'Ant, tiger, moose, and dove ARE ALL ANIMALS', 'Beetle, leopard, okapi, and mouse ARE ALL ANIMALS', 'Cankerworm, arctic fox, parakeet, and pig ARE ALL ANIMALS'] resultados en import pprint pprint.pprint(list(map(animals, insects, carnivores, herbivores, omnivores)))
    • 478. 413 def f(): print(20) y = f y() # Output: 20 Capítulo 88: Funciones Introducción Las funciones en Python proporcionan un código organizado, reutilizable y modular para realizar un conjunto de acciones específicas. Las funciones simplifican el proceso de codificación, evitan la lógica redundante y hacen que el código sea más fácil de seguir. Este tema describe la declaración y la utilización de funciones en Python. Python tiene muchas funciones integradas como print() , input() , len() . Además de las funcionesintegradas,tambiénpuedecrearsuspropiasfuncionespararealizartrabajosmás específicos, que se denominan funciones definidas por el usuario . Sintaxis • def function_name ( arg1, ... argN, * args, kw1, kw2 = predeterminado, ..., ** kwargs ): declaraciones • lambda arg1, ... argN, * args, kw1, kw2 = predeterminado, ..., ** kwargs : expresión Parámetros Parámetro Detalles arg1 , ..., argN Argumentos regulares * args Argumentos posicionales sin nombre kw1 , ..., kwN Argumentos solo de palabra clave ** kwargs El resto de argumentos de palabras clave. Observaciones 5 cosas básicas que puedes hacer con las funciones: • Asignar funciones a variables • Definir funciones dentro de otras funciones ( funciones anidadas )
    • 479. 414 return "Hello "+ name + "!" return inner_fun greet = outer_fun("Sophia") print(greet()) # Output: Hello Sophia! # the variable name is available to the inner function def outer_fun(name): def inner_fun(): def function_name(parameters): statement(s) • Las funciones pueden devolver otras funciones. def f(y): def nth_power(x): return x ** y return nth_power # returns a function squareOf = f(2) cubeOf = f(3) squareOf(3) cubeOf(2) # function that returns the square of a number # function that returns the cube of a number # Output: 9 # Output: 8 • Las funciones se pueden pasar como parámetros a otras funciones. def a(x, y): print(x, y) def b(fun, str): fun('Hello',str) b(a, 'Sophia') # b has two arguments: a function and a string # Output: Hello Sophia • Las funciones internas tienen acceso al ámbito de cierre ( Cierre ) Recursos adicionales • Más sobre funciones y decoradores:https://www.thecodeship.com/patterns/guide-to-pythonfunction-decorators/ Examples Definiendo y llamando funciones simples. Usar la instrucción def es la forma más común de definir una función en python. Esta declaración es una declaración compuesta llamada cláusula única con la siguiente sintaxis: function_name se conoce como el identificador de la función. Dado que la definición de una función es una sentencia ejecutable, su ejecución vincula el nombre de la función con el objeto de la def f(a, b, y): def inner_add(a, b): # inner_add is hidden from outer code return a + b return inner_add(a, b)**y
    • 480. 415 def greet(): print("Hello") greet() # Out: Hello def greet_two(greeting): print(greeting) greet_two("Howdy") # Out: Howdy def greet_two(greeting="Howdy"): print(greeting) greet_two() # Out: Howdy def many_types(x): if x < 0: función que se puede llamar más adelante utilizando el identificador. parameters es una lista opcional de identificadores que se unen a los valores proporcionados como argumentos cuando se llama a la función. Una función puede tener un número arbitrario de argumentos separados por comas. statement(s) también conocidas como el cuerpo de la función ) son una secuencia no vacía de sentencias que se ejecutan cada vez que se llama a la función. Esto significa que el cuerpo de una función no puede estar vacío, como cualquier bloque con sangría . Este es un ejemplo de una definición de función simple cuyo propósito es imprimir Hello cada vez que se llama: Ahora llamemos a la función de greet() definida: Ese es otro ejemplo de una definición de función que toma un solo argumento y muestra el valor pasado cada vez que se llama a la función: Después de eso, la función greet_two() debe llamarse con un argumento: También puede dar un valor predeterminado a ese argumento de función: Ahora puedes llamar a la función sin dar un valor: Notaráque,adiferenciademuchosotros idiomas,nonecesitadeclararexplícitamenteun tipode devolución de la función. Las funcionesdePython pueden devolver valores de cualquier tipo a través de la palabra clave return . ¡Una función puede devolver cualquier número de tipos diferentes!
    • 481. 416 def do_nothing(): pass print(do_nothing()) # Out: None def give_me_five(): return 5 print(give_me_five()) # Print the returned value # Out: 5 # Print the saved returned value num =give_me_five() print(num) # Out: 5 print(give_me_five() + 10) # Out: 15 Mientras la persona que llama maneje esto correctamente, este es un código de Python perfectamente válido. Una función que llega al final de la ejecución sin una declaración de retorno siempre devolverá None : Como se mencionó anteriormente, una definición de función debe tener un cuerpo de función, una secuencia de sentencias no vacía. Por lo tanto, la instrucción de pass se utiliza como cuerpo de la función, que es una operación nula: cuando se ejecuta, no sucede nada. Hace lo que significa, salta. Es útil como marcador de posición cuando se requiere una declaración sintácticamente, pero no es necesario ejecutar ningún código. Devolviendo valores desde funciones Las funciones pueden return un valor que puede utilizardirectamente: o guarda el valor para su uso posterior: o use el valor para cualquier operación: Si se encuentra return en la función, la función se cerrará inmediatamente y las operaciones return "Hello!" else: return 0 print(many_types(1)) print(many_types(-1)) # Output: 0 Hello!
    • 482. 417 def give_me_another_five(): return 5 print('This statement will not be printed. Ever.') print(give_me_another_five()) # Out: 5 def give_me_two_fives(): return 5, 5 # Returns two 5 first, second = give_me_two_fives() print(first) # Out: 5 print(second) # Out: 5 def divide(dividend, divisor): # The names ofthe function and its arguments # The arguments are available by name in the body of the function print(dividend / divisor) divide(10, 2) # output: 5 divide(divisor=2, dividend=10) # output: 5 def make(action='nothing'): return action subsiguientes no se evaluarán: También puede return varios valores (en forma de tupla): Una función sin una declaración de return devuelve implícitamente None . De manera similar, una función con una declaración de return , pero sin valor de retorno o variable devuelve None . Definiendo una función con argumentos. Los argumentos se definen entre paréntesis después del nombre de la función: El nombre de la función y su lista de argumentos se denominan la firma de la función. Cada argumento nombrado es efectivamente una variable local de la función. Al llamar a la función, dé valores para los argumentos enumerándolos en orden o especifíquelos en cualquier orden usando los nombres de la definición de función: Definiendo una función con argumentos opcionales. Los argumentos opcionales se pueden definir asignando (usando = ) un valor predeterminado al nombre de argumento:
    • 483. 418 make("fun") # Out: fun make(action="sleep") # Out: sleep #The argument is optionalso the functionwill use the default value if the argument is # not passed in. make() # Out: nothing def func(value1, value2, optionalvalue=10): return '{0} {1} {2}'.format(value1, value2, optionalvalue1) print(func(1, 'a', 100)) # Out: 1 a 100 print(func('abc', 14)) # abc 14 10 print(func('This', optionalvalue='StackOverflow Documentation', value2='is')) # Out: This is StackOverflow Documentation Llamar a esta función es posible de 3 maneras diferentes: Advertencia Los tipos mutables (list, dict ,set ,etc.) deben tratarse con cuidado cuando se dan como atributopredeterminado .Cualquier mutación del argumento por defectolo cambiarápermanentemente.ConsulteDefinirunafunciónconargumentosmutables opcionales . Definiendo una función con múltiples argumentos. Uno puede dar a la función tantos argumentos como quiera, las únicas reglas fijas son que cada nombre de argumento debe ser único y que los argumentos opcionales deben estar después de los no opcionales: Al llamar a la función, puede dar cada palabra clave sin el nombre, pero el orden importa: O combinar dando los argumentos con nombre y sin. Entonces los que tienen nombre deben seguir a los que no tienen, pero el orden de los que tienen nombre no importa: Definiendo una función con un número arbitrario de argumentos. Número arbitrario de argumentos
    • 484. 419 def func(*args): # args will be a tuple containing all valuesthat are passed in for i in args: print(i) func(1, 2, 3) # Calling it with 3 arguments # Out: 1 # 2 # 3 list_of_arg_values = [1, 2, 3] func(*list_of_arg_values) # Calling it with list of values, * expands the list # Out: 1 # 2 # 3 func() # Calling it withoutarguments # No Output def func(**kwargs): # kwargs will be a dictionary containing the names as keys and the values as values for name, value in kwargs.items(): print(name, value) func(value1=1, value2=2, value3=3) # Calling it with 3 arguments # Out: value1 1 # value2 2 posicionales: La definición de una función capaz de tomar un número arbitrario de argumentos se puede hacer prefijando uno de los argumentos con un * No puede proporcionar un valor predeterminado para args , por ejemplo func(*args=[1, 2, 3]) generará un error de sintaxis (ni siquiera compilará). No puede proporcionarlos por nombre al llamar a la función, por ejemplo, func(*args=[1, 2, 3]) generará un TypeError . Pero si yatienesusargumentosenuna matriz (o cualquierotroIterable ),puede invocar su función así: func(*my_stuff) . Se puede acceder a estos argumentos ( *args ) por índice, por ejemplo, args[0] devolverá el primer argumento Número arbitrario de argumentos de palabras clave Puede tomar un número arbitrario de argumentos con un nombre definiendo un argumento en la definición con dos * delante:
    • 485. 420 deffunc(arg1, arg2=10 , *args, kwarg1, kwarg2=2, **kwargs): pass # |-positional-|-optional-|---keyword-only--|-optional-| No puede proporcionarlos sin nombres, por ejemplo, func(1, 2, 3) generará un TypeError . kwargses un simple diccionario nativo de python. Por ejemplo, args['value1'] dará el valor para el argumentovalue1.AsegúresedeverificardeantemanoqueexistatalargumentooseKeyErrorun KeyError . Advertencia Puede combinar estos con otros argumentos opcionales y requeridos, pero el orden dentro de la definición es importante. Losargumentosposicionales/palabrasclavesonloprimero.(Argumentosrequeridos). Luego vienen los argumentos arbitrarios *arg .(Opcional). Luego vienen los argumentos de palabra clave . (Necesario). Finalmente lapalabra clave arbitraria **kwargs viene.(Opcional). • arg1 debe darse, de lo contrario se TypeError un TypeError . Se puede dar como argumento posicional ( func(10) ) o de palabra clave ( func(arg1=10) ). • kwarg1 debe proporcionar kwarg1 , pero solo se puede proporcionar como palabra claveargumento: func(kwarg1=10) . • arg2 y kwarg2 son opcionales. Si se va a cambiar el valor, se aplican las mismas reglas que para arg1 (posicional o palabra clave) y kwarg1 (solo palabra clave). • *args capturaparámetros posicionalesadicionales.Perotenga encuentaquearg1 yarg2 deben proporcionarse como argumentos posicionales para pasar argumentos a *args : func(1, 1, 1, 1) . • **kwargs captura todos los parámetros de palabras clave adicionales. En este caso, cualquier parámetro que no sea arg1 , arg2 , kwarg1 o kwarg2 . Por ejemplo: func(kwarg3=10) . • EnPython3,puedeusar* soloparaindicarquetodoslosargumentosposterioresdeben especificarse como palabras clave. Por ejemplo, la función math.isclose en Python 3.5 y superior se define usando def math.isclose (a, b, *, rel_tol=1e-09, abs_tol=0.0) , lo que significaquelosprimerosdosargumentosse puedensuministrardemaneraposicional pero el opcional Los parámetros terceroy cuarto solose pueden suministrar comoargumentos de palabras clave. # bar 2 # Calling it with a dictionary my_dict = {'foo': 1, 'bar': 2} func(**my_dict) # Out: foo 1 func() # Calling it without arguments # No Out put # value3 3
    • 486. 421 def func(arg1, arg2=10, **kwargs): try: kwarg1 = kwargs.pop("kwarg1") except KeyError: raise TypeError("missing required keyword-only argument: 'kwarg1'") kwarg2 = kwargs.pop("kwarg2", 2) # function body ... def fn(**kwargs): print(kwargs) f1(**kwargs) def f1(**kwargs): print(len(kwargs)) fn(a=1, b=2) # Out: # {'a': 1, 'b': 2} # 2 Python 2.x no admite parámetros de palabras clave solamente. Este comportamiento puede ser emulado con kwargs : Nota sobre nombrar Laconvención de nombrar argumentos opcionales posicionales args y opcionales de palabras clave kwargs es solo una convención que puede usar cualquier nombre que desee, pero es útil seguirla convención para que otros sepan lo que está haciendo,o incluso usted mismo más adelante, así que hágalo. Nota sobre la singularidad Cualquier función se puede definir con ninguno o un *args y ninguno o uno **kwargs pero no con más de uno de cada uno. También *args debe ser el último argumento posicional y **kwargs debe ser el último parámetro. El intento de utilizar más de uno de ambos dará lugar a una excepción de error de sintaxis. Nota sobre funciones de anidamiento con argumentos opcionales Es posible anidar dichas funciones y la convención habitual es eliminar los elementos que el código ya ha manejado, pero si está pasando los parámetros, debe pasar argumentos opcionales posicionales con un prefijo * y argumentos de palabras clave opcionales con un prefijo ** , de lo contrario, los argumentos se pueden pasar como una lista o tupla y los kwargs como un solo diccionario. p.ej: Definiendo una función con argumentos mutables opcionales.
    • 487. 422 def f(a, b=42, c=[]): pass print(f. defaults ) # Out: (42,[]) def append(elem, to=[]): to.append(elem) # This call to append() mutates the default variable "to" return to append(1) # Out: [1] append(2) # Appends it to the internally stored list # Out: [1, 2] append(3, []) #Using a new created list givesthe expected result # Out: [3] # Calling it again without argument will append to the internally stored list again append(4) # Out: [1, 2, 4] Existe un problema cuando se usan argumentos opcionales con un tipo predeterminado mutable (descrito en Definición de una función con argumentos opcionales ), lo que puede conducir a un comportamiento inesperado. Explicación Este problema surge porque los argumentos predeterminados de una función se inicializan una vez , en el momento en que se define la función y no (como en muchos otros idiomas) cuando se llama a la función. Los valores predeterminados se almacenan dentro de la variable miembro defaults del objetode defaults . Para los tipos inmutables (ver Pasar argumento y mutabilidad ) esto no es un problema porque no hay manera de mutar la variable; solo se puede reasignar, sin cambiar el valor original. Por lo tanto, se garantiza que los subsiguientes tengan el mismo valor predeterminado. Sin embargo, para un tipo mutable , el valor original puede mutar, haciendo llamadas a sus diversas funciones miembro. Por lo tanto, no se garantiza que las llamadas sucesivas a la función tengan el valor predeterminado inicial. Nota: Algunos IDE como PyCharm emitirán una advertencia cuando se especifique un tipo mutable como atributo predeterminado. Solución Si desea asegurarse de que el argumento predeterminado sea siempre el que especifique en la definición de la función, entonces la solución es usar siempre un tipo inmutable como su argumento predeterminado.
    • 488. 423 def append(elem, to=None): if to is None: to = [] to.append(elem) return to def greeting(): return "Hello" print(greeting()) Hello greet_me = lambda: "Hello" print(greet_me()) Hello Un modismo común para lograr esto cuando se necesita un tipo mutable como predeterminado, es utilizar None (inmutable) como argumento predeterminado y luego asignar el valor predeterminado real a la variable de argumento si es igual a None . Funciones Lambda (Inline / Anónimo) La palabra clave lambda crea una función en línea que contiene una sola expresión. El valor de esta expresión es lo que la función devuelve cuando se invoca. Considere la función: el cual, cuando es llamado como: huellas dactilares: Esto se puede escribir como una función lambda de la siguiente manera: Vea la nota al final de esta sección con respecto a la asignación de lambdas a las variables. En general, no lo hagas. Estocrea una funciónenlíneaconel nombregreet_me que devuelve Hello .Tengaencuentaque no escribe return cuando crea una función con lambda. El valor después de : se devuelve automáticamente. Una vez asignada a una variable, se puede usar como una función regular: huellas dactilares: lambda
    • 489. 424 strip_and_upper_case = lambda s: s.strip().upper() strip_and_upper_case(" Hello ") HELLO greeting = lambda x, *args, **kwargs: print(x, args, kwargs) greeting('hello', 'world', world='world') hello ('world',) {'world': 'world'} # ['BaZ ', ' bAR', 'foo '] sorted( [" foo ", " bAR", "BaZ "], key=lambda s:s.strip()) # Out: sorted( map( lambda s: s.strip(), [" foo ", " bAR", "BaZ "])) # Out: # ['BaZ', 'bAR', 'foo'] sorted( map( lambda s: s.strip().upper(), [" foo ", " bAR", "BaZ "])) # Out: # ['BAR', 'BAZ', 'FOO'] my_list = [3, -4, -2, 5, 1, 7] sorted( my_list, key=lambda x: abs(x)) s puede tomar argumentos, también: devuelve la cadena: También pueden tomar un número arbitrario de argumentos / argumentos de palabras clave, como las funciones normales. huellas dactilares: lambda se usan comúnmente para funciones cortas que son convenientes para definir en el punto donde se llaman (típicamente con sorted , filter y map ). Por ejemplo, esta línea ordena una lista de cadenas que ignoran su caso e ignoran los espacios en blanco al principio y al final: sorted( [" foo ", " bAR", "BaZ "], key=lambda s: s.strip().upper()) # Out: # [' bAR', 'BaZ ', ' foo '] Ordenar la lista simplemente ignorando espacios en blanco: Ejemplos con map : Ejemplos con listas numéricas:
    • 490. 425 def foo(msg): print(msg) greet = lambda x = "hello world": foo(x) greet() hello world def f(x): return 2*x f = lambda x: 2*x Uno puede llamar a otras funciones (con / sin argumentos) desde dentro de una función lambda. huellas dactilares: Esto es útil porque lambda puede contener solo una expresión y al usar una función subsidiaria se pueden ejecutar varias declaraciones. NOTA Tenga en cuenta que PEP-8 (la guía de estilo oficial de Python) no recomienda asignar lambdas a las variables (como hicimos en los dos primeros ejemplos): Siempre use una instrucción def en lugar de una instrucción de asignación que vincule una expresión lambda directamente a un identificador. Sí: No: La primera forma significa que el nombre del objeto de función resultante es específicamente f lugar del genérico <lambda> . Esto es más útil para las trazas y representaciones de cadenas en general. El uso de la declaración de asignación elimina el único beneficio que puede ofrecer una expresión lambda sobre una declaración explícita de def (es decir, que se puede incrustar dentro de una expresión más grande). # Out: # [1, -2, 3, -4, 5, 7] list( filter( lambda x: x>0, my_list)) # Out: # [3, 5, 1, 7] list( map( lambda x: abs(x), my_list)) # Out: [3, 4, 2, 5, 1, 7]
    • 491. 426 # list labelled by y has been mutated too # call foo with y as argument # list labelled by x has been mutated y = [4, 5, 6] foo(y) # Out: [9, 5, 6] print(y) # Out: [9, 5, 6] # here x is the parameter # This mutates the list labelled by both x and y def foo(x): x[0] = 9 print(x) # y is the argument, x is the parameter # Pretend that we wrote "x = y", then go to line 1 y = [4, 5, 6] foo(y) y # Out: [9, 5, 6] def foo(x): # here x is the parameter, when we call foo(y) we assign y tox x[0] = 9 # This mutates the list labelled by both x and y x = [1, 2, 3] # x is now labeling a different list (y isunaffected) x[2] = 8 # This mutates x's list, not y's list x = [3, 1, 9] y = x x.append(5) # Mutatesthe list labelled by x and y, both x and y are bound to [3, 1, 9] x.sort() # Mutatesthe list labelled by x and y (in-place sorting) x = x+ [4] # Does not mutate the list (makes a copy for x only, not y) z = x # z is x ([1, 3, 9, 4]) x += [6] # Mutates the list labelled by both x and z (uses the extend function). x = sorted(x) # Does not mutate the list (makes a copy for x only). x # Out: [1, 3, 4, 5, 6, 9] y # Out: [1, 3, 5, 9] z # Out: [1, 3, 5, 9, 4, 6] Argumento de paso y mutabilidad. Primero, alguna terminología: • argumento (parámetro real ): la variable real que se pasa a una función; • parámetro (parámetro formal ): la variable de recepción que se utiliza en una función. En Python, los argumentos se pasan por asignación (a diferencia de otros idiomas, donde los argumentos pueden pasarse por valor / referencia / puntero). • Mutar un parámetro mutará el argumento (si el tipo del argumento es mutable). • Reasignar el parámetro no reasignará el argumento. En Python, realmente no asignamos valores a las variables, en lugar de eso, vinculamos (es decir, asignamos, adjuntamos) variables (consideradas como nombres ) a los objetos. • Inmutable: enteros, cadenas, tuplas, etc. Todas las operaciones hacen copias. • Mutable: listas, diccionarios, conjuntos, etc. Las operaciones pueden o no mutar.
    • 492. 427 def makeInc(x): def inc(y): # x is "attached" in the definition of inc return y + x return inc incOne = makeInc(1) incFive = makeInc(5) incOne(5) # returns 6 incFive(5) # returns 10 def makeInc(x): def inc(y): # incrementing x is not allowed x += y return x return inc incOne = makeInc(1) incOne(5) # UnboundLocalError: local variable 'x' referenced before assignment def makeInc(x): def inc(y): nonlocal x # now assigning a value to x is allowed x += y return x return inc incOne = makeInc(1) incOne(5) # returns 6 Cierre Los cierres en Python son creados por llamadas a funciones. Aquí, la llamada a makeInc crea un enlace para x que se hace referencia dentro de la función inc . Cada llamada a makeInc crea una nueva instancia de esta función, pero cada instancia tiene un enlace a un enlace diferente dex . Observe que, mientras que en un cierre regular, la función encerrada hereda completamente todas las variables de su entorno envolvente, en esta construcción, la función encerrada solo tiene acceso de lectura a las variables heredadas, pero no puede asignárselas. Python 3 ofrece la declaración no nonlocal ( variables no locales ) para realizar un cierre completo con funciones anidadas. Python 3.x 3.0 Funciones recursivas Una función recursiva es una función que se llama a sí misma en su definición. Por ejemplo, la
    • 493. 428 def factorial(n): #n here should be an integer if n == 0: return 1 else: return n*factorial(n-1) factorial(0) #out 1 factorial(1) #out 1 factorial(2) #out 2 factorial(3) #out 6 factorial = lambda n: 1 if n == 0 else n*factorial(n-1) def cursing(depth): try: cursing(depth + 1) # actually, re-cursing except RuntimeError as RE: print('I recursed {} times!'.format(depth)) cursing(0) # Out: I recursed 1083 times! sys.setrecursionlimit(2000) cursing(0) # Out: I recursed 1997 times! función matemática,factorial,definidaporfactorial(n) = n*(n-1)*(n-2)*...*3*2*1 . se puede programar como Las salidas aquí son: como se esperaba. Observe que esta función es recursiva porque el segundo return factorial(n1) , donde la función se llama a sí mismo en su definición. Algunas funciones recursivas pueden implementarse usando lambda , la función factorial que usa lambda sería algo como esto: La función produce la misma salida que la anterior. Límite de recursión Hay un límite a la profundidad de la posible recursión, que depende de la implementación de Python. Cuando se alcanza el límite, se genera una excepción RuntimeError: Es posible cambiar el límite de profundidad de recursión usando sys.setrecursionlimit(limit) y verificar este límite por sys.getrecursionlimit() .
    • 494. 429 def fibonacci(n): def step(a,b): return b, a+b a, b = 0, 1 for i in range(n): a, b =step(a, b) return a def make_adder(n): def adder(x): return n + x return adder add5 = make_adder(5) add6 = make_adder(6) add5(10) #Out: 15 add6(10) #Out: 16 defrepeatedly_apply(func,n,x): for i in range(n): x = func(x) return x repeatedly_apply(add5, 5, 1) #Out: 26 def unpacking(a, b, c=45, d=60, *args, **kwargs): print(a, b, c, d, args, kwargs) >>> unpacking(1, 2) 1 2 45 60 () {} >>> unpacking(1, 2, 3, 4) 1 2 3 4 () {} >>> unpacking(1, 2, c=3, d=4) 1 2 3 4 () {} >>> unpacking(1, 2, d=4, c=3) 1 2 3 4 () {} Desde Python 3.5, la excepción es un RecursionError , que se deriva de RuntimeError . Funciones anidadas Las funciones en python son objetos de primera clase. Se pueden definir en cualquier ámbito. Las funciones que capturan su ámbito de distribución pueden transmitirse como cualquier otro tipo de objeto Iterable y desempaquetado del diccionario. Las funciones le permiten especificar estos tipos de parámetros: posicionales, nombrados, variables posicionales, Argumentos de palabras clave (kwargs). Aquí hay un uso claro y conciso de cada tipo.
    • 495. 430 >>> pair = (3,) >>> unpacking(1, 2, *pair, d=4) 1 2 3 4 () {} >>> unpacking(1, 2, d=4, *pair) 1 2 3 4 () {} >>> unpacking(1, 2, *pair, c=3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'c' >>> unpacking(1, 2, c=3, *pair) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'c' >>> args_list = [3] >>> unpacking(1, 2, *args_list, d=4) 1 2 3 4 () {} >>> unpacking(1, 2, d=4, *args_list) 1 2 3 4 () {} >>> unpacking(1, 2, c=3, *args_list) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'c' >>> unpacking(1, 2, *args_list, c=3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'c' >>> pair = (3, 4) >>> unpacking(1, 2, *pair) 1 2 3 4 () {} >>> unpacking(1, 2, 3, 4, *pair) 1 2 3 4 (3, 4) {} >>> unpacking(1, 2, d=4, *pair) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'd' >>> unpacking(1, 2, *pair, d=4) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'd' >>> args_list = [3, 4] >>> unpacking(1, 2, *args_list) 1 2 3 4 () {} >>> unpacking(1, 2, 3, 4, *args_list) 1 2 3 4 (3, 4) {} >>> unpacking(1, 2, d=4, *args_list) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'd' >>> unpacking(1, 2, *args_list, d=4) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'd' >>> arg_dict = {'c':3, 'd':4}
    • 496. 431 def f(*a, b): pass f(1, 2, 3) # TypeError: f() missing 1 required keyword-only argument: 'b' def f(a, b, *, c): pass f(1, 2, 3) # TypeError: f() takes 2 positional arguments but 3 were given f(1, 2, c=3) # No error Forzando el uso de parámetros nombrados Todos los parámetros especificados después del primer asterisco en la firma de función son solo palabras clave. En Python 3 es posible poner un solo asterisco en la firma de la función para garantizar que los argumentos restantes solo puedan pasarse utilizando argumentos de palabras clave. Lambda recursiva utilizando variable asignada Un método para crear funciones lambda recursivas implica asignar la función a una variable y luego hacer referencia a esa variable dentro de la misma función. Un ejemplo común de esto es el cálculo recursivo del factorial de un número, como se muestra en el siguiente código: >>> unpacking(1, 2, **arg_dict) 1 2 3 4 () {} >>> arg_dict = {'d':4, 'c':3} >>> unpacking(1, 2, **arg_dict) 1 2 3 4 () {} >>> arg_dict = {'c':3, 'd':4, 'not_a_parameter': 75} >>> unpacking(1, 2, **arg_dict) 1 2 3 4 () {'not_a_parameter': 75} >>> unpacking(1, 2, *pair, **arg_dict) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'd' >>> unpacking(1, 2, 3, 4, **arg_dict) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'd' # Positional arguments take priority over any other form of argument passing >>> unpacking(1, 2, **arg_dict, c=3) 1 2 3 4 () {'not_a_parameter': 75} >>> unpacking(1, 2, 3, **arg_dict, c=3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unpacking() got multiple values for argument 'c'
    • 497. 432 Descripción del código A la función lambda, a través de su asignación variable, se le pasa un valor (4) que evalúa y devuelve 1 si es 0 o, de lo contrario, devuelve el valor actual ( i ) * otro cálculo realizado porla función lambda del valor - 1 ( i-1 ). Esto continúa hasta que el valor pasado se reduce a 0 ( return 1 ). Un proceso que se puede visualizar como: lambda_factorial = lambda i:1 if i==0 else i*lambda_factorial(i-1) print(lambda_factorial(4)) # 4 * 3 * 2 * 1 = 12 * 2 = 24
    • 498. 433 Capítulo 89: Funciones parciales Introducción Como probablemente sepa si vino de la escuela de OOP, especializarse en una clase abstracta y usarla es una práctica que debe tener en cuenta al escribir su código. ¿Qué pasaría si pudieras definir una función abstracta y especializarla para crear diferentes versiones de ella? Piensa que es una especie de función de herencia donde se vinculan parámetros específicos para que sean confiables para un escenario específico. Sintaxis • parcial (función, ** params_you_want_fix) Parámetros Param detalles X el número a elevar y el exponente aumento La función a especializarse. Observaciones Como se indica en el documento de Python, functools.partial : Devuelva un nuevo objeto parcial que, cuando se le llame, se comportará como una función llamada con los argumentos posicionales, argumentos y palabras clave de palabras clave. Si se proporcionan más argumentos a la llamada, se anexan a args. Si se proporcionan argumentos de palabras clave adicionales, amplían y anulan las palabras clave. Consulte este enlace para ver cómo se puede implementar parcial . Examples Elevar el poder Supongamos que queremos elevar x a un número y . Escribirías esto como:
    • 499. 434 def raise(x, y): if y in (3,4,5): return x**y raise NumberNotInRangeException("You should provide a valid exponent") from functors import partial raise_to_three = partial(raise, y=3) raise_to_four = partial(raise, y=4) raise_to_five = partial(raise, y=5) ¿Qué pasa si su valor y puede asumir un conjunto finito de valores? Supongamos que y puede ser uno de [3,4,5] y digamos que no quiere ofrecer al usuario final la posibilidad de usar dicha función, ya que es muy computacional. De hecho, verificará si se proporciona y asume un valor válido y reescribirá su función como: ¿Sucio? Usemos el formulario abstracto y lo especialicemos en los tres casos: implementémoslo parcialmente . ¿Qué pasa aquí? Hemos fijado los parametros y y definimos tres funciones diferentes. No es necesario usar la función abstracta definida anteriormente (puede hacerla privada ), pero puede usar funciones aplicadas parciales para tratar de elevar un número a un valor fijo. def raise_power(x, y): return x**y
    • 500. 435 # naive partial implementation of the Python 2.x xrange() def xrange(n): i = 0 while i < n: yield i i += 1 # looping for i in xrange(10): print(i) # prints the values 0, 1, ..., 9 # unpacking a, b, c = xrange(3) # 0, 1, 2 # building a list l = list(xrange(10)) # [0, 1, ..., 9] def nums(): Capítulo 90: Generadores Introducción Losgeneradoressoniteradoresperezososcreadosporlasfuncionesdelgenerador(queutilizan el yield ) o las expresiones del generador (que usan (an_expression for x in an_iterator) ). Sintaxis • rendimiento <expr> • rendimiento de <expr> • <var> = rendimiento <expr> • siguiente ( <iter> ) Examples Iteración Un objeto generador soporta el protocolo iterador . Es decir, proporciona un método next() ( next () en Python 3.x), que se utiliza para avanzar en su ejecución, y su método iter devuelve.Estosignificaquesepuedeusarun generadorencualquier construccióndelenguaje que admita objetos iterablesgenéricos. La siguiente función () El next() incorporado es un envoltorio conveniente que se puede usar para recibir un valor de cualquieriterador(incluidouniteradorgenerador)yparaproporcionarunvalorpredeterminadoen caso de que se agote el iterador.
    • 501. 436 def accumulator(): total = 0 value = None while True: # receive sent value value = yield total if value is None: break # aggregate values total += value generator = accumulator() # advance until the first "yield" next(generator) # 0 # from this point on, the generator aggregates values # Calling next(generator) is equivalent to calling generator.send(None) next(generator) # StopIteration La sintaxis es la next(iterator[, default]) . Si el iterador finaliza y se pasa un valor predeterminado,sedevuelve.Sinoseproporcionóningúnvalorpredeterminado,seStopIteration . Enviando objetos a un generador. Además de recibir valores de un generador, es posible enviar un objeto a un generador utilizando el método send() . generator.send(1) # 1 generator.send(10) # 11 generator.send(100) # 111 # ... Lo que pasa aquí es lo siguiente: • Cuando llama por primera vez al next(generator) , el programa avanza a la primera declaración de yield y devuelve el valor del totalenese punto, que es0.La ejecución del generador se suspende en estepunto. • Cuando llama a generator.send(x) , el intérprete toma el argumento x y lo convierte en el valor de retorno de la última declaración de yield , que se asigna al value .El generador continúa como de costumbre, hasta que da el siguiente valor. • Cuando finalmente llama a next(generator) , el programa trata esto como si estuviera yield 1 yield 2 yield 3 generator = nums() next(generator, None) # 1 next(generator, None) # 2 next(generator, None) # 3 next(generator, None) #None next(generator, None) #None # ...
    • 502. 437 generator = (i * 2 for i in range(3)) next(generator) # 0 next(generator) # 2 next(generator) # 4 next(generator) # raises StopIteration sum(i ** 2 for i in range(4)) # 0^2 + 1^2 + 2^2 + 3^2 = 0 + 1 + 4 + 9 = 14 expression = (x**2 for x in range(10)) def function(): for x in range(10): yield x**2 enviando None al generador. No hay nada especial en None , sin embargo, este ejemplo utiliza None como un valor especial para pedirle al generador que se detenga. Expresiones generadoras Es posible crear iteradores de generador utilizando una sintaxis similar a la comprensión. Si a una función no necesariamente se le debe pasar una lista, puede guardar caracteres (y mejorar la legibilidad) colocando una expresión de generador dentro de una llamada de función. El paréntesis de la llamada a la función hace implícitamente que su expresión sea una expresión generadora. Además, guardará en la memoria porque en lugar de cargarla lista completa sobre la que está iterando ( [0, 1, 2, 3] en el ejemplo anterior), el generador permite que Python use los valores según sea necesario. Introducción Las expresiones de los generadores son similares a las listas, diccionarios y conjuntos de comprensión, pero están entre paréntesis. Los paréntesis no tienen que estar presentes cuando se usan como el único argumento para una llamada de función. Este ejemplo genera los 10 primeros cuadrados perfectos, incluido 0 (en el que x = 0). Lasfuncionesdelgenerador sonsimilares alas funciones regulares,exceptoque tienen unao más declaraciones de yield en su cuerpo. Dichas funciones no pueden return ningún valor (sin embargo, se permiten return vacías si desea detener el generador antes). Esta función del generador es equivalente a la expresión del generador anterior, produce el mismo. Nota : todas las expresiones generadoras tienen sus propias funciones equivalentes , pero no al revés.
    • 503. 438 sum(i for i in range(10) if i % 2 == 0) #Output: 20 any(x = 0 for x in foo) #Output: True or False depending on foo type(a > b for a in foo if a % 2 == 1) #Output: <class 'generator'> sum((i for i in range(10) if i % 2 == 0)) any((x = 0 for x in foo)) type((a > b for a in foo if a % 2 == 1)) fooFunction(i for i in range(10) if i % 2 == 0,foo,bar) return x = 0 for x in foo barFunction(baz, a > b for a in foo if a % 2 == 1) g1 = function() print(g1) # Out: <generator object function at 0x1012e1888> for x in g1: print("Received", x) # Output: Se puede usar una expresión generadora sin paréntesis si ambos paréntesis se repetirían de lo contrario: En lugar de: Pero no: Al llamar a una función de generador se genera un objeto generador , que luego se puede iterar. A diferencia de otros tipos de iteradores, los objetos generadores solo se pueden atravesar una vez. Observe que el cuerpo de un generador no se ejecuta inmediatamente: cuando llama a function() en el ejemplo anterior, devuelve inmediatamente un objeto generador, sin ejecutar siquiera la primeradeclaracióndeimpresión.Estopermitequelosgeneradoresconsumanmenosmemoria quelas funcionesquedevuelvenunalista,ypermitecreargeneradoresqueproducensecuencias infinitamente largas. Por esta razón, los generadores a menudo se utilizan en la ciencia de datos y en otros contextos que involucran grandes cantidades de datos. Otra ventaja es que otro código puede usar inmediatamente los valores generados por un generador, sin esperar a que se produzca la secuencia completa. Sin embargo, si necesita usar los valores producidos por un generador más de una vez, y si generarlos cuesta más que almacenarlos, puede ser mejor almacenar los valores generados como una list que volver a generar la secuencia. Consulte 'Restablecer un generador' a continuación para obtener más detalles. Normalmente, un objeto generador se usa en un bucle, o en cualquier función que requiera un iterable:
    • 504. 439 arr1 = list(g1) # arr1 = [], because the loop above already consumed all the values. g2 = function() arr2 = list(g2) # arr2 = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # Received 0 # Received 1 # Received 4 # Received 9 # Received 16 # Received 25 # Received 36 # Received 49 # Received 64 # Received 81 Comolosobjetosgeneradoressoniteradores,unopuederecorrerlosmanualmenteusandola función next() . Al hacerlo, se devolverán los valores cedidos uno por uno en cada invocación posterior. Bajo el capó, cada vez que llama a next() en un generador, Python ejecuta declaraciones en el cuerpo de la función del generador hasta que llega a la siguiente declaración de yield . En este punto, devuelve el argumento del comando de yield y recuerda el punto en el que ocurrió. Llamar a next() una vez más reanudará la ejecución desde ese punto y continuará hasta la próxima declaración de yield . Si Python llega al final de la función del generador sin encontrar más yield , se StopIteration una excepción StopIteration (estoesnormal,todos lositeradoressecomportan delamisma manera). g3 =function() a = next(g3) b = next(g3) c = next(g3) ... j = next(g3) # a becomes 0 # b becomes 1 # c becomes 2 # Raises StopIteration, j remains undefined TengaencuentaqueenelgeneradorPython2,losobjetosteníanmétodos.next() quesepodían usarparaiteraratravésdelosvaloresproducidosmanualmente.EnPython3,estemétodofue reemplazado por el estándar . next () para todos los iteradores. Restablecer un generador Recuerde que solo puede recorrer los objetos generados por un generador una vez . Si ya ha iterado a través de los objetos en una secuencia de comandos, cualquier otro intento de hacerlo dará como resultado None . Si necesita usar los objetos generados por un generador más de una vez, puede definir la función del generador de nuevo y usarla por segunda vez, o bien, puede almacenar la salida de la función del generador en una lista en el primer uso. Volver a definir la función del generador será una buena opción si está manejando grandes volúmenes de datos, y almacenar una lista de todos los elementos de datos ocuparía mucho espacio en el disco. A la inversa, si es costoso generar los artículos inicialmente, es posible que prefiera almacenar los artículos generados en una lista para
    • 505. 440 def fib(a=0, b=1): """Generator that yields Fibonacci numbers. `a` and `b` are the seed values""" while True: yield a a, b = b, a + b f = fib() print(', '.join(str(next(f)) for _ in range(10))) def integers_starting_from(n): while True: yield n n += 1 natural_numbers = integers_starting_from(1) natural_numbers = itertools.count(1) multiples_of_two = (x * 2 for x in natural_numbers) multiples_of_three = (x for x in natural_numbers if x % 3 == 0) list(multiples_of_two) # will never terminate, or raise an OS-specific error first_five_multiples_of_three = [next(multiples_of_three) for _ in range(5)] # [3, 6, 9, 12, 15] poder reutilizarlos. Usando un generador para encontrar los números de Fibonacci Un caso de uso práctico de un generador es recorrer los valores de una serie infinita. Aquí hay un ejemplo de cómo encontrar los primeros diez términos de la secuencia de Fibonacci . 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 Secuencias infinitas Se pueden usar generadores para representar secuencias infinitas: La secuencia infinita de números como la anterior también se puede generar con la ayuda de itertools.count . El código anterior se puede escribir como abajo Puede usar la comprensión del generador en generadores infinitos para producir nuevos generadores: Tenga en cuenta que un generador infinito no tiene un fin, por lo que pasarlo a cualquier función que intente consumir el generador por completo tendrá graves consecuencias : En su lugar, use la lista de listas / conjuntos con range (o xrange para python <3.0):
    • 506. 441 from itertools import islice multiples_of_four = (x * 4 for x in integers_starting_from(1)) first_five_multiples_of_four = list(islice(multiples_of_four, 5)) # [4, 8, 12, 16, 20] next(natural_numbers) # yields 16 next(multiples_of_two) # yields 34 next(multiples_of_four) # yields 24 for idx, number in enumerate(multiplies_of_two): print(number) if idx == 9: break # stop after taking the first 10 multiplies of two import itertools def fibonacci(): a, b = 1, 1 while True: yield a a, b = b, a + b first_ten_fibs = list(itertools.islice(fibonacci(), 10)) # [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] def nth_fib(n): return next(itertools.islice(fibonacci(), n - 1, n)) ninety_nineth_fib = nth_fib(99) # 354224848179261915075 def foob(x): yield from range(x * 2) yield from range(2) list(foob(5)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1] o use itertools.islice() para cortar el iterador en un subconjunto: Tenga en cuenta que el generador original también se actualiza, al igual que todos los demás generadores que vienen de la misma "raíz": Una secuencia infinita también se puede iterar con un bucle for .Asegúrese de incluir una instrucción de break condicional para que el bucle finalice eventualmente: Ejemplo clásico - números de Fibonacci Rindiendo todos los valores de otro iterable. Python 3.x 3.3 Utilice el yield from si desea obtener todos los valores de otro iterable:
    • 507. 442 def fibto(n): a, b = 1, 1 while True: if a >= n: break yield a a, b = b, a + b def usefib(): yield from fibto(10) yield from fibto(20) list(usefib()) # [1, 1, 2, 3, 5, 8, 1, 1, 2, 3, 5, 8, 13] # create and advance generator to the first yield def coroutine(func): def start(*args,**kwargs): cr = func(*args,**kwargs) next(cr) return cr return start # example coroutine @coroutine def adder(sum = 0): while True: x = yield sum sum += x # example use s = adder() s.send(1) # 1 s.send(2) # 3 from os import listdir from os.path import isfile, join, exists Esto funciona también con generadores. Coroutines Los generadores pueden ser utilizados para implementar coroutines: Coroutines se usa comúnmente para implementar máquinas de estado, ya que son principalmente útiles para crear procedimientos de un solo método que requieren un estado para funcionar correctamente. Operan en un estado existente y devuelven el valor obtenido al finalizar la operación. Rendimiento con recursión: listado recursivo de todos los archivos en un directorio Primero, importa las bibliotecas que trabajan con archivos: Una función auxiliar para leer solo archivos de un directorio:
    • 508. 443 def get_directories(path): for directory in listdir(path): full_path = join(path, directory) if not isfile(full_path): if exists(full_path): yield full_path def get_files_recursive(directory): for file in get_files(directory): yield file for subdirectory in get_directories(directory): for file in get_files_recursive(subdirectory): # here the recursive call yield file def get_files_recursive(directory): yield from get_files(directory) for subdirectory in get_directories(directory): yield from get_files_recursive(subdirectory) for x, y in zip(a,b): print(x,y) 1 x 2 y 3 z Otra función auxiliar para obtener solo los subdirectorios: Ahora use estas funciones para obtener recursivamente todos los archivos dentro de un directorio y todos sus subdirectorios (usando generadores): Esta función se puede simplificar utilizando el yield from : Iterando sobre generadores en paralelo. Para iterar sobre varios generadores en paralelo, use el zip incorporado: Resultados en: EnPython2deberíasusaritertools.izip enitertools.izip lugar. Aquítambiénpodemosverque todas las funciones zip producen tuplas. Tenga en cuenta que zip dejará de iterar tan pronto como uno de los iterables se quede sin elementos. Si desea iterar durante el tiempo más largo posible, use itertools.zip_longest() . def get_files(path): for file in listdir(path): full_path = join(path, file) if isfile(full_path): if exists(full_path): yield full_path
    • 509. 444 def create(): result = [] # logic here... result.append(value) # possibly in several places # more logic... return result # possibly in several places values = create() def create_gen(): # logic... yield value # more logic return # not needed if at the end of the function, of course values = list(create_gen()) def preorder_traversal(node): yield node.value for child in node.children: yield from preorder_traversal(child) def find_and_transform(sequence, predicate, func): for element in sequence: if predicate(element): return func(element) raise ValueError item = find_and_transform(my_sequence, my_predicate, my_func) item = next(my_func(x) for x in my_sequence if my_predicate(x)) # StopIteration will be raised if there are no matches; this exception can # be caught and transformed, if desired. Código de construcción de lista de refactorización Supongamos que tiene un código complejo que crea y devuelve una lista al comenzar con una lista en blanco y agregarla repetidamente: Cuando no es práctico reemplazar la lógica interna con una lista de comprensión, puede convertir toda la función en un generador en el lugar y luego recopilar los resultados: Si la lógica es recursiva, use el yield from para incluir todos los valores de la llamada recursiva en un resultado "aplanado": buscando La next función es útil incluso sin iterar. Pasar una expresión del generador a la next es una forma rápida de buscar la primera aparición de un elemento que coincida con algún predicado. Código de procedimiento como puede ser reemplazado con:
    • 510. 445 def first(generator): try: return next(generator) except StopIteration: raise ValueError Para este propósito,puede ser conveniente crear un alias, como first = next ,o una funciónde envoltura para convertir laexcepción:
    • 511. 446 with EXPR as VAR: BLOCK mgr = (EXPR) exit = type(mgr). exit # Not calling it yet value = type(mgr). enter (mgr) exc = True try: try: VAR = value #Only if "as VAR" is present BLOCK except: # The exceptional case is handled here exc = False if not exit(mgr, *sys.exc_info()): raise # The exception is swallowed if exit() returns true finally: # The normal and non-local-goto cases are handled here Capítulo 91: Gestores de contexto (declaración “con”) Introducción Si bien los administradores de contexto de Python son ampliamente utilizados, pocos entienden el propósito detrás de su uso. Estas declaraciones, comúnmente utilizadas con los archivos de lectura y escritura, ayudan a la aplicación a conservar la memoria del sistema y mejorar la administración de recursos al garantizar que los recursos específicos solo se usan para ciertos procesos. Este tema explica y demuestra el uso de los gestores de contexto de Python. Sintaxis • con "context_manager" (como "alias") (, "context_manager" (como "alias")?) *: Observaciones LosgestoresdecontextosedefinenenPEP343.Estándiseñadosparaserutilizadoscomoun mecanismo más sucinto parala administraciónderecursos que el quetry ... finally construye. La definición formal es lasiguiente. En estePEP, los gestores de contexto proporcionan los enter () y exit () que se invocan al ingresar y salir del cuerpo de la declaración with. Luego pasa a definir la instrucción with lo siguiente. La traducción de la declaración anterior es:
    • 512. 447 open_file = open(filename) with open_file: file_contents = open_file.read() # the open_file object has automatically been closed. with open(filename) as open_file: file_contents = open_file.read() # the open_file object has automatically been closed. with database_connection as cursor: cursor.execute(sql_query) Examples Introducción a los gestores de contexto y con la declaración. Un administrador de contexto es un objeto que se notifica cuando un contexto (un bloque de código) comienza y termina . Normalmente se utiliza uno con la instrucción with .Se encarga de la notificación. Por ejemplo, los objetos de archivo son gestores de contexto. Cuando un contexto finaliza, el objeto de archivo se cierra automáticamente: El ejemplo anterior generalmente se simplifica utilizando la palabra clave as : Cualquier cosa que finalice la ejecución del bloque hace que se llame al método de salida del administrador de contexto. Esto incluye excepciones y puede ser útil cuando un error hace que salga prematuramente de un archivo abierto o conexión. Salir de un script sin cerrar correctamente los archivos / conexiones es una mala idea, ya que puede causar la pérdida de datos u otros problemas. Al utilizar un administrador de contexto, puede asegurarse de que siempre se tomen precauciones para evitar daños o pérdidas de esta manera. Esta característica fue añadida en Python 2.5. Asignar a un objetivo Muchosadministradoresdecontextodevuelvenunobjetocuandoseingresa.Puedeasignarese objeto a un nuevo nombre en la declaración with . Por ejemplo, usar una conexión de base de datos en una declaración with podría darle un objeto de cursor: Los objetos de archivo se devuelven solos, esto hace posible abrir el objeto de archivo y usarlo como administrador de contexto en una expresión: if exc: exit(mgr, None, None, None)
    • 513. 448 class AContextManager(): def enter (self): print("Entered") # optionally return an object return "A-instance" def exit (self, exc_type, exc_value, traceback): print("Exited" + (" (with an exception)" if exc_type else "")) # return True if you want to suppress the exception with AContextManager() as a: print("a is %r" % a) # Entered # a is 'A-instance' # Exited with AContextManager() as a: print("a is %d" % a) # Entered # Exited (with an exception) # Traceback (most recent call last): # File "<stdin>", line 2, in<module> # TypeError: %d format: a number is required, not str class MyContextManager: def enter (self): return self def exit (self): print('something') Escribiendo tu propio gestor de contexto. Un administrador de contexto es cualquier objeto que implementa dos métodos mágicos enter () y exit () (aunque también puede implementar otros métodos): Si el contexto sale con una excepción, la información sobre esa excepción se pasa como un triple exc_type , exc_value , traceback (estas son las mismas variables que devuelve el sys.exc_info() función). Si el contexto sale normalmente, los tres de estos argumentos serán None . Si ocurre una excepción y se pasa al método exit , el método puede devolver True para suprimir la excepción, o la excepción volverá a presentarse al final de la función exit . Tenga en cuenta que en el segundo ejemplo, a pesar de que se produce una excepción en medio del cuerpo de la instrucción with, el controlador exit aún se ejecuta, antes de que la excepción se propague al ámbito externo. Si solo necesita un método exit , puede devolver la instancia del administrador de contexto: with open(filename) as open_file: file_contents = open_file.read()
    • 514. 449 import contextlib @contextlib.contextmanager def context_manager(num): print('Enter') yield num + 1 print('Exit') with context_manager(2) as cm: # the following instructions are run when the 'yield' point of the context # manager is reached. # 'cm' will have the value that was yielded print('Right in the middle with cm = {}'.format(cm)) Enter Right in the middle with cm = 3 Exit @contextlib.contextmanager def error_handling_context_manager(num): print("Enter") try: yield num + 1 except ZeroDivisionError: print("Caught error") finally: print("Cleaning up") print("Exit") with error_handling_context_manager(-1) as cm: print("Dividing by cm = {}".format(cm)) print(2 / cm) Escribiendo tu propio administrador de contexto usando la sintaxis del generador. Tambiénesposibleescribirunadministradordecontextousandolasintaxisdelgeneradorgracias al decorador contextlib.contextmanager : produce: El decorador simplifica la tarea de escribir un administrador de contexto al convertir un generador en uno. Todo antes de que la expresión de rendimiento se convierta en el método enter , el valor generado se convierta en el valor devuelto por el generador (que se puede vincular a una variable en la declaración with), y todo después de la expresión de rendimiento se convierte en el método exit Si el administrador de contexto debe manejar una excepción, se puede escribir un try..except..finally try..except..finally en el generador, y este bloque de excepción manejará cualquier excepción que se genere en el bloque with . Esto produce:
    • 515. 450 with open(input_path) as input_file, open(output_path, 'w') as output_file: # do something with both files. # e.g. copy the contents of input_file into output_file for line in input_file: output_file.write(line + '\n') with open(input_path) as input_file: with open(output_path, 'w') as output_file: for line in input_file: output_file.write(line + '\n') class File(): def init (self, filename, mode): self.filename = filename self.mode = mode def enter (self): self.open_file = open(self.filename, self.mode) return self.open_file def exit (self, *args): self.open_file.close() for _ in range(10000): with File('foo.txt', 'w') as f: f.write('foo') Gestores de contexto multiples Puede abrir varios gestores de contenido al mismo tiempo: Tiene el mismo efecto que los administradores de contexto de anidamiento: Gestionar recursos init () configuraelobjeto,enestecaso,configuraelnombredelarchivoyelmodoparaabrir el archivo. enter () abre y devuelve el archivo y exit () simplemente locierra. El uso de estos métodos mágicos ( enter , exit )lepermiteimplementarobjetos que se pueden usar fácilmente with la instrucción with. Usar clase de archivo: Enter Dividing by cm = 0 Caught error Cleaning up Exit
    • 516. 451
    • 517. 452 import turtle ninja = turtle.Turtle() ninja.speed(10) for i in range(180): ninja.forward(100) ninja.right(30) ninja.forward(20) ninja.left(60) ninja.forward(50) ninja.right(30) ninja.penup() ninja.setposition(0, 0) ninja.pendown() ninja.right(2) turtle.done() Capítulo 92: Gráficos de tortuga Examples Ninja Twist (Tortuga Gráficos) Aquí una Tortuga Gráficos Ninja Twist:
    • 518. 453 hash.sha1() hash.update(arg) hash.digest() hash.hexdigest() Capítulo 93: hashlib Introducción hashlib implementa una interfaz común para muchos algoritmos de resumen de hash y resumen de mensajes. Se incluyen los algoritmos de hash seguro FIPS SHA1, SHA224, SHA256, SHA384 y SHA512. Examples Hash MD5 de una cadena Este módulo implementa una interfaz común para muchos algoritmos de resumen de hash y resumen de mensajes. Se incluyen los algoritmos hash seguros SHA1, SHA224, SHA256, SHA384 y SHA512 de FIPS (definidos en FIPS 180-2), así como el algoritmo MD5 de RSA (definido en Internet RFC 1321). Hay un método constructor nombrado para cada tipo de hash. Todos devuelven un objeto hash con la misma interfaz simple. Por ejemplo: use sha1() para crear un objeto hash SHA1. Los constructores de algoritmos hash que siempre están presentes en este módulo son md5() , sha1() , sha224() , sha256() , sha384() y sha512() . Ahorapuedealimentar esteobjetoconcadenasarbitrariasusandoel métodoupdate().En cualquier momento,puedesolicitarelresumende laconcatenacióndelas cadenas que se lehan suministrado utilizando los métodos digest() o hexdigest(). Actualice el objeto hash con la cadena arg. Las llamadas repetidas son equivalentes a una sola llamada con la concatenación de todos los argumentos: m.update (a); m.update (b) es equivalente a m.update (a + b). Devuelva el resumen de las cadenas pasadas al método update () hasta el momento. Esta es una cadena de bytes digest_size que pueden contener caracteres no ASCII, incluidos los bytes nulos. Al igual que digest () excepto que el resumen se devuelve como una cadena de doble longitud, que contiene solo dígitos hexadecimales. Esto se puede usar para
    • 519. 454 >>> import hashlib >>> m = hashlib.md5() >>> m.update("Nobody inspects") >>> m.update(" the spammish repetition") >>> m.digest() '\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9' >>> m.hexdigest() 'bb649c83dd1ea5c9d9dec9a18df0ffe9' >>> m.digest_size 16 >>> m.block_size 64 hashlib.md5("Nobody inspects the spammish repetition").hexdigest() 'bb649c83dd1ea5c9d9dec9a18df0ffe9' >>> h = hashlib.new('ripemd160') >>> h.update("Nobody inspects the spammish repetition") >>> h.hexdigest() 'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc' intercambiar el valor de forma segura en el correo electrónico u otros entornos no binarios. Aquí hay un ejemplo: o: algoritmo proporcionado por OpenSSL También existe un constructor new() genérico que toma el nombre de la cadena del algoritmo deseado como su primer parámetro para permitir el acceso a los hashes enumerados anteriormente, así como a cualquier otro algoritmo que pueda ofrecer su biblioteca OpenSSL. Los constructores nombrados son mucho más rápidos que new() y deberían preferirse. Usando new() con un algoritmo proporcionado por OpenSSL:
    • 520. 455 import heapq numbers = [1, 4, 2, 100, 20, 50, 32, 200, 150, 8] print(heapq.nlargest(4, numbers)) # [200, 150, 100, 50] print(heapq.nsmallest(4, numbers)) # [1, 2, 4, 8] people = [ {'firstname': 'John', 'lastname': 'Doe', 'age': 30}, {'firstname': 'Jane', 'lastname': 'Doe', 'age': 25}, {'firstname': 'Janie', 'lastname': 'Doe', 'age': 10}, {'firstname': 'Jane', 'lastname': 'Roe', 'age': 22}, {'firstname': 'Johnny', 'lastname': 'Doe', 'age': 12}, {'firstname': 'John', 'lastname': 'Roe', 'age': 45} ] oldest = heapq.nlargest(2, people, key=lambda s: s['age']) print(oldest) # Output: [{'firstname': 'John', 'age': 45, 'lastname': 'Roe'}, {'firstname': 'John', 'age': 30, 'lastname': 'Doe'}] youngest = heapq.nsmallest(2, people, key=lambda s: s['age']) print(youngest) # Output: [{'firstname': 'Janie', 'age': 10, 'lastname': 'Doe'}, {'firstname': 'Johnny', 'age': 12, 'lastname': 'Doe'}] Capítulo 94: Heapq Examples Artículos más grandes y más pequeños en una colección. Para encontrarlos elementos más grandes enuna colección, el módulo heapq tiene una función llamada nlargest , le pasamos dos argumentos, el primero es el número de elementos que queremos recuperar, el segundo es el nombre de la colección: De manera similar, para encontrar los elementos más pequeños en una colección, usamos la función nsmallest : Las funciones nlargest y nsmallest toman un argumento opcional (parámetro clave) para estructurasde datos complicadas.El siguienteejemplo muestra el uso dela propiedad age para recuperar las personas más antiguas y más jóvenes del diccionario de people : Artículo más pequeño en una colección. Lapropiedad más interesante de un heap es que su elemento más pequeño es siempre el primer elemento: heap[0]
    • 521. 456 import heapq numbers = [10, 4, 2, 100, 20, 50, 32, 200, 150, 8] heapq.heapify(numbers) print(numbers) # Output: [2, 4, 10, 100, 8, 50, 32, 200, 150, 20] heapq.heappop(numbers) # 2 print(numbers) # Output: [4, 8, 10, 100, 20, 50, 32, 200, 150] heapq.heappop(numbers) # 4 print(numbers) # Output: [8, 20, 10, 100, 150, 50, 32, 200]
    • 522. 457 Capítulo 95: Herramienta 2to3 Sintaxis • $ 2to3 [-options] ruta / a / archivo.py Parámetros Parámetro Descripción nombre de archivo / nombre_directorio 2to3 acepta una lista de archivos o directorios que se va a transformar como su argumento. Los directorios se recursivamente recorren para las fuentes de Python. Opción Opción Descripción -f FIX, --fix = FIX Especificartransformacionesaaplicar;pordefecto:todos.Listar las transformaciones disponibles con--list-fixes -j PROCESOS, -- procesos = PROCESOS Ejecutar 2to3 al mismo tiempo -x NOFIX, --nofix = NOFIX Excluir una transformación -l, --list-fixes Listar las transformaciones disponibles -p, --print-function Cambialagramáticaparaqueprint()seaconsideradauna función. -v, --verbose Salida más detallada --no-diffs No se muestran datos de la refactorización. -w Escribir archivos modificados -n, --nobackups No cree copias de seguridad de archivos modificados -o OUTPUT_DIR, -- output-dir = OUTPUT_DIR Coloque los archivos de salida en este directorio en lugar de sobrescribir los archivos de entrada. Requiere la -n , ya que los archivos de copia de seguridad no son necesarios cuando los archivos de entrada no se modifican. -W, --write-unchangedfiles Escribir archivos de salida, incluso si no se requieren cambios. Útil con -o para que se traduzca y copie un árbol fuente completo. Implica -w .
    • 523. 458 def greet(name): print "Hello, {0}!".format(name) print "What's your name?" name = raw_input() greet(name) $ 2to3 example.py > path/to/2to3.py example.py RefactoringTool: Skipping implicit fixer: buffer Parámetro Descripción --add-suffix = ADD_SUFFIX Especifique una cadenaquese agregaráa todoslosnombres de archivo de salida. Requiere -n si no está vacío. Ej .: --addsuffix='3' generará archivos .py3 . Observaciones La herramienta 2to3 es un programa de Python que se utiliza para convertir el código escrito en Python 2.x en el código de Python 3.x. La herramienta lee el código fuente de Python 2.x y aplica una serie de reparadores para transformarlo en un código válido de Python 3.x. La herramienta 2to3 está disponible en la biblioteca estándar como lib2to3, que contiene un amplio conjunto de fijadores que manejarán casi todo el código. Dado que lib2to3 es una biblioteca genérica, es posible escribir sus propios fijadores para 2to3. Examples Uso básico Considere el siguiente código Python2.x. Guarde el archivo como example.py Python 2.x 2.0 Enelarchivoanterior,hayvariaslíneasincompatibles.Elmétodoraw_input()sehareemplazado coninput()enPython3.xylaprint ya noesunadeclaración, sino unafunción.Este códigose puede convertir a código Python 3.x usando la herramienta 2to3. Unix Windows La ejecución del código anterior generará las diferencias con respecto al archivo fuente original, como se muestra a continuación.
    • 524. 459 def greet(name): print("Hello, {0}!".format(name)) print("What's your name?") name = input() greet(name) $ 2to3 -w example.py > path/to/2to3.py -w example.py Las modificaciones se pueden volver a escribir en el archivo de origen utilizando el indicador -w. Se crea una copia de seguridad del archivo original llamado example.py.bak , a menos que se indique el distintivo -n. Unix Windows Ahora el archivo example.py se ha convertido de Python 2.x al código de Python 3.x. Una vez finalizado, example.py contendrá el siguiente código válido de Python3.x: Python 3.x 3.0 RefactoringTool: Skipping implicit fixer: idioms RefactoringTool: Skipping implicit fixer: set_literal RefactoringTool: Skipping implicit fixer: ws_comma RefactoringTool: Refactored example.py ---example.py (original) +++ example.py (refactored) @@ -1,5 +1,5 @@ def greet(name): - print "Hello, {0}!".format(name) -print "What's your name?" -name = raw_input() + print("Hello, {0}!".format(name)) +print("What's your name?") +name = input() greet(name) RefactoringTool: Files that need to be modified: RefactoringTool: example.py
    • 525. 460 pip install pydotplus pip install https://github.com/carlos-jenkins/pydotplus/archive/master.zip import pydotplus graph_a = pydotplus.graph_from_dot_file('demo.dot') graph_a.write_svg('test.svg') # generate graph in svg. Capítulo 96: herramienta grafica Introducción Las herramientas de python se pueden usar para generar graficos. Examples PyDotPlus PyDotPlus es una versión mejorada del antiguo proyecto pydot que proporciona una interfaz Python al lenguaje Dot de Graphviz. Instalación Para la última versión estable: Para la versión de desarrollo: Cargar gráfico como se define por un archivo DOT • Se asume que el archivo está en formato DOT. Se cargará, se analizará y se devolverá una clase Dot, que representa el gráfico. Por ejemplo, un simple demo.dot: digraph demo1 {a -> b -> c; c -> a; } Obtendrá un svg (gráficos vectoriales escalables) como este:
    • 526. 461 import pygraphviz as pgv G = pgv.AGraph("demo.dot") G.draw('test', format='svg', prog='dot') PyGraphviz Obtenga PyGraphviz del Índice de Paquetes de Python en http://pypi.python.org/pypi/pygraphviz O instálalo con: pip install pygraphviz y se intentará encontrar e instalar una versión adecuada que coincida con su sistema operativo y la versión de Python. Puede instalar la versión de desarrollo (en github.com) con: pip install git://github.com/pygraphviz/pygraphviz.git#egg=pygraphviz Obtenga PyGraphviz del Índice de Paquetes de Python en http://pypi.python.org/pypi/pygraphviz O instálalo con: easy_install pygraphviz y se intentará encontrar e instalar una versión adecuada que coincida con su sistema operativo y la versión de Python. Cargar gráfico como se define por un archivo DOT • Se asume que el archivo está en formato DOT. Se cargará, se analizará y se devolverá una clase Dot, que representa el gráfico. Por ejemplo, un simple demo.dot: digraph demo1 {a -> b -> c; c -> a; } • Cárgalo y dibújalo. Obtendrá un svg (gráficos vectoriales escalables) como este:
    • 527. 462
    • 528. 463 import ijson def load_json(filename): with open(filename, 'r') as fd: parser = ijson.parse(fd) ret = {'builders': {}} for prefix, event, value in parser: if (prefix, event) == ('builders', 'map_key'): buildername = value ret['builders'][buildername] = {} elif prefix.endswith('.shortname'): ret['builders'][buildername]['shortname'] = value return ret if name == " main ": load_json('allthethings.json') Capítulo 97: ijson Introducción ijson es una excelente biblioteca para trabajar con archivos JSON en Python. Desafortunadamente, de forma predeterminada, utiliza un analizador Python JSON puro como su backend. Se puede lograr un rendimiento mucho mayor utilizando un backend C. Examples Ejemplo simple Ejemplo de ejemplo Tomado de un punto de referencia ENLACE DE ARCHIVO JSON
    • 529. 464 print "Hello World!" import clr from System import Console Console.WriteLine("Hello World!") Capítulo 98: Implementaciones no oficiales de Python Examples IronPython Implementación de código abierto para .NET y Mono escrito en C #, con licencia de Apache License 2.0. Se basa en DLR (Dynamic Language Runtime). Sólo es compatible con la versión 2.7, la versión 3 se está desarrollando actualmente. Diferencias con CPython: • Integración estrecha con .NET Framework. • Las cadenas son Unicode por defecto. • No admite extensiones para CPython escritas en C. • No sufre de Global Intérprete Lock. • El rendimiento suele ser menor, aunque depende de las pruebas. Hola Mundo También puedes usar las funciones .NET: enlaces externos • Sitio web oficial • Repositorio GitHub Jython Implementación de código abierto para JVM escrita en Java, con licencia de Python Software Foundation License. Sólo es compatible con la versión 2.7, la versión 3 se está desarrollando actualmente. Diferencias con CPython:
    • 530. 465 print "Hello World!" from java.lang import System System.out.println("Hello World!") • Integración estrecha con JVM. • Las cuerdas son Unicode. • No admite extensiones para CPython escritas en C. • No sufre de Global Intérprete Lock. • El rendimiento suele ser menor, aunque depende de las pruebas. Hola Mundo También puedes usar las funciones de Java: enlaces externos • Sitio web oficial • Repositorio mercurial Transcrypt Transcrypt es una herramienta para precompilar un subconjunto bastante extenso de Python en un Javascript compacto y legible. Tiene las siguientes características: • Permite la programación OO clásica con herencia múltiple utilizando la sintaxis de Python pura, analizada por el analizador nativo de CPython • Integración perfecta con el universo de bibliotecas de JavaScript de alta calidad orientadas a la web, en lugar de las de Python orientadas al escritorio • Sistema de módulo jerárquico basado en URL que permite la distribución de módulos a través de PyPi • Relación simple entre la fuente Python y el código JavaScript generado para una fácil depuración • Mapas de referencia de niveles múltiples y anotación opcional del código de destino con referencias de origen • Descargas compactas, kB's en lugar de MB's • Código JavaScript optimizado, que utiliza memoization (almacenamiento en caché de llamadas) para omitir opcionalmente la cadena de búsqueda de prototipos • La sobrecarga del operador se puede activar y desactivar localmente para facilitar las matemáticas numéricas legibles Tamaño y velocidad del código
    • 531. 466 <script src=" javascript /hello.js"></script> <h2>Hello demo</h2> <p> <div id = "greet">...</div> <button onclick="hello.solarSystem.greet ()">Click me repeatedly!</button> <p> <div id = "explain">...</div> <button onclick="hello.solarSystem.explain ()">And click me repeatedly too!</button> from itertools import chain class SolarSystem: planets = [list (chain (planet, (index + 1,))) for index, planet in enumerate (( ('Mercury', 'hot', 2240), ('Venus', 'sulphurous', 6052), ('Earth', 'fertile', 6378), ('Mars', 'reddish', 3397), ('Jupiter', 'stormy', 71492), ('Saturn', 'ringed', 60268), ('Uranus', 'cold', 25559), ('Neptune', 'very cold', 24766) ))] lines = ( '{} is a {} planet', 'The radius of {} is {} km', '{} is planet nr. {} counting from the sun' ) def init (self): self.lineIndex = 0 def greet (self): self.planet = self.planets [int (Math.random () * len (self.planets))] document.getElementById ('greet') .innerHTML = 'Hello {}'.format (self.planet [0]) self.explain () def explain (self): document.getElementById ('explain').innerHTML = ( self.lines [self.lineIndex] .format (self.planet [0], self.planet [self.lineIndex + 1]) ) self.lineIndex = (self.lineIndex + 1) % 3 La experiencia ha demostrado que 650 kB de código fuente de Python se traducen aproximadamente en la misma cantidad de código fuente de JavaScript. La velocidad coincide con la velocidad del JavaScript manuscrito y puede sobrepasarlo si la memorización de llamadas está activada. Integración con HTML Integración con JavaScript y DOM
    • 532. 467 class A: def init (self, x): self.x = x def show (self, label): print ('A.show', label, self.x) class B: def init (self, y): alert ('In B constructor') self.y = y def show (self, label): print ('B.show', label, self.y) class C (A, B): def init (self, x, y): alert ('In Cconstructor') A. init (self, x) B. init (self, y) self.show ('constructor') def show (self, label): B.show (self, label) print ('C.show', label, self.x, self.y) a = A (1001) a.show ('america') b = B (2002) b.show ('russia') c = C (3003, 4004) c.show ('netherlands') show2 = c.show show2 ('copy') Integración con otras bibliotecas de JavaScript Transcrypt se puede utilizar en combinación con cualquier biblioteca de JavaScript sin medidas ni sintaxis especiales. En la documentación se dan ejemplos para ao react.js, riot.js, fabric.js y node.js. Relación entre Python y código JavaScript Pitón JavaScript solarSystem = SolarSystem ()
    • 533. 468 enlaces externos • Sitio web oficial: http://www.transcrypt.org/ • Repositorio: https://github.com/JdeH/Transcrypt var A = class ('A', [object], { get init () {return get (this, function (self, x) { self.x = x; });}, get show (){return get (this, function (self, label) { print ('A.show', label, self.x); });} }); var B = class ('B', [object], { get init () {return get (this, function (self, y) { alert ('In B constructor'); self.y = y; });}, get show (){return get (this, function (self, label) { print ('B.show', label, self.y); });} }); var C = class ('C', [A, B], { get init () {return get (this, function (self, x, y) { alert ('In C constructor'); A. init (self, x); B. init (self, y); self.show ('constructor'); });}, get show () {return get (this, function (self, label) { B.show (self, label); print ('C.show', label, self.x, self.y); });} }); var a = A (1001); a.show ('america'); var b = B (2002); b.show ('russia'); var c = C (3003, 4004); c.show ('netherlands'); var show2 = c.show; show2 ('copy');
    • 534. 469 >>> import random >>> print(random.randint(1, 10)) 4 >>> import random as rn >>> print(rn.randint(1, 10)) 4 import custom Capítulo 99: Importando modulos Sintaxis • importar nombre_módulo • import module_name.submodule_name • desde nombre_módulo import * • from module_name import submodule_name [, class_name , function_name , ... etc] • desde nombre_módulo importar nombre_algunos como nuevo_nombre • from module_name.submodule_name import class_name [, function_name , ... etc] Observaciones Importar un módulo hará que Python evalúe todo el código de nivel superior en este módulo para que aprenda todas las funciones, clases y variables que contiene el módulo. Cuando desee que un módulo suyo se importe en otro lugar, tenga cuidado con su código de nivel superior y if name == ' main ': en if name =='main':sinodeseaqueseejecutecuandose importe el módulo. Examples Importando un modulo Utilice la declaración de import : import module importará un módulo y luego le permitirá hacer referencia a sus objetos (valores, funciones y clases, por ejemplo) utilizando la sintaxis module.name . En el ejemplo anterior, se importa el módulo random , que contiene la función randint . Entonces, al importar random , puede llamar a randint con random.randint . Puedes importar un módulo y asignarlo a un nombre diferente: Si su archivo python main.py está en la misma carpeta que custom.py . Puedes importarlo así: También es posible importar una función desde un módulo:
    • 535. 470 from urllib.request import urlopen from hello import function from world import function function() #world's function will be invoked. Not hello's import hello import world hello.function() # exclusively hello's function will be invoked world.function() # exclusively world's function will be invoked >>> # Multiple modules >>> import time, sockets, random >>> # Multiple functions >>> from math import sin, cos, tan >>> # Multiple constants >>> from math import pi, e >>> print(pi) 3.141592653589793 >>> print(cos(45)) 0.5253219888177297 >>> print(time.time()) 1482807222.7240417 >>> from urllib.request import urlopen as geturl, pathname2url as path2url, getproxies >>> from math import factorial as fact, gamma, atan as arctan >>> import random.randint, time, sys Para importar funciones específicas más profundamente en un módulo, el operador de punto se puede usar solo en el lado izquierdo de la palabra clave de import : En Python, tenemos dos formas de llamar a la función desde el nivel superior. Uno es import y otro es from . Debemos utilizar la import cuando tenemos la posibilidad de colisión de nombres. Supongamos que tenemos el archivo hello.py y los archivos world.py que tienen la misma función llamada function . Entonces la declaración de import funcionará bien. En general la import le proporcionará un espacio de nombres. Pero si está lo suficientemente seguro, en todo su proyecto no hay forma de tener el mismo nombre de función que debe usar from declaración Múltiples importaciones se pueden hacer en la misma línea: Las palabras clave y la sintaxis que se muestran arriba también se pueden usar en combinaciones: >>> from math import sin >>> sin(1) 0.8414709848078965
    • 536. 471 fromrandomimportrandint#Syntax"fromMODULENAMEimportNAME1[,NAME2[,...]]" print(randint(1, 10)) # Out: 5 # Out: 3.14159265359 frommath import pi print(pi) random.randrange(1, 10) # works only if "import random" has been run before NameError: name 'random' is not defined import random random.randrange(1, 10) from module_name import * from math import * sqrt(2) # instead of math.sqrt(2) ceil(2.7) # instead of math.ceil(2.7) Importando nombres específicos desde un módulo En lugar de importar el módulo completo, solo puede importar nombres específicos: senecesitadeformafrom random ,porqueelintérpretedepythondebesaberdequérecursodebe importar una función o clase y import randint especifica la función o la clase en sí. Otro ejemplo a continuación (similar al anterior): El siguiente ejemplo generará un error, porque no hemos importado un módulo: Salidas: El intérprete de python no entiende lo que quieres decir con random . Debe declararse agregando import random al ejemplo: Importando todos los nombres de un módulo por ejemplo: >>> print(time.time()) 1482807222.7240417 >>> print(arctan(60)) 1.554131203080956 >>> filepath = "/dogs/jumping poodle (december).png" >>> print(path2url(filepath)) /dogs/jumping%20poodle%20%28december%29.png
    • 537. 472 def sqrt(num): print("I don't know what's the square root of {}.".format(num)) sqrt(4) # Output: I don't know what's the square root of 4. from math import * sqrt(4) # Output: 2.0 def f(): from math import * class A: from math import * SyntaxError: import * only allowed at module level # mymodule.py all = ['imported_by_star'] imported_by_star = 42 not_imported_by_star = 21 >>> from mymodule import * Esto importará todos los nombres definidos en el módulo math en el espacio de nombres global, excepto los nombres que comienzan con un guión bajo (lo que indica que el escritor siente que es solo para uso interno). Advertencia :si una función con el mismo nombre yasedefinió oimportó, se sobrescribirá . Casi siempre importando solo nombres específicos from math import sqrt, ceil es la forma recomendada : Las importaciones destacadas solo se permiten a nivel de módulo. Los intentos de realizarlas en definiciones de clase o función dan como resultado un SyntaxError . y ambos fallan con: La variable especial all Los módulos pueden tener una variable especial llamada all para restringir qué variables se importan cuando se usan from mymodule import * . Dado el siguiente módulo: Sólo imported_by_star ha sido importada cuando se utiliza from mymodule import * :
    • 538. 473 >>> from mymodule import not_imported_by_star >>> not_imported_by_star 21 import importlib random = importlib.import_module("random") collections_abc = importlib.import_module("collections.abc") Sin embargo, not_imported_by_star se puede importar explícitamente: Importación programática Python 2.x 2.7 Para importar un módulo a través de una llamada de función, use el módulo importlib (incluido en Python a partir de la versión 2.7): La función importlib.import_module() también importará el submódulo de un paquete directamente: Para versiones anteriores de Python, use el módulo imp . Python 2.x 2.7 Utilice las funciones imp.find_module y imp.load_module para realizar una importación programática. Tomado de la documentación de la biblioteca estándar NOuse import()paraimportar módulosmedianteprogramación.Haydetallessutiles relacionadosconsys.modules,elargumentofromlist,etc.quesonfácilesdepasarporalto,que importlib.import_module() maneja por ti. Importar módulos desde una ubicación de sistema de archivos arbitraria. import imp, sys def import_module(name): fp, pathname, description = imp.find_module(name) try: return imp.load_module(name, fp, pathname, description) finally: if fp: fp.close() >>> imported_by_star 42 >>> not_imported_by_star Traceback (most recent calllast): File "<stdin>", line 1, in <module> NameError: name 'not_imported_by_star' is not defined
    • 539. 474 import sys sys.path.append("/path/to/directory/containing/your/module") import mymodule from module.submodule import function if user_input == "os": os = import ("os") Si deseaimportarun móduloqueyanoexistecomo un módulointegrado enlaBiblioteca estándardePythonni comounpaqueteadicional,puedehacerloagregandolarutaal directorio donde se encuentra su módulo a sys.path Esto puede ser útil cuando existen varios entornos de Python en un host. Es importante que agregue la ruta al directorio en el que se encuentra mymodule , no la ruta al módulo en sí. Reglas PEP8 para Importaciones Algunas pautas de estilo PEP8 recomendadas para importaciones: 1. Las importaciones deben ser en líneas separadas: from math import sqrt, ceil from math importsqrt from math import ceil # Not recommended # Recommended 2. Ordene las importaciones de la siguiente manera en la parte superior del módulo: • Importaciones de la biblioteca estándar • Importaciones de terceros relacionados • Importaciones específicas de aplicaciones / bibliotecas locales 3. Se deben evitar las importaciones de comodines ya que genera confusión en los nombres en el espacio de nombres actual. Si lo hace from module import * , puede no estar claro siun nombre específico en su código proviene de module o no.Esto es doblemente cierto si tiene múltiples declaraciones from module import * -type. 4. Evite el uso de importaciones relativas; usa importaciones explícitas en su lugar. Importando submódulos Esto importa la function desde module.submodule . importar () función La función import () se puede usar para importar módulos donde el nombre solo se conoce en tiempo de ejecución
    • 540. 475 # 3.141592653589793 # 3 import math math.pi = 3 print(math.pi) reload(math) print(math.pi) mod = import (r"C:/path/to/file/anywhere/on/computer/module.py") # 3 # 3 import math math.pi = 3 print(math.pi) import math print(math.pi) if 'math' in sys.modules: # Is the ``math`` module in the register? del sys.modules['math'] # If so, remove it. import math print(math.pi) # 3.141592653589793 print(math.pi) # 3 import sys Esta función también se puede utilizar para especificar la ruta del archivo a un módulo Reimportando un módulo Cuando utilice el intérprete interactivo, es posible que desee volver a cargar un módulo. Esto puede ser útil si está editando un módulo y desea importar la versión más reciente, o si ha modificado un elemento de un módulo existente y desea revertir sus cambios. Tenga en cuenta que no puede volver a import el módulo para revertir: Esto se debe a que el intérprete registra todos los módulos que importa. Y cuando intenta reimportar un módulo, el intérprete lo ve en el registro y no hace nada. Por lo tanto, la manera más difícil de reimportar es usar la import después de eliminar el elemento correspondiente del registro: Pero hay más de una manera directa y sencilla. Python 2 Utilice la función de reload : Python 2.x 2.3 Python 3 # equivalent to import os
    • 541. 476 from importlib import reload reload(math) print(math.pi) # 3.141592653589793 # 3 import math math.pi = 3 print(math.pi) La función de reload ha movido a importlib : Python 3.x 3.0
    • 542. 477 from future import print_function # other imports and instructions go after future print('Hello world') Capítulo 100: Incompatibilidades que se mueven de Python 2 a Python 3 Introducción A diferencia de la mayoría de los idiomas, Python admite dos versiones principales. Desde 2008, cuando se lanzó Python 3, muchos han hecho la transición, mientras que muchos no lo han hecho. Para entender ambos, esta sección cubre las diferencias importantes entre Python 2 y Python 3. Observaciones Actualmente hay dos versiones compatibles de Python: 2.7 (Python 2) y 3.6 (Python 3). Además, las versiones 3.3 y 3.4 reciben actualizaciones de seguridad en formato de origen. Python 2.7 es compatible con versiones anteriores de la mayoría de las versiones anteriores de Python, y puede ejecutar el código de Python desde la mayoría de las versiones 1.xy 2.x de Python sin cambios. Está ampliamente disponible, con una extensa colección de paquetes. También es considerado obsoleto por los desarrolladores de CPython, y recibe solo seguridad y desarrollo de corrección de errores. Los desarrolladores de CPython tienen la intención de abandonar esta versión del lenguaje en 2020 . De acuerdo con la Propuesta 373 de mejora de Python, no hay lanzamientos futuros planeados de Python 2 después del 25 de junio de 2016, pero las correcciones de errores y las actualizaciones de seguridad serán compatibles hasta 2020. (No especifica cuál será la fecha exacta en 2020 para la fecha de caducidad de Python 2.) Python 3 rompió intencionalmente la compatibilidad con versiones anteriores, para abordar las preocupaciones que los desarrolladores de idiomas tenían con el núcleo del lenguaje. Python 3 recibe nuevos desarrollos y nuevas características. Es la versión del lenguaje con la que los desarrolladores del lenguaje pretenden avanzar. Durante el tiempo entre la versión inicial de Python 3.0 y la versión actual, algunas características de Python 3 se portaron en Python 2.6, y otras partes de Python 3 se ampliaron para tener una sintaxis compatible con Python 2. Por lo tanto, es posible escribir Python que funcionará tanto en Python 2 como en Python 3, mediante el uso de futuras importaciones y módulos especiales (como seis ). Las importaciones futuras deben estar al comienzo de su módulo: Para obtener más información sobre el módulo future , consulte la página correspondiente en
    • 543. 478 # null string for sep: prints as ABC # flush the output buffer, added in Python 3.3 # print space-separated arguments: "1 2 3" # print tuple "(1, 2, 3)" print("Flush this", flush=True) print(1, 2, 3) print((1, 2, 3)) print("Comma", "separated", "output", sep=",") # sep specifies the separator print("A", "B", "C", sep="") # print a newline (must use parentheses) # end specifies what to append (defaults to newline) # file specifies the output buffer print "Hello World" # SyntaxError print("Hello World") print() print("No newline", end="") print("Error", file=sys.stderr) print "Hello World" print # print a newline print "No newline", # add trailing comma to remove newline print >>sys.stderr, "Error" # print to stderr print("hello") # print "hello", since ("hello") == "hello" print() # print an empty tuple "()" print 1, 2, 3 # print space-separated arguments: "1 2 3" print(1, 2, 3) # print tuple "(1, 2, 3)" print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) la documentación de Python . La herramienta 2to3 es un programa de Python que convierte el código de Python 2.x en el código de Python 3.x; consulte también la documentación de Python . El paquete seis proporciona utilidades para la compatibilidad con Python 2/3: • Acceso unificado a bibliotecas renombradas • variables para los tipos de cadena / Unicode • Funciones para el método que se eliminó o se ha renombrado. Una referencia para las diferencias entre Python 2 y Python 3 se puede encontrar aquí . Examples Declaración de impresión vs. función de impresión En Python 2, print es una declaración: Python 2.x 2.7 En Python 3, print() es una función, con argumentos de palabras clave para usos comunes: Python 3.x 3.0 La función de impresión tiene los siguientes parámetros: sep es lo que separa los objetos que pasas para imprimir. Por ejemplo:
    • 544. 479 print('foo', 'bar', end='!') # out: foo bar! print('foo', end='~') print('bar') # out: foo~bar from future import print_function s = 'Cafe' # type(s) == str s = u'Café' # type(s) == unicode b = 'Lorem ipsum' # type(b) == str end es lo que sigue el final de la declaración de impresión. Por ejemplo: La impresión de nuevo después de una declaración de impresión final que no sea de nueva línea se imprimirá en la misma línea: Nota: Para compatibilidad futura, print función de print también está disponible en Python 2.6 en adelante; sin embargo, no se puede utilizar a menos que el análisis de la declaración de print se deshabilite con Estafunción tieneexactamente el mismoformatoquePython3,excepto quecarecedel parámetro de flush . Ver PEP 3105 para la justificación. Cuerdas: Bytes contra Unicode Python 2.x 2.7 En Python 2 hay dos variantes de cadena: las de bytes con tipo ( str ) y las de texto con tipo ( unicode ). EnPython 2, un objeto de tipo str es siempre una secuencia de bytes, pero se usa comúnmente tanto para texto como para datos binarios. Un literal de cadena se interpreta como una cadena de bytes. Hay dos excepciones: Puedes definir un literal de Unicode (texto) explícitamente prefijando el literal con u : Alternativamente, puede especificar que los literales de cadena de un módulo completo deberían crear literales Unicode (texto): print('foo', 'bar', sep='~') # out: foo~bar print('foo', 'bar', sep='.') # out: foo.bar
    • 545. 480 isinstance(s, basestring) # type(s) == str # type(s) == str (note the accented trailing e) s = 'Cafe' s = 'Café' # Or, if you really need a byte string: s = b'Cafe' # type(s) == bytes s = 'Café'.encode() # type(s) == bytes isinstance(s, str) u'Cafe' == 'Cafe' >>> ur'Café' File "<stdin>", line 1 ur'Café' ^ SyntaxError: invalid syntax Para verificar si su variable es una cadena (ya sea Unicode o una cadena de bytes), puede usar: Python 3.x 3.0 En Python 3, el tipo str es un tipo de texto Unicode. Además, Python 3 agregó un objeto de bytes , adecuado para "blobs" binarios o escrito en archivos independientes de lacodificación.Para crearun objeto de bytes,puedeprefijar b aun literal de cadena o llamar al método de encode la cadena: Para probar si un valor es una cadena, use: Python 3.x 3.3 También es posible prefijar literales de cadena con un prefijo u para facilitar la compatibilidad entre las bases de código de Python 2 y Python 3. Dado que, en Python 3, todas las cadenas son Unicode de forma predeterminada, el antepuesto de una cadena literal con u no tiene ningún efecto: Sin embargo, el prefijo ur cadena Unicode sin procesar de Python 2 no es compatible: Tenga en cuenta que debe encode un objeto de texto ( str ) de Python 3 para convertirlo en una representación de bytes de ese texto. La codificación predeterminada de este método es UTF-8 . Puede usar decode para pedir a un objeto de bytes texto Unicode que representa: from future import unicode_literals s = 'Café' # type(s) == unicode b = 'Lorem ipsum' # type(b) == unicode
    • 546. 481 from future import unicode_literals print(repr("hi")) # u'hi' b"abc"[0] == 97 b"abc"[0:1] == b"a" # -*- coding: utf8 -*- print("Hi, my name is Łukasz Langa.") print(u"Hi, my name is Łukasz Langa."[::-1]) print("Hi, my name is Łukasz Langa."[::-1]) # Output in Python 2 # Hi, my name is Łukasz Langa. # .agnaL zsakuŁ si eman ym ,iH # .agnaL zsaku��si eman ym ,iH # Output in Python 3 # Hi, my name is Łukasz Langa. # .agnaL zsakuŁ si eman ym ,iH # .agnaL zsakuŁ si eman ym,iH Python 2.x 2.6 Mientras que el tipo de bytes existe tanto en Python 2 como en 3, el tipo unicode solo existe en Python 2. Para usar las cadenas de Unicode implícitas de Python 3 en Python 2, agregue lo siguiente en la parte superior de su archivo de código: Python 3.x 3.0 Otra diferencia importante es que la indexaciónde bytes enPython 3 da como resultado una salida int como: Mientras se corta en un tamaño de uno, se obtiene un objeto de longitud de 1 bytes: Además, Python 3 corrige algunos comportamientos inusuales con Unicode, es decir, invierte cadenas de bytes en Python 2. Por ejemplo, se resuelve el siguiente problema : División entera Elsímbolodedivisiónestándar(/)funcionademaneradiferenteenPython3yPython2 cuando se aplica a enteros. CuandosedivideunenteroporotroenteroenPython3,laoperacióndedivisiónx / yrepresenta una verdadera división (usa el método truediv ) y produce un resultado de punto flotante. Mientras tanto, la misma operación en Python 2 representa una división clásica que redondea el resultado hacia el infinito negativo (también conocido como tomar el piso ). >>> b.decode() 'Café'
    • 547. 482 # equivalent to `/` in Python 3 from operator import truediv, floordiv assert truediv(10, 8) == 1.25 Por ejemplo: Código Salida Python 2 Salida Python 3 3 / 2 1 1.5 2 / 3 0 0.6666666666666666 -3 / 2 -2 -1.5 El comportamiento de redondeo hacia cero fue obsoleto en Python 2.2 , pero permanece en Python 2.7 por motivos de compatibilidad con versiones anteriores y se eliminó en Python 3. Nota:paraobtenerunresultado flotanteenPython2 (sinredondearelpiso)podemosespecificar unodelosoperandosconelpuntodecimal.Elejemploanteriorde2/3queda0enPython2se usará como 2 / 3.0 o 2.0 / 3 o 2.0/3.0 para obtener 0.6666666666666666 Código Salida Python 2 Salida Python 3 3.0 / 2.0 1.5 1.5 2 / 3.0 0.6666666666666666 0.6666666666666666 -3.0 / 2 -1.5 -1.5 También está el operador de división de piso ( // ), que funciona de la misma manera en ambasversiones:seredondeaal entero más cercano.(aunquesedevuelveunflotador cuandose usa con flotadores) En ambas versiones, el operador // asigna a floordiv . Código Salida Python 2 Salida Python 3 3 // 2 1 1 2 // 3 0 0 -3 // 2 -2 -2 3.0 // 2.0 1.0 1.0 2.0 // 3 0.0 0.0 -3 // 2.0 -2.0 -2.0 Uno puede imponer explícitamente la división verdadera o la división de piso usando funciones nativas en el módulo del operator :
    • 548. 483 # needs to be the first statement in a module from future import division Si bien es claro y explícito, el uso de funcionesde operadorpara cada división puede ser tedioso. Cambiar el comportamiento del operador / a menudo será preferido. Una práctica común es eliminar el comportamiento de división típico agregando la from future import division como la primera declaración en cada módulo: Código Salida Python 2 Salida Python 3 3 / 2 1.5 1.5 2 / 3 0.6666666666666666 0.6666666666666666 -3 / 2 -1.5 -1.5 from future import division garantiza que el operador / representa la división verdadera y solo dentro de los módulos que contienen la importación future , porlo queno hayrazones de peso para no habilitarla en todos los módulos nuevos. Nota:Algunosotroslenguajesdeprogramaciónutilizanelredondeohaciacero (truncamiento)en lugar de redondearhacia el infinitonegativo comoPython (es decir,enesos idiomas -3 / 2 == -1 ). Este comportamiento puede crear confusión al portar o comparar código. Nota sobre los operandos deflotación :Como alternativa alafrom future import division , se podría usar el símbolo de división habitual / y asegurarse de que al menos uno de los operandosesunaflotación: 3 / 2.0 == 1.5 .Sinembargo, estopuedeconsiderarseunamala práctica. Es demasiado fácil escribir el average = sum(items) / len(items) y olvidarse delanzar uno delosargumentosparaflotar.Además,estoscasospuedenevadirconfrecuenciaelaviso durantelaspruebas,porejemplo,sirealizapruebasenunamatrizquecontienefloatperorecibe una matriz de int s en producción. Además, si se usa el mismo código en Python 3, los programasqueesperanque3/23 / 2 == 1 seaVerdaderonofuncionaráncorrectamente. Vea PEP 238 para una explicación más detallada de por qué se cambió el operador de la división en Python 3 y por qué se debe evitar la división de estilo antiguo. Vea el tema de Matemáticas simples para más información sobre la división. Reducir ya no es una función incorporada. En Python 2, reduce está disponible comounafunción incorporada odesdeelpaquetefunctools (versión 2.6 enadelante), mientras queen Python 3, reduceestádisponible solo desdefunctools. Sin embargo, la sintaxis para reduce tanto en Python2 como en Python3 es la misma y es reduce(function_to_reduce, list_to_reduce) . assert floordiv(10, 8) == 1 # equivalent to `//`
    • 549. 484 >>> my_list = [1, 2, 3, 4, 5] >>> import operator >>> reduce(operator.truediv, my_list) 0.008333333333333333 >>> my_list = [1, 2, 3, 4, 5] >>> import operator, functools >>> functools.reduce(operator.truediv, my_list) 0.008333333333333333 print(range(1, 10)) # Out: [1, 2, 3, 4, 5, 6, 7, 8, 9] print(isinstance(range(1, 10), list)) # Out: True print(xrange(1, 10)) # Out: xrange(1, 10) print(isinstance(xrange(1, 10), xrange)) # Out: True print(range(1, 10)) # Out: range(1, 10) print(isinstance(range(1, 10), range)) Como ejemplo, consideremos reducir una listaa un solo valor al dividir cada uno de los números adyacentes. Aquí usamos la función truediv de la biblioteca del operator . En Python 2.x es tan simple como: Python 2.x 2.3 En Python 3.x el ejemplo se vuelve un poco más complicado: Python 3.x 3.0 También podemos utilizar from functools import reduce para evitar reduce llamadas con el nombre del espacio de nombres. Diferencias entre las funciones de rango y rango En Python 2, la función de range devuelve una lista, mientras que xrange crea un objeto de xrange especial, que es una secuencia inmutable, que a diferencia de otros tipos de secuencia incorporados, no admite el corte y no tiene métodos de index ni de count : Python 2.x 2.3 En Python 3, xrange se expandió a la secuencia de range , que ahora crea un objeto de range . No hay tipo xrange : Python 3.x 3.0
    • 550. 485 print(range(1, 10)[3:7]) # Out: range(3, 7) print(range(1, 10).count(5)) # Out: 1 print(range(1, 10).index(7)) # Out: 6 # range(10000000000000000) # The output would be: # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # MemoryError print(xrange(100000000000000000)) # Out: xrange(100000000000000000) print(list(range(1, 10))) # Out: [1, 2, 3, 4, 5, 6, 7, 8, 9] #forward-compatible from builtins import range Además, dado que Python 3.2, el range también admite el corte, index y count : La ventaja de usar un tipo de secuencia especial en lugar de una lista es que el intérprete no tiene que asignar memoria para una lista y llenarla: Python 2.x 2.3 Como generalmente se desea el último comportamiento, el primero se eliminó en Python 3.Si aún desea tener una lista en Python 3, simplemente puede usar el constructor list() en un objeto de range : Python 3.x 3.0 Compatibilidad Para mantenerla compatibilidadentrelas versionesdePython2.xyPython3.x, puedeusar el módulo builtins del future paquete externo para lograr tanto compatibilidad con versiones anteriores como compatibilidad con versiones anteriores: Python 2.x 2.0 # Out: True # print(xrange(1, 10)) # The output will be: #Traceback (most recent call last): # File "<stdin>", line 1, in <module> #NameError: name 'xrange' is not defined
    • 551. 486 #backward-compatible from past.builtins import xrange for i in xrange(10**8): pass first, second, *tail, last = [1, 2, 3, 4, 5] print(first) # Out: 1 print(second) # Out: 2 print(tail) # Out: [3, 4] print(last) # Out: 5 first, second, *tail, last = [1, 2, 3, 4] print(tail) # Out: [3] first, second, *tail, last = [1, 2, 3] print(tail) # Out: [] print(last) # Out: 3 begin, *tail = "Hello" print(begin) # Out: 'H' print(tail) Python 3.x 3.0 El range en la biblioteca future admite la segmentación, el index y el count en todas las versiones de Python, al igual que el método incorporado en Python 3.2+. Desembalaje Iterables Python 3.x 3.0 En Python 3, puedes descomprimir un iterable sin saber la cantidad exacta de elementos que contiene, e incluso tener una variable que mantenga el final del iterable. Para eso, proporciona una variable que puede recopilar una lista de valores. Esto se hace colocando un asterisco antes del nombre. Por ejemplo, desempaquetar una list : Nota : Al usar la sintaxis de la *variable , la variable siempre será una lista, incluso si el tipo original noera unalista.Puede contener cero o máselementos dependiendo del número de elementos en la listaoriginal. Del mismo modo, desempaquetando un str : for i in range(10**8): pass
    • 552. 487 person = ('John', 'Doe', (10, 16, 2016)) *_, (*_, year_of_birth) = person print(year_of_birth) # Out: 2016 *head, *tail = [1, 2] # Out: SyntaxError: two starred expressions in assignment {*range(4), 4, *(5, 6, 7)} # Out: {0, 1, 2, 3, 4, 5, 6, 7} iterable = [1, 2, 3, 4, 5] print(iterable) # Out: [1, 2, 3, 4, 5] print(*iterable) # Out: 1 2 3 4 5 tail = {'y': 2, 'z': 3} {'x': 1, **tail} # Out: {'x': 1, 'y': 2, 'z': 3} dict1 = {'x': 1, 'y': 1} dict2 = {'y': 2, 'z': 3} {**dict1, **dict2} # Out: {'x': 1, 'y': 2, 'z': 3} Ejemplo de desempaquetar una date ; _ se utiliza en este ejemplo como una variable desechable (solo nos interesa el valor del year ): Vale la pena mencionar que, dado que * consume una cantidad variable de elementos, no puede tener dos * s para el mismo iterable en una asignación; no sabría cuántos elementos entran en el primer desempaquetado y cuántos en el segundo : Python 3.x 3.5 Hasta ahora hemos discutido el desempaquetado en las tareas. * y ** se extendieron en Python . Ahora es posible tener varias operaciones de desempaquetado en una expresión: Python 2.x 2.0 También es posible descomprimir un iterable en argumentos de función: Python 3.x 3.5 Desembalar un diccionario usa dos estrellas adyacentes ** ( PEP 448 ): Esto permite anular valores antiguos y fusionar diccionarios. Python 3.x 3.0 # Out: ['e', 'l', 'l', 'o']
    • 553. 488 try: raise IOError, "input/output error" except IOError, exc: print exc # Works in Python 2, but syntax error in Python 3: map(lambda (x, y): x + y, zip(range(5), range(5))) # Same is true for non-lambdas: def example((x, y)): pass # Works in both Python 2 and Python 3: map(lambda x: x[0] + x[1], zip(range(5), range(5))) # And non-lambdas, too: def working_example(x_y): x, y = x_y pass try: raise IOError("input/output error") except IOError as exc: print(exc) try: file = open('database.db') except FileNotFoundError as e: raise DatabaseError('Cannot open {}') from e Python 3 eliminó el desempaquetado de tuplas en las funciones. Por lo tanto lo siguiente no funciona en Python 3 Ver PEP 3113 para una explicación detallada. Levantando y manejando excepciones EstaeslasintaxisdePython2,tengaencuentalascomas,enlaslíneasderaise yexcept : Python 2.x 2.3 En Python 3, el , la sintaxis se deja caer y se sustituye por el paréntesis y as palabra clave: Para la compatibilidad con versiones anteriores, la sintaxis de Python 3 también está disponible en Python 2.6 en adelante, por lo que debe usarse para todo el código nuevo que no necesita ser compatible con versiones anteriores. Python 3.x 3.0 Python 3 también agrega el encadenamiento de excepciones , en el que puede indicar que alguna otra excepción fue la causa de esta excepción. Por ejemplo La excepción generada en la declaración de except es de tipo DatabaseError , pero la excepción original está marcada como el atributo cause de esa excepción. Cuando se muestra el rastreo,
    • 554. 489 Traceback (most recent call last): File "<stdin>", line 2, in<module> FileNotFoundError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<stdin>", line 4, in <module> DatabaseError('Cannot open database.db') try: file = open('database.db') except FileNotFoundError as e: raise DatabaseError('Cannot open {}') Traceback (most recent call last): File "<stdin>", line 2, in<module> FileNotFoundError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 4, in <module> DatabaseError('Cannot open database.db') import sys import traceback try: funcWithError() except: sys_vers = getattr(sys, 'version_info', (0,)) if sys_vers < (3, 0): traceback.print_exc() raise Exception("new exception") try: file = open('database.db') except FileNotFoundError as e: la excepción original también se mostrará en el rastreo: Si lanza un bloque de except sin encadenamiento explícito: La traza es Python 2.x 2.0 Ninguno de los dos está soportado en Python 2.x; la excepción original y su rastreo se perderán si se genera otra excepción en el bloque de excepción. El siguiente código puede ser usado para compatibilidad: Python 3.x 3.3 Para "olvidar" la excepción lanzada anteriormente, use raise from None
    • 555. 490 g = (i for i in range(0, 3)) g.next() # Yields 0 g.next() # Yields 1 g.next() # Yields 2 Traceback (most recent call last): File "<stdin>", line 4, in<module> DatabaseError('Cannot open database.db') import six try: file = open('database.db') except FileNotFoundError as e: six.raise_from(DatabaseError('Cannot open {}'), None) g = (i for i in range(0, 3)) next(g) # Yields 0 next(g) # Yields 1 next(g) # Yields 2 Ahora el rastreo sería simplemente O para que sea compatible con Python 2 y 3 puede usar el paquete seis así: .next () método en los iteradores renombrados En Python 2, se puede recorrer un iterador usando un método llamado next en el mismo iterador: Python 2.x 2.3 EnPython 3, el método .next ha sido renombrado a . next ,reconociendosufunción"mágica", por lo que llamar a .next generará un AttributeError . La forma correcta de acceder a esta funcionalidadtantoenPython2comoenPython3esllamaralanextfunciónconeliteradorcomo argumento. Python 3.x 3.0 Este código es portátil en las versiones desde 2.6 hasta las versiones actuales. Comparación de diferentes tipos Python 2.x 2.3 Se pueden comparar objetos de diferentes tipos. Los resultados son arbitrarios, pero consistentes.EstánordenadosdemodoqueNoneesmenorquecualquierotracosa,lostipos numéricos son más pequeños que los tipos no numéricos y todo lo demás está ordenado lexicográficamenteportipo.Porlotanto,un intesmenorque un stry unatuplees mayor que una list : raise DatabaseError('Cannot open {}') from None
    • 556. 491 user_input = raw_input() l = [7, 'x', (1, 2), [5, 6], 5, 8.0, 'y', 1.2, [7, 8], 'z'] sorted(l) # Out: [1.2, 5, 7, 8.0, [5, 6], [7, 8], 'x', 'y', 'z', (1, 2)] 1 < 1.5 # Out: True [1, 2] > 'foo' # TypeError: unorderable types: list() > str() (1, 2) > 'foo' #TypeError: unorderable types: tuple() >str() [1, 2] > (1, 2) # TypeError: unorderable types: list() > tuple() >>> list = [1, 'hello', [3, 4], {'python': 2}, 'stackoverflow', 8, {'python': 3}, [5, 6]] >>> sorted(list, key=str) # Out: [1, 8, [3, 4], [5, 6], 'hello', 'stackoverflow', {'python': 2}, {'python': 3}] Esto se hizo originalmente para poder ordenar una lista de tipos mixtos y los objetos se agruparían por tipo: Python 3.x 3.0 Se produce una excepción al comparar diferentes tipos (no numéricos): Para ordenar las listas mixtas en Python 3 por tipos y para lograr la compatibilidad entre versiones, debe proporcionar una clave para la función ordenada: Elusodestrcomolafuncióndekeyconviertetemporalmentecadaelementoenunacadenasolo parafines decomparación. Luegovelarepresentación delacadenacomenzandocon[,', {o y es capaz de ordenarlas (y todos los siguientes caracteres). Entrada del usuario En Python 2, la entrada del usuario se acepta utilizando la función raw_input , Python 2.x 2.3 Mientras que en Python 3, la entrada del usuario se acepta usando la función de input . Python 3.x 3.0 [1, 2] > 'foo' # Out: False (1, 2) > 'foo' # Out: True [1, 2] > (1, 2) # Out: False 100 < [1, 'x'] < 'xyz' < (1, 'x') # Out: True
    • 557. 492 try: input = raw_input except NameError: pass d = {'a': 0, 'b': 1, 'c': 2, '!': 3} for key in d.keys(): if key.isalpha(): del d[key] EnPython2,lainput lafunciónaceptarálaentradaeinterpretarla.Sibienestopuedeserútil, tiene varias consideraciones de seguridad y seeliminó enPython 3.Para acceder a la misma funcionalidad, se puede usar eval(input()). Para mantener un script portátil en las dos versiones, puede colocar el código a continuación cerca de la parte superior de su script de Python: Cambios en el método del diccionario EnPython3,muchosdelosmétodosdeldiccionariotienenuncomportamientobastantediferente al de Python 2, y muchos también fueron eliminados: has_key , iter* y view* se han ido. En lugar ded.has_key(key) , quehabíaestado en desusodurante muchotiempo, ahora se debeusarlakey in d . En Python 2, las keys métodos de diccionario, values y items devuelven listas. En Python 3 devuelven los objetos de vista en su lugar;los objetos de vista no son iteradores, y se diferencian de ellos de dos maneras, a saber: • tienen tamaño (uno puede usar la función len en ellos) • Se pueden iterar varias veces. Además, como con los iteradores, los cambios en el diccionario se reflejan en los objetos de vista. Python 2.7 ha respaldado estos métodos desde Python 3; están disponibles como viewkeys , viewvalues y elementos de viewitems . Para transformar el código de Python 2 en el código de Python 3, los formularios correspondientes son: • d.keys() , d.values() y d.items() de Python 2 deben cambiarse a list(d.keys()) , list(d.values()) y list(d.items()) • d.iterkeys() , d.itervalues() y d.iteritems() deben cambiarse a iter(d.keys()) , o incluso mejor, iter(d) ; iter(d.values()) e iter(d.items()) respectivamente • y, finalmente, las llamadas al método Python 2.7 d.viewkeys() , d.viewvalues() y d.viewitems() se pueden reemplazar por d.keys() , d.values() y d.items() . Portar el código de Python 2 que itera sobre las claves del diccionario, los valores o los elementos mientras se muta a veces es complicado. Considerar: user_input = input()
    • 558. 493 exec('code') exec('code', global_vars) exec('code', global_vars, local_vars) exec 'code' exec 'code' in global_vars exec 'code' in global_vars, local_vars class A(object): @property def get(self): raise IOError ElcódigoparecequefuncionaríademanerasimilarenPython3,peroallíelmétododelaskeys devuelve un objeto de vista,no una lista, y si el diccionario cambia de tamaño mientras se repite, el código de Python 3 se bloqueará con RuntimeError: dictionary changed size during iteration . La solución es, por supuesto, escribir correctamente for key in list(d) . Demanera similar,los objetos de vista se comportande manera diferente alos iteradores: uno no puedeusar next()enellos,y unono puede reanudarlaiteración;ensulugar sereiniciaría;Siel código de Python 2 pasa el valor de retorno de d.iterkeys() , d.itervalues() o d.iteritems() a un método que espera un iterador en lugar de un iterable , entonces debería ser iter(d) , iter(d.values()) o iter(d.items()) en Python 3. La sentencia exec es una función en Python 3 EnPython2,execesunadeclaración,conunasintaxisespecial:execcode [inglobals[,locals]]. En Python 3, execahora es una función: exec(code, [, globals[, locals]]) , y la sintaxis de Python 2 generará un SyntaxError. Amedidaquesecambiólaprintdeunadeclaración aunafunción,tambiénseagregóuna importación future . Sin embargo, no hay from future import exec_function , ya que no es necesario:ladeclaraciónexecenPython2tambiénsepuedeusarconunasintaxisqueseve exactamentecomolainvocacióndelafunciónexecenPython3.Porlotanto,puedecambiarlas declaraciones Python 2.x 2.3 a las formas Python 3.x 3.0 y se garantiza que las últimas formas funcionarán de manera idéntica tanto en Python 2 como en Python 3. Error de la función hasattr en Python 2 En Python 2, cuando una propiedad hasattr un error, hasattr ignorará esta propiedad y devolverá False .
    • 559. 494 try: a.get except AttributeError: print("no get property!") p = getattr(a, "get", None) if p is not None: print(p) else: print("no get property!") Este error se corrige en Python3. Así que si usas Python 2, usa o use getattr en getattr lugar Módulos renombrados Algunos módulos en la biblioteca estándar han sido renombrados: Viejo nombre Nuevo nombre _winreg Winreg ConfigParser configparser copy_reg copyreg Cola cola SocketServer socketserver _markupbase markupbase reprimir reprender test.test_support test.support Tkinter tkinter class B(object): @property def get(self): return 'get in b' a = A() b = B() print 'a hasattr get: ', hasattr(a, 'get') # output False in Python 2 (fixed, True in Python 3) print 'b hasattr get', hasattr(b, 'get') # output True in Python 2 and Python 3
    • 560. 495 >>> X. mro ( main .X, object) >>> Y. mro ( main .Y, object) >>> 0755 # only Python 2 0o755 # both Python 2 and Python 3 class X: pass class Y(object): pass Viejo nombre Nuevo nombre tkFileDialog tkinter.filedialog urllib / urllib2 urllib, urllib.parse, urllib.error, urllib.response, urllib.request, urllib.robotparser Algunos módulos incluso se han convertido de archivos a bibliotecas. Tome tkinter y urllib desde arriba como ejemplo. Compatibilidad Al mantenerlacompatibilidadentrelas versionesdePython2.xy 3.x,puedeusarel paquete externo future para habilitar la importación de paquetes de biblioteca de nivel superior con nombres de Python 3.x en las versiones de Python 2.x. Constantes octales En Python 2, un literal octal podría definirse como Para asegurar la compatibilidad cruzada, use Todas las clases son "clases de nuevo estilo" en Python 3. En Python 3.x todas las clases son clases de nuevo estilo ; Al definir una nueva clase, Python implícitamente la hace heredar de un object . Como tal, especificar un object en una definición de class es completamente opcional: Python 3.x 3.0 Ambas de estas clases ahora contienen object en su mro (orden de resolución de métodos): Python 3.x 3.0 En Python 2.x clases son, por defecto, las clases de estilo antiguo; no heredan implícitamente del
    • 561. 496 >>> 1 <> 2 True >>> 1 <> 1 False >>> foo = 'hello world' >>> repr(foo) "'hello world'" >>> `foo` "'hello world'" class X: pass class Y(object): pass >>> Y. mro (<class ' main .Y'>, <type 'object'>) class mycls(object): """I am fully compatible with Python 2/3""" metaclass = type class mycls: """I am also fully compatible with Python 2/3""" object .Esto hace que la semántica de las clases difiera dependiendo de si agregamos explícitamente el object como una class base: Python 2.x 2.3 En este caso, si intentamos imprimir el mro de Y , mro una salida similar a la del caso Python 3.x : Python 2.x 2.3 Esto sucede porque hicimos que Y heredara explícitamente de un objeto al definirlo: class Y(object): pass . Para la clase X que no hereda del objeto, el atributo mro noexiste,alintentar acceder a él se obtiene un AttributeError . Para garantizar la compatibilidad entre ambas versiones de Python, las clases se pueden definir con el object como una clase base: Alternativamente, si la variable metaclass está configurada para type en el ámbito global, todas las clases definidas posteriormente en un módulo dado son implícitamente un estilo nuevo sin la necesidad de heredar explícitamente del object : Se eliminaron los operadores <> y ``, sinónimo de! = Y repr () En Python 2, <> es un sinónimo para != ; Del mismo modo, `foo` es un sinónimo de repr(foo) . Python 2.x 2.7 Python 3.x 3.0
    • 562. 497 "1deadbeef3".decode('hex') # Out: '\x1d\xea\xdb\xee\xf3' '\x1d\xea\xdb\xee\xf3'.encode('hex') # Out: 1deadbeef3 "1deadbeef3".decode('hex') # Traceback (most recent call last): # File "<stdin>", line 1, in<module> # AttributeError: 'str' object has no attribute 'decode' b"1deadbeef3".decode('hex') # Traceback (most recent call last): # File "<stdin>", line 1, in<module> # LookupError: 'hex' is not a text encoding; use codecs.decode() to handle arbitrary codecs '\x1d\xea\xdb\xee\xf3'.encode('hex') # Traceback (most recent call last): # File "<stdin>", line 1, in<module> # LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs b'\x1d\xea\xdb\xee\xf3'.encode('hex') # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # AttributeError: 'bytes' object has no attribute 'encode' import codecs codecs.decode('1deadbeef4', 'hex') # Out: b'\x1d\xea\xdb\xee\xf4' codecs.encode(b'\x1d\xea\xdb\xee\xf4', 'hex') # Out: b'1deadbeef4' codecs.encode(b'\x1d\xea\xdb\xee\xff', 'hex').decode('ascii') codificar / decodificar a hex ya no está disponible Python 2.x 2.7 Python 3.x 3.0 Sinembargo,comolosugiereelmensajedeerror,puedeusarelmódulodecodecs paralograrel mismo resultado: Tenga en cuenta que codecs.encode devuelve un objeto de bytes . Para obtener un objeto str simplemente decode a ASCII: >>> 1 <> 2 File "<stdin>", line 1 1 <> 2 ^ SyntaxError: invalid syntax >>> `foo` File "<stdin>", line 1 `foo` ^ SyntaxError: invalid syntax
    • 563. 498 x = 'hello world!' vowels = [x for x in 'AEIOU'] print (vowels) # Out: ['A', 'E', 'I', 'O', 'U'] print(x) # Out: 'U' x = 'hello world!' vowels = [x for x in 'AEIOU'] print (vowels) # Out: ['A', 'E', 'I', 'O', 'U'] print(x) # Out: 'hello world!' Función cmp eliminada en Python 3 En Python 3 se eliminó la función incorporada de cmp , junto con el método especial cmp . De la documentación: Lafuncióncmp()debetratar comopasada, yelmétodoespecial cmp ()yanose admite. Use lt () para clasificar, eq () con hash () , y otras comparaciones ricas según sea necesario. (Si realmente necesita la funcionalidad cmp() , puede usar la expresión (a > b) - (a < b) como equivalente para cmp(a, b) . Además, todas las funciones incorporadas que aceptaron el parámetro cmp ahora solo aceptan el parámetro de key clave única. Enelmódulofunctools tambiénhayunafunciónútilcmp_to_key(func) quelepermiteconvertirde una función de estilo cmp a una key estilo de key : Transformaruna funcióndecomparaciónde estiloantiguoenunafunciónclave.Se usacon herramientas que aceptanfunciones clave(como sorted(), min(), max(), heapq.nlargest() , heapq.nsmallest() , itertools.groupby() ). Esta función se utiliza principalmente como una herramienta detransiciónpara los programas quese conviertendesdePython2queadmiteelusodefuncionesdecomparación. Variables filtradas en la lista de comprensión. Python 2.x 2.3 Python 3.x 3.0 Como se puede ver en el ejemplo, en Python 2 se filtró el valor de x : ¡enmascaró a hello world! e imprimió U , ya que este fue el último valor de x cuando finalizó el bucle. Sin embargo, en Python 3 x imprime el hello world! originalmente definido hello world! , ya que la # Out: '1deadbeeff'
    • 564. 499 x = 'hello world!' vowels = [] for x in 'AEIOU': vowels.append(x) print(x) # Out: 'U' # Python 2.X >>> map(str, [1, 2, 3, 4, 5]) ['1', '2', '3', '4', '5'] >>> type(_) >>> <class 'list'> # Python 3.X >>> map(str, [1, 2, 3, 4, 5]) <map object at 0x*> >>> type(_) <class 'map'> # We need to apply map again because we "consumed" the previous map.... >>> map(str, [1, 2, 3, 4, 5]) >>> list(_) ['1', '2', '3', '4', '5'] >>> map(None, [0, 1, 2, 3, 0, 4]) [0, 1, 2, 3, 0, 4] >>> list(map(None, [0, 1, 2, 3, 0, 5])) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'NoneType' object is not callable variable local de la lista de comprensión no enmascara las variables del ámbito circundante. Además, ni las expresiones generadoras (disponibles en Python desde la versión 2.5) ni las comprensiones de diccionario o conjunto (que fueron respaldadas a Python 2.7 desde Python 3) filtran las variables en Python 2. Tenga en cuenta que tanto en Python 2 como enPython 3, las variables se filtrarán en el ámbito circundante cuando se use un bucle for: mapa() map() es un componente que es útil para aplicar una función a elementos de un iterable. En Python 2, el map devuelve una lista.En Python 3, map devuelve un objeto map , que es un generador. En Python 2, puede pasar None para que funcione como una función de identidad. Esto ya no funciona en Python 3. Python 2.x 2.3 Python 3.x 3.0
    • 565. 500 >>> map(None, [1, 2, 3], [1, 2], [1, 2, 3, 4, 5]) [(1, 1, 1), (2, 2, 2), (3, None, 3), (None, None, 4), (None, None, 5)] >>> list(map(lambda x, y, z: (x, y, z), [1, 2, 3], [1, 2], [1, 2, 3, 4, 5])) [(1, 1, 1), (2, 2, 2)] # to obtain the same padding as in Python 2 use zip_longest from itertools >>> import itertools >>> list(itertools.zip_longest([1, 2, 3], [1, 2], [1, 2, 3, 4, 5])) [(1, 1, 1), (2, 2, 2), (3, None, 3), (None, None, 4), (None, None, 5)] >>> [str(i) for i in [1, 2, 3, 4, 5]] ['1', '2', '3', '4', '5'] >>> s = filter(lambda x: x.isalpha(), 'a1b2c3') >>> s 'abc' >>> s = map(lambda x: x * x, [0, 1, 2]) >>> s [0, 1, 4] >>> s = zip([0, 1, 2], [3, 4, 5]) >>> s [(0, 3), (1, 4), (2, 5)] >>> it = filter(lambda x: x.isalpha(), 'a1b2c3') Además, al pasar más de un iterable como argumento en Python 2, el map rellena los iterables más cortos con None (similar a itertools.izip_longest ). En Python 3, la iteración se detiene después de la iteración más corta. En Python 2: Python 2.x 2.3 En Python 3: Python 3.x 3.0 Nota :enlugar de un map considere utilizarlistasde comprensión,quesoncompatibles con Python 2/3. Reemplazo del map(str, [1, 2, 3, 4, 5]) : filter (), map () y zip () devuelven iteradores en lugar de secuencias Python 2.x 2.7 En el filterPython 2, las funciones incorporadas de map y zip devuelven una secuencia. map y zip siempre devuelven una lista, mientras que con el filter el tipo de retorno depende del tipo de parámetro dado: Python 3.x 3.0 En el filter Python 3, el map y el zip iterador de retorno en sulugar:
    • 566. 501 import foo from .moduleY import spam from.moduleYimportspamasham from . import moduleY from ..subpackage1 import moduleY from ..subpackage2.moduleZ import eggs from ..moduleA import foo from ...package import bar from ...sys import path Desde Python 2, itertools.izip es equivalente a Python 3 zip izip se ha eliminado en Python 3. Importaciones absolutas /relativas En Python 3,PEP 404 cambia la forma en que funcionan las importaciones desde Python 2.Ya no se permiten las importaciones relativas implícitas en los paquetes y from ... import * solo se permiten en el código de nivel de módulo. Para lograr el comportamiento de Python 3 en Python 2: • lacaracterísticadeimportacionesabsolutassepuedehabilitarfrom future import absolute_import • Se alientan las importaciones relativas explícitas en lugar de las importacionesrelativas implícitas Para aclarar, en Python 2, un módulo puede importar el contenido de otro módulo ubicadoen el mismo directorio de la siguiente manera: Observe que la ubicación de foo es ambigua desde la declaración de importación solo.Este tipo deimportaciónrelativaimplícitasedesaconseja,portanto,a favordelas importaciones relativas explícitas , que se parecen a lassiguientes: El punto . Permite una declaración explícita dela ubicación del módulo dentro del árbol de directorios. >>> it <filter object at 0x00000098A55C2518> >>> ''.join(it) 'abc' >>> it = map(lambda x: x * x, [0, 1, 2]) >>> it <map object at 0x000000E0763C2D30> >>> list(it) [0, 1, 4] >>> it = zip([0, 1, 2], [3, 4, 5]) >>> it <zip object at 0x000000E0763C52C8> >>> list(it) [(0, 3), (1, 4), (2, 5)]
    • 567. 502 shapes ├── init .py | ├── circle.py | ├── square.py | └── triangle.py from . import util # use util.PI, util.sq(x), etc from .util import * #use PI, sq(x), etc to call functions from .. import util # use util.PI, util.sq(x), etc from ..util import * # use PI, sq(x), etc to call functions Más sobre Importaciones Relativas Considere algún paquete definido por el usuario llamado shapes . La estructura del directorio es la siguiente: circle.py , square.py y triangle.py importan util.py como un módulo. ¿Cómo se referirán a un módulo en el mismonivel? O El.Seutilizaparaimportacionesrelativasdelmismo nivel. Ahora,considereundiseñoalternativodelmódulodeshapes: Ahora, ¿cómo se referirán estas 3 clases a util.py? O └── util.py ├── triangle.py │ ├── init .py │ | shapes ├── init .py | ├── circle │ ├── init .py │ └── circle.py | ├── square │ ├── init .py │ └── square.py | ├── triangle
    • 568. 503 import io assert io.open is open # the builtin is an alias buffer = io.StringIO() buffer.write('hello,')#returnsnumberofcharacterswritten buffer.write('world!\n') buffer.getvalue() # 'hello, world!\n' with open('data.txt') as f: first_line = next(f) assert type(first_line) is str with open('data.bin', 'rb') as f: first_kb = f.read(1024) assert type(first_kb) is bytes with open('old_japanese_poetry.txt', 'shift_jis') as text: haiku = text.read() round(1.5) # Out: 2.0 round(0.5) # Out: 1.0 round(-0.5) # Out: -1.0 round(-1.5) # Out: -2.0 El..seutilizaparalasimportaciones relativasdenivelpadre.Añadir más. sconnúmerode niveles entre el padre y el niño. Archivo I / O file ya no es un nombre incorporado en 3.x ( open aún funciona). Los detalles internos del archivo de E / S se han trasladado al módulo de la biblioteca estándar io , que también es el nuevo hogar de StringIO : El modo de archivo (texto frente a binario) ahora determina el tipo de datos producidos al leer un archivo (y el tipo requerido para escribir): La codificación de los archivos de texto se establece de forma predeterminada en locale.getpreferredencoding(False) . Para especificar una codificación explícitamente, use el parámetro de palabra clave de encoding : La función round () rompe el empate y devuelve el tipo rotura de corbata redonda () En Python 2, usar round() en un número igualmente cercano a dos enteros devolverá el más alejado de 0. Por ejemplo: Python 2.x 2.7 Sin embargo, en Python 3, round() devolverá el entero par (también conocido como redondeo de banqueros ). Por ejemplo:
    • 569. 504 round(4.8) # 5 round(4.8) # 5.0 round(1.5) # Out: 2 round(0.5) # Out: 0 round(-0.5) # Out: 0 round(-1.5) # Out: -2 True, False = False, True True # False False # True Python 3.x 3.0 La función round () sigue la mitad de la estrategia de redondeo uniforme que redondeará los números a mitad de camino al entero par más cercano (por ejemplo, round(2.5) ahora devuelve 2 en lugar de 3.0). Según la referencia en Wikipedia , esto también se conoce como redondeo imparcial , redondeo convergente , redondeo estadístico, redondeo holandés , redondeo gaussiano o redondeo impar . La mitad del redondeo uniforme es parte del estándar IEEE 754 y también es el modo de redondeo predeterminado en .NET de Microsoft. Esta estrategia de redondeo tiende a reducir el error de redondeo total. Como en promedio, la cantidad de números que se redondean es la misma que la cantidad de números que se redondean hacia abajo, los errores de redondeo se cancelan. En cambio, otros métodos de redondeo tienden a tener un sesgo hacia arriba o hacia abajo en el error promedio. round () tipo de retorno La función round() devuelve un tipo float en Python 2.7 Python 2.x 2.7 A partir de Python 3.0, si se omite el segundo argumento (número de dígitos), devuelve un int . Python 3.x 3.0 Verdadero, Falso y Ninguno En Python 2, True , False y None son constantes integradas. Lo que significa que es posible reasignarlos. Python 2.x 2.0 No puedes hacer esto con None desde Python 2.4.
    • 570. 505 hi = sys.stdout.write('hello world\n') # Out: hello world type(hi) # Out: <type 'NoneType'> True, False = False, True # SyntaxError: can't assign to keyword None = None # SyntaxError: can't assign to keyword None = None # SyntaxError: cannot assign to None import sys char_count = sys.stdout.write('hello world □\n') # Out: hello world □ char_count # Out: 14 byte_count = sys.stdout.buffer.write(b'hello world \xf0\x9f\x90\x8d\n') # Out: hello world □ byte_count # Out: 17 >>> 2**31 2147483648L >>> type(2**31) <type 'long'> >>> 2**30 1073741824 >>> type(2**30) Python 2.x 2.4 En Python 3, True , False y None ahora son palabras clave. Python 3.x 3.0 Devolver valor al escribir en un objeto de archivo En Python 2, escribir directamente en un identificador de archivo devuelve None : Python 2.x 2.3 En Python 3, escribir en un identificador devolverá el número de caracteres escritos al escribir texto, y el número de bytes escritos al escribir bytes: Python 3.x 3.0 largo vs. int En Python 2, cualquier entero mayor que un C ssize_t se convertiría en el tipo de datos long , indicado por un sufijo L en el literal. Por ejemplo, en una compilación de Python de 32 bits: Python 2.x 2.7
    • 571. 506 class MyClass: def nonzero (self): return False my_instance = MyClass() print bool(MyClass) # True print bool(my_instance) # False # True # False class MyClass: def bool (self): return False my_instance = MyClass() print(bool(MyClass)) print(bool(my_instance)) Sin embargo, en Python 3, el tipo de datos long fue eliminado; no importa qué tan grande sea el número entero, será un int . Python 3.x 3.0 2**1024 # Output: 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021 print(-(2**1024)) # Output: - 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021 type(2**1024) # Output: <class 'int'> Valor booleano de clase Python 2.x 2.7 EnPython 2, si desea definir un valor booleano de clase por sí mismo,debe implementar el método nonzero en su clase. El valor es True pordefecto. Python 3.x 3.0 En Python 3, bool se usa en lugar de nonzero <type 'int'> >>> 2**31 - 1 # 2**31 is long and long - int is long 2147483647L
    • 572. 507 Capítulo 101: Indexación y corte Sintaxis • obj [inicio: detener: paso] • cortar • rebanada (inicio, parada [, paso]) Parámetros Paramer Descripción obj El objeto del que desea extraer un "subobjeto" de start El índice de obj que desea que comience el subobjeto (tenga en cuenta que Python tiene un índice de cero, lo que significa que el primer elemento de obj tiene un índice de 0 ). Si se omite, el valor predeterminado es 0 . stop El índice (no incluido) de obj que desea que termine el subobjeto.Si se omite, el valor predeterminado es len(obj) . step Le permite seleccionar solo cada elemento de step . Si se omite, el valor predeterminado es 1 . Observaciones Puede unificar el concepto de corte de cadenas con el de cortar otras secuencias al ver las cadenas como una colección de caracteres inmutables, con la advertencia de que un carácter Unicode está representado por una cadena de longitud 1. Enlanotaciónmatemática,puedeconsiderardividirparausarunintervalosemiabiertode[start, end),esdecir,queelinicioestáincluidoperoelfinalno.Lanaturalezasemiabiertadelintervalo tiene la ventaja de que len(x[:n])= n donde len(x)> = n , mientras que el intervalo que se cierra al inicio tiene la ventaja de que x[n:n+1] = [x[n]] donde x es una lista con len(x) >= n , manteniendo así la coherencia entre la notación de indexación y de corte. Examples Rebanado basico Para cualquier iterable (por ejemplo, una cadena, lista, etc.), Python le permite dividir y devolver una subcadena o una lista secundaria de sus datos. Formato para rebanar:
    • 573. 508 # "ace" (every 2nd element) # "bd" (from index 1, to index 4 (excluded), every 2nd element) a[::2] a[1:4:2] # "abcde" (from index 0 (default), to the second last element (last element - 1)) # "abcd" (from index 0 (default), to the third last element (last element -2)) # "f" (from the last element to the end (default len()) a[:-1] a[:-2] a[-1:] a[3:1:-1] # "dc" (from index 2 to None (default), in reverse order) a[::-1] # "fedcba" (from last element (default len()-1), to first, in reverse order(-1)) a[5:None:-1] # "fedcba" (this is equivalent to a[::-1]) a[5:0:-1] # "fedcb" (from the last element (index 5) to second element (index 1) dónde, • start es el primer índice de la rebanada. Por defecto es 0 (el índice del primer elemento) • stop uno más allá del último índice de la rebanada. Por defecto a len (iterable) • step es el tamaño del paso (mejor explicado porlos ejemplos a continuación) Ejemplos: Además, cualquiera de los anteriores se puede utilizar con el tamaño de paso definido: Los índices pueden ser negativos, en cuyo caso se calculan desde el final de la secuencia. Los tamaños de los pasos también pueden ser negativos, en cuyo caso la división se repetirá en orden inverso: Este constructo es útil para revertir un iterable. Tenga en cuenta que para los pasos negativos, el end_index predeterminado es None (consulte http://stackoverflow.com/a/12521981 ) Hacer una copia superficial de una matriz Una forma rápida de hacer una copia de una matriz (en lugar de asignar una variable con otra a = "abcdef" a # "abcdef" # Same as a[:] or a[::] since it uses the defaults for all three indices a[- 1] # "f" a[:] #"abcdef" a[::] #"abcdef" a[3:] # "def" (from index 3, to end(defaults to size of iterable)) a[:4] # "abcd" (from beginning(default 0) to position 4 (excluded)) a[2:4] # "cd" (from position 2, to position 4 (excluded)) iterable_name[start:stop:step]
    • 574. 509 arr[:] arr = ['a', 'b', 'c'] copy = arr[:] arr.append('d') print(arr) # ['a', 'b', 'c', 'd'] print(copy) # ['a', 'b', 'c'] s = 'reverse me!' s[::-1] # '!em esrever' class MultiIndexingList: def init (self, value): self.value = value def repr (self): return repr(self.value) def getitem (self, item): if isinstance(item, (int, slice)): return self.class(self.value[item]) return [self.value[i] for i in item] def setitem (self, item, value): if isinstance(item, int): self.value[item] = value elif isinstance(item, slice): referencia a la matriz original) es: Vamosa examinarlasintaxis. [:]Mediosquestart , end , y sliceestán omitidos. Los valores predeterminados son 0 , len(arr)y 1 ,respectivamente, lo quesignifica que el subarregloque solicitamostendrátodosloselementosdearrdesdeelprincipiohastaelfinal. En la práctica, esto se parece a algo como: Como puede ver, arr.append('d') agregó d a arr , ¡pero la copy mantuvo sin cambios! Tenga en cuenta que esto hace una copia superficial y es idéntico a arr.copy() . Invertir un objeto Puedeusar cortespararevertir muyfácilmenteunastr,listotuple (obásicamentecualquier objeto de colección que implemente el corte con el parámetro de paso).Este es un ejemplo de inversión de una cadena, aunque esto se aplica igualmente a los otros tipos mencionados anteriormente: Veamos rápidamente la sintaxis. [::-1] significa que la división debe ser desde el principio hasta el final de la cadena (porque se omiten el start y el end ) y un paso de -1 significa que debe moverse a través de la cadena en sentidoinverso. Clases personalizadas de indexación: getitem , setitem y delitem
    • 575. 510 del a[4,2,5] a # Out: [1, 100, 4, 8] <-- indicated which element came from which index a = MultiIndexingList([1,2,3,4,5,6,7,8]) a # Out: [1, 2, 3, 4, 5, 6, 7, 8] a[1,5,2,6,1] # Out: [2, 6, 3, 7, 2] a[4, 1, 5:, 2, ::2] # Out: [5, 2, [6, 7, 8], 3, [1, 3, 5, 7]] # 4|1-|----50:---|2-|-----::2----- lst = [1, 2, 3] Esto permite el corte y la indexación para el acceso al elemento: Al configurar y eliminar elementos solo se permite la indexación de enteros separados por comas (sin rebanar): a[4] = 1000 a # Out: [1, 2, 3, 4, 1000, 6, 7, 8] a[2,6,1] = 100 a # Out: [1, 100, 100, 4, 1000, 6, 100, 8] del a[5] a # Out: [1, 100, 100, 4, 1000, 100, 8] Asignación de rebanada Otra característica interesante que utiliza los segmentos es la asignación de sectores. Python le permite asignar nuevos segmentos para reemplazar los segmentos antiguos de una lista en una sola operación. Esto significa que si tiene una lista, puede reemplazar varios miembros en una sola tarea: raise ValueError('Cannot interpret slice with multiindexing') else: for i in item: if isinstance(i, slice): raise ValueError('Cannot interpret slice with multiindexing') self.value[i] = value def delitem (self, item): if isinstance(item, int): del self.value[item] elif isinstance(item, slice): del self.value[item] else: if any(isinstance(elem, slice) for elem in item): raise ValueError('Cannot interpret slice with multiindexing') item = sorted(item, reverse=True) for elem in item: del self.value[elem]
    • 576. 511 lst = [1, 2, 3, 4, 5] lst[1:4] = [6] print(lst) # Out: [1, 6, 5] lst = [1, 2, 3] lst[:] = [4, 5, 6] print(lst) # Out: [4, 5, 6] lst = [1, 2, 3] lst[-2:] = [4, 5, 6] print(lst) # Out: [1, 4, 5, 6] >>> programmer_1 = [ 1956, 'Guido', 'van Rossum', 'Python', 'Netherlands'] >>> programmer_2 = [ 1815, 'Ada', 'Lovelace', 'Analytical Engine', 'England'] >>> name_columns = slice(1, 3) >>> programmer_1[name_columns] ['Guido', 'van Rossum'] >>> programmer_2[name_columns] ['Ada', 'Lovelace'] arr = ['a', 'b', 'c', 'd'] print(arr[0]) >> 'a' print(arr[1]) La asignación tampoco debe coincidir en tamaño, por lo que si desea reemplazar una porción antigua por una nueva que es de tamaño diferente, podría: También es posible usar la sintaxis de corte conocida para hacer cosas como reemplazar toda la lista: O solo los dos últimos miembros: Rebanar objetos Los cortes son objetos en sí mismos y se pueden almacenar en variables con la función de slice() incorporada. Las variables de división se pueden usar para hacer que su código sea más legible y para promover la reutilización. Indexación básica Las listas de Python están basadas en 0, es decir, se puede acceder al primer elemento de la lista mediante el índice 0 Puede acceder al segundo elemento de la lista por índice 1 , tercer elemento por índice 2 y así sucesivamente: lst[1:3] = [4, 5] print(lst) # Out: [1, 4, 5]
    • 577. 512 print(arr[-1]) >> 'd' print(arr[-2]) >> 'c' print arr[6] Traceback (most recent call last): File "<stdin>", line 1, in<module> IndexError: list index out of range También puede usar índices negativos para acceder a los elementos del final de la lista. p.ej. El índice -1 le dará el último elemento de la lista y el índice -2 le dará el segundo elemento de la lista: Si intenta acceder a un índice que no está presente en la lista, se IndexError un IndexError : >> 'b' print(arr[2]) >> 'c'
    • 578. 513 headers_set = [] headers_sent = [] def write (data): """ Writes header data from 'start_response()' as well as body data from 'response' to system standard output. """ if not headers_set: raise AssertionError("write() before start_response()") elif not headers_sent: status, response_headers = headers_sent[:] = headers_set sys.stdout.write('Status: %s\r\n' % status) for header in response_headers: sys.stdout.write('%s: %s\r\n' % header) sys.stdout.write('\r\n') sys.stdout.write(data) sys.stdout.flush() def start_response(status, response_headers): """ Sets headers for the response returned by this server.""" if headers_set: raise AssertionError("Headers already set!") headers_set[:] = [status, response_headers] return write = sys.stdin = sys.stderr import os, sys def run(application): environ['wsgi.input'] environ['wsgi.errors'] Capítulo 102: Interfaz de puerta de enlace de servidor web (WSGI) Parámetros Parámetro Detalles start_response Una función utilizada para procesar el inicio. Examples Objeto de servidor (Método) A nuestro objeto de servidor se le asigna un parámetro de 'aplicación' que puede ser cualquier objeto de aplicación que se pueda llamar (ver otros ejemplos). Primero escribe los encabezados, luego el cuerpo de datos devueltos por nuestra aplicación a la salida estándar del sistema.
    • 579. 514 # This is the most important piece of the 'server object' # Our result will be generated by the 'application' given to this method as a parameter result = application(environ, start_response) try: for data in result: if data: write(data) if not headers_sent: write('') # Body isn't empty send its data to 'write()' #Bodyisempty,sendemptystringto'write()'
    • 580. 515 pip install amqpstorm from amqpstorm import Connection def on_message(message): """This function is called on message received. :param message: Delivered message. :return: """ print("Message:", message.body) # Acknowledge that we handled the message without any issues. message.ack() # Reject the message. # message.reject() # Reject the message, and put it back in the queue. # message.reject(requeue=True) connection = Connection('127.0.0.1', 'guest', 'guest') Capítulo 103: Introducción a RabbitMQ utilizando AMQPStorm Observaciones La última versión de AMQPStorm está disponible en pypi o puede instalarla usando pip Examples Cómo consumir mensajes de RabbitMQ Comience con la importación de la biblioteca. Alconsumirmensajes,primerodebemosdefinirunafunciónparamanejarlosmensajesentrantes. Esta puede ser cualquier función que se pueda llamar y tiene que tomar un objeto de mensaje o una tupla de mensaje (según el parámetro to_tuple definido en start_consuming ). Además de procesar los datos del mensaje entrante, también tendremos que Reconocer o Rechazar el mensaje. Esto es importante, ya que necesitamos informar a RabbitMQ que recibimos y procesamos el mensaje correctamente. A continuación, debemos configurar la conexión al servidor RabbitMQ. Después de eso tenemos que configurar un canal. Cada conexión puede tener múltiples canales
    • 581. 516 channel = connection.channel() channel.basic.consume(callback=on_message, queue='simple_queue', no_ack=False) channel.start_consuming(to_tuple=False) from amqpstorm import Connection from amqpstorm import Message connection = Connection('127.0.0.1', 'guest', 'guest') channel = connection.channel() # Message Properties. properties = { 'content_type': 'text/plain', 'headers': {'key': 'value'} } # Create the message. message = Message.create(channel=channel, body='Hello World!', properties=properties) y, en general, al realizar tareas de subprocesos múltiples, se recomienda (pero no es obligatorio) tener uno por subproceso. Una vez que tengamos configurado nuestro canal, debemos informarle a RabbitMQ que queremos comenzar a consumir mensajes.Eneste caso, usaremos nuestra función on_message previamente definida para manejar todos nuestros mensajes consumidos. La cola que escucharemos en el servidor RabbitMQ será simple_queue , y también le estamos diciendo a RabbitMQ que reconoceremos todos los mensajes entrantes una vez que hayamos terminado con ellos. Finalmente, necesitamos iniciar el bucle IO para comenzar a procesar los mensajes entregados por el servidor RabbitMQ. Cómo publicar mensajes a RabbitMQ Comience con la importación de la biblioteca. Luego necesitamos abrir una conexión al servidor RabbitMQ. Después de eso tenemos que configurar un canal. Cada conexión puede tener múltiples canales y, en general, al realizar tareas de subprocesos múltiples, se recomienda (pero no es obligatorio) tener uno por subproceso. Una vez que tengamos configurado nuestro canal, podemos comenzar a preparar nuestro mensaje.
    • 582. 517 message.publish(routing_key='simple_queue') channel.queue.bind(exchange='amq.direct', routing_key='hello', queue='hello') delay_channel.queue.declare(queue='hello_delay', durable=True, arguments={ 'x-message-ttl': 5000, 'x-dead-letter-exchange': 'amq.direct', 'x-dead-letter-routing-key': 'hello' }) delay_channel.basic.publish(exchange='', Ahora podemos publicar el mensaje simplemente llamando a publish y proporcionando una routing_key . En este caso, vamos a enviar el mensaje a una cola llamada simple_queue . Cómo crear una cola retrasada en RabbitMQ Primero debemos configurar dos canales básicos, uno para la cola principal y otro para la cola de demora.En mi ejemplo al final, incluyo un par de marcas adicionales que no son necesarias, pero hacen que el código sea más confiable; tales como confirm delivery , delivery_mode y durable . Puede encontrar más información sobre estos en el manual de RabbitMQ. Después de configurar los canales, agregamos un enlace al canal principal que podemos utilizar para enviar mensajes desde el canal de retardo a nuestra cola principal. A continuación, debemos configurar nuestro canal de retardo para reenviar los mensajes a la cola principal una vez que hayan caducado. • x-message-ttl (Mensaje - Time To Live) Normalmente se usa para eliminar automáticamente los mensajes antiguos en la cola después de una duración específica, pero al agregar dos argumentos opcionales podemos cambiar este comportamiento y, en cambio, hacer que este parámetro determine en milisegundos el tiempo que los mensajes permanecerán en la cola de demora. • x-dead-letter-routing-key Esta variable nos permite transferir el mensaje a una cola diferente una vez que han caducado, en lugar del comportamiento predeterminado de eliminarlo por completo. • x-dead-letter-exchange Esta variable determina qué Exchange usó para transferir el mensaje de hello_delay a hello queue. Publicación en la cola de retardo Cuando hayamos terminado de configurar todos los parámetros básicos de Pika, simplemente envíe un mensaje a la cola de demora utilizando la publicación básica.
    • 583. 518 from amqpstorm import Connection connection = Connection('127.0.0.1', 'guest', 'guest') # Create normal 'Hello World' type channel. channel = connection.channel() channel.confirm_deliveries() channel.queue.declare(queue='hello', durable=True) # We need to bind this channel to an exchange, that will be used to transfer # messages from our delay queue. channel.queue.bind(exchange='amq.direct', routing_key='hello', queue='hello') # Create our delay channel. delay_channel = connection.channel() delay_channel.confirm_deliveries() # This is where we declare the delay, and routing for our delay channel. delay_channel.queue.declare(queue='hello_delay', durable=True, arguments={ 'x-message-ttl': 5000, # Delay until the message is transferred in milliseconds. 'x-dead-letter-exchange': 'amq.direct', # Exchange used to transfer the message from A to B. 'x-dead-letter-routing-key': 'hello' # Name of the queue we want the message transferred to. }) delay_channel.basic.publish(exchange='', routing_key='hello_delay', body='test', properties={'delivery_mode': 2}) print("[x] Sent") Una vez que haya ejecutado el script, debería ver las siguientes colas creadas en su módulo de administración RabbitMQ. Ejemplo. routing_key='hello_delay', body='test', properties={'delivery_mod': 2})
    • 584. 519 import collections >>> collections.Iterator() class MyIterable: def iter (self): return self def next (self): #code #Classic iterable object in older versions of python, getitem is still supported... class MySequence: def getitem (self, index): if (condition): raise IndexError return (item) #Can produce a plain `iterator` instance by using iter(MySequence()) Capítulo 104: Iterables e iteradores Examples Iterador vs Iterable vs generador Uniterable esun objeto que puede devolver un iterador.Cualquier objeto con estado que tenga un método iter y devuelva un iterador es iterable. También puede ser un objeto sin estado que implemente un método getitem . - El método puede tomar índices (comenzando desde cero) y generar un IndexError cuando los índices ya no son válidos. La clase str de Python es un ejemplo de getitem iterable. Un iterador es un objeto que produce el siguiente valor en una secuencia cuando llama al next(*object*) en algún objeto. Además, cualquier objeto con un método next esuniterador. Un iterador genera StopIteration después de agotar el iterador y no se puede reutilizar en este punto. Clases iterables Las clases iter definen un iter y next . Ejemplo de una clase iterable: Intentando crear una instancia de la clase abstracta del módulo de collections para ver mejor esto. Ejemplo: Python 2.x 2.3
    • 585. 520 class MyIterable(object): #or collections.Iterator, which I'd recommend.... .... def iter (self): return self defnext(self): #code next = next >>> TypeError: Cant instantiate abstract class Iterator with abstract methods next ex1 = MyIterableClass() ex2 = MySequence() for (item) in (ex1): #code for (item) in (ex2): #code [1, 2, 3] # list, iterate over items (1, 2, 3) # tuple {1, 2, 3} # set {1: 2, 3: 4} # dict, iterate over keys def foo(): # foo isn't iterable yet... yield 1 res = foo() # ...but res already is Python 3.x 3.0 Maneje la compatibilidad de Python 3 para las clases iterables en Python 2 haciendo lo siguiente: Python 2.x 2.3 Ambos son ahora iteradores y se pueden pasar a través de: Los generadores son formas simples de crear iteradores. Un generador es un iterador y un iterador es un iterable. Lo que puede ser iterable Iterable puede ser cualquier cosa por la cual los artículos se reciben uno por uno, solo hacia adelante . Las colecciones Python incorporadas son iterables: Los generadores devuelven iterables: Iterando sobre todo iterable >>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
    • 586. 521 a, = iterable def foo(): yield 1 a, = foo() # a = 1 nums = [1, 2, 3] a, = nums # ValueError: too many values to unpack s = {1, 2} # or list or generator or even iterator i = iter(s) # get iterator a = next(i) # a = 1 b = next(i) # b = 2 c = next(i) # raises StopIteration def gen(): yield 1 iterable = gen() for a in iterable: print a #What was the first item ofiterable? No way to get it now. # Only to get a new iterator gen() Verificar solo un elemento en iterable. Utilice el desembalaje para extraer el primer elemento y asegurarse de que sea el único: Extraer valores uno por uno. Comienceconiter() incorporado paraobtener iterador sobre iterable yusenext() paraobtener elementos uno por uno hasta que se StopIteration para StopIteration el final: ¡El iterador no es reentrante! s = {1, 2, 3} # get every element in s for a in s: print a # prints 1, then 2, then 3 # copy into list l1 = list(s) # l1 = [1, 2, 3] # use list comprehension l2 = [a * 2 for a in s if a > 2] # l2 = [6]
    • 587. 522 from kivy.app import App from kivy.uix.label import Label class Test(App): def build(self): return Label(text='Hello world') if name == 'main ': Test().run() from kivy.app import App from kivy.uix.label import Label Capítulo 105: kivy - Framework Python multiplataforma para el desarrollo de NUI Introducción NUI: una interfaz de usuario natural (NUI) es un sistema para la interacción persona-computadora que el usuario opera a través de acciones intuitivas relacionadas con el comportamiento humano natural y cotidiano. Kivy es una biblioteca de Python para el desarrollo de aplicaciones ricas en medios con capacidad multitáctil que se pueden instalar en diferentes dispositivos. La función multitáctil se refiere a la capacidad de una superficie sensible al tacto (generalmente una pantalla táctil o un trackpad) para detectar o detectar entradas provenientes de dos o más puntos de contacto simultáneamente. Examples Primera aplicación Para crear una aplicación kivy. 1. subclase la clase de aplicación 2. Implementar el método de construcción , que devolverá el widget. 3. Crea una instancia de la clase e invoca la carrera . Explicación La declaración anterior importará la aplicación de clase principal. Esto estará presente en su directorio de instalación directorio_instalación / kivy / app.py La declaración anterior importará la etiqueta del elemento ux. Todos los elementos ux están presentes en su directorio de instalación directorio_instalación / kivy / uix /.
    • 588. 523 def build(self): return Label(text='Hello world') if name == ' main ': Test().run() La declaración anterior es para crear su aplicación y el nombre de la clase será el nombre de su aplicación. Esta clase se hereda de la clase de la aplicación padre. La declaración anterior anula el método de compilación de la clase de aplicación. Lo que devolverá el widget que debe mostrarse cuando inicie la aplicación. La declaración anterior es el cuerpo del método de construcción. Está devolviendo la etiqueta con su texto Hola mundo . La declaración anterior es el punto de entrada desde donde el intérprete de Python comienza a ejecutar su aplicación. La declaración anterior Inicializa tu clase de prueba creando su instancia. E invoca la función de clase de aplicación run (). Su aplicación se verá como la imagen de abajo. class Test(App):
    • 589. 524
    • 590. 525 try: self.version = "Expat %d.%d.%d" % expat.version_info except AttributeError: pass # unknown try: os.unlink(filename_larry) except: pass Capítulo 106: La declaración de pase Sintaxis • pasar Observaciones ¿Porquéquerríadecirleal intérpretequenohaganadaexplícitamente?Pythontieneelrequisito sintáctico de que los bloques de código (después de, if , except , def , class , etc.) no pueden estar vacíos. Pero a veces un bloque de código vacío es útil en sí mismo. Un bloque de class vacío puede definir una nueva clase diferente, como una excepción que se puede capturar. Un bloque de except vacío puede ser la forma más simple de expresar "pedir perdón más tarde" si no hubiera nada por lo que pedir perdón. Si un iterador hace todo el trabajo pesado, un iterador vacío for ejecutar el iterador puede ser útil. Porlo tanto, si no se supone que ocurra nada en un bloque de código, se necesita un pass para que dicho bloque no produzca un IndentationError . Alternativamente, se puede usar cualquier declaración (incluido solo un término para ser evaluado, como el literal de Ellipsis ... o una cadena, más a menudo una cadena de documentación), pero el passdeja claro que en realidad no se supone que suceda nada, y no es necesario para ser realmente evaluado y (al menos temporalmente)almacenado enla memoria.Aquíhayuna pequeña colección anotadadelos usos más frecuentes del passque se cruzó en mi camino, junto con algunos comentarios sobre buenas y malas prácticas. • Ignorar (todo o) un cierto tipo de Exception (ejemplo de xml ): Nota: ignorar todos los tipos de aumentos, como en el siguiente ejemplo de pandas , generalmente se considera una mala práctica, ya que también detecta excepciones que probablemente deberían transmitirse a la persona que llama, por ejemplo, KeyboardInterrupt o SystemExit (o incluso HardwareIsOnFireError - ¿Cómo lo sabe?) no se está ejecutando en un cuadro personalizado con errores específicos definidos, que alguna aplicación dellamada querría conocer?).
    • 591. 526 class CompileError(Exception): pass class _BaseSubmittingController(_BaseController): def submit(self, tasks): pass def retrieve(self, deferred_results): pass for x, error in MDNewton(mp, f, (1,-2), verbose=0, norm=lambda x: norm(x, inf)): pass class ParsingError(Exception): """Error encountered while parsing an ill-formed datafile.""" pass def update_agent(agent): ... def update_agent(agent): En sulugar, usar al menos except Error: o enestecaso, preferiblemente, except OSError: se consideraunapráctica mucho mejor.Un análisisrápidode todos losmódulos depythonque heinstaladomedioelhechodequemásdel10%detodos, except ...: passdeclaraciones de except ...: pass detectan todas las excepciones, por lo que sigue siendo un patrón frecuente en la programación de python. • Derivar una clase de excepción que no agrega un comportamiento nuevo (por ejemplo, en scipy ): De manera similar, las clases destinadas a la clase base abstracta a menudo tienen un init vacío explícito u otros métodos que sesuponeque derivan lassubclases.(por ejemplo, pebl ) • La prueba de que el código se ejecuta correctamente para unos pocos valores de prueba, sin preocuparse por los resultados (de mpmath ): • En las definiciones de clase o función, a menudo una cadena de documentación ya está implementada como la declaración obligatoria que debe ejecutarse como la única cosa en el bloque. En tales casos, el bloque puede contener un pass además de la cadena de documentación para decir "Esto no pretende hacer nada", por ejemplo, en pebl : • Enalgunos casos, el pass se utiliza como marcador de posición para decir "Este método / class / if-block / ... no se ha implementado todavía, pero este será el lugar para hacerlo", aunque personalmente prefiero el literal de Ellipsis ... (NOTA: solo python-3) para diferenciar estrictamente entre esto y el "no-op"intencional en el ejemplo anterior.Por ejemplo, si escribo un modelo a grandes rasgos, podría escribir donde otros podrían tener
    • 592. 527 def time_step(agents): for agent in agents: update_agent(agent) try: metadata = metadata['properties'] except KeyError: pass class CompileError(Exception): pass antes de comounrecordatorio paracompletarlafunciónupdate_agent enunpuntoposterior, pero ejecutealgunaspruebasparaversielrestodel códigosecomportacomoseesperaba. (Una tercera opción para este caso es raise NotImplementedError . Esto es útil en particular para dos casos:“Este método abstractodebe serimplementado por cada subclase,nohay unaformagenéricadedefinirloenestaclasebase”,o“Estafunción,conestenombre,aún noestáimplementado en estaversión, peroeste es el aspectoquetendrásufirma” ) Examples Ignorar una excepción Crear una nueva excepción que puede ser capturada pass
    • 593. 528 print('hello world!') # out: hello world! foo = 1 bar = 'bar' baz = 3.14 print(foo) # out: 1 print(bar) # out: bar print(baz) # out: 3.14 print(foo, bar, baz) # out: 1 bar 3.14 print(str(foo) + " " + bar + " " + str(baz)) # out: 1 bar 3.14 # Wrong: # type:int str float print(foo + bar + baz) # will result in an error print(4 + 5) # out: 9 print("4" + "5") # out: 45 print([4] + [5]) # out: [4, 5] Capítulo 107: La función de impresión Examples Fundamentos de impresión En Python 3 y superior, print es una función en lugar de una palabra clave. También puede pasar una serie de parámetros para print : Otra forma de print múltiples parámetros es usando un + Sin embargo, lo que debe tener cuidado al utilizar + para imprimir varios parámetros es que el tipo de parámetros debe ser el mismo. Tratar de imprimir el ejemplo anterior sin la conversión de la string primero daría como resultado un error, ya que intentaría agregar el número 1 a la cadena "bar" y agregarlo al número 3.14 . Esto se debe a que el contenido de la print se evaluará primero:
    • 594. 529 import random #telling python to include a function to create random numbers randnum = random.randint(0, 12) #make a random number between 0 and 12 and assign it to a variable print("The randomly generated number was - " + str(randnum)) print("this has no newline at the end of it... ", end="") print("see?") # out: this has no newline at the end of it... see? with open('my_file.txt', 'w+') as my_file: print("this goes to the file!", file=my_file) >>>print('apples','bannas','cherries',sep=',') apple, bannas, cherries >>> print('apple','banna', 'cherries', sep=', ') apple, banna, cherries >>> >>> print("<a", end=''); print(" class='jidn'" if 1 else "", end=''); print("/>") <a class='jidn'/> >>> print("paragraph1", end="\n\n");print("paragraph2") paragraph1 paragraph2 De lo contrario, usar a + puede ser muy útil para que un usuario lea la salida de variables. En el siguiente ejemplo, ¡la salida es muy fácil de leer! El siguiente script demuestra esto Puede evitar la print la función de imprimir automáticamente una nueva línea utilizando el end de parámetros: Si desea escribir en un archivo, puede pasarlo como file parámetros: ¡Esto va al archivo! Parámetros de impresión Puedes hacer más que solo imprimir texto. print también tiene varios parámetros para ayudarte. Argumento sep : coloca una cadena entreargumentos. ¿Necesita imprimir una lista de palabras separadas por una coma o alguna otra cadena? end argumento: use algo que no sea una nueva línea al final Sin el argumento end , todas print() funciones print() escriben una línea y luego van al principio de la siguiente línea.Puede cambiarlo para que no haga nada (use una cadena vacía de ''), o doble espacio entre párrafos utilizando dos líneasnuevas.
    • 595. 530 >>> def sendit(out, *values, sep=' ', end='\n'): ... print(*values, sep=sep, end=end,file=out) ... >>> sendit(sys.stdout, 'apples', 'bannas', 'cherries', sep='\t') apples bannas cherries >>> with open("delete-me.txt", "w+") as f: ... sendit(f, 'apples', 'bannas', 'cherries', sep=' ', end='\n') ... >>> with open("delete-me.txt", "rt") as f: ... print(f.read()) ... apples bannas cherries >>> file argumento: enviar salida a otro lugar que no sea sys.stdout. Ahora puede enviar su texto a stdout, a un archivo, oa StringIO y no le importa lo que le den. Si funciona como un archivo, funciona como un archivo. Hay un cuarto parámetro de flush que forzará la descarga de la corriente. >>>
    • 596. 531 import module2.py print('hello') Capítulo 108: La variable especial name Introducción La variable especial name se usa para verificar si un archivo ha sido importado como un módulo o no, y para identificar una función, clase, objeto de módulo por su atributo name . Observaciones La variable especial de Python name se establece en el nombre del módulo que lo contiene. En el nivel superior (como en el intérprete interactivo, o en el archivo principal) se establece en ' main ' .Estosepuedeusarparaejecutarunbloquedeinstruccionessiunmóduloseejecuta directamente en lugar de importarse. El atributo especial relacionado obj. name se encuentra en las clases, los módulos y las funciones importadas (incluidos los métodos) y proporciona el nombre del objeto cuando se define. Examples name == ' main ' La variable especial name no es establecida por el usuario. Se utiliza principalmente para verificar si el módulo se está ejecutando solo o no porque se realizó una import . Para evitar que su módulo ejecute ciertas partes de su código cuando se importa, verifique if name == ' main ' . Deje que module_1.py tenga una sola línea de largo: Y veamos que pasa, dependiendo de module2.py. Situación 1 módulo2.py Ejecutando module1.py imprimiráhello Ejecutando module2.py imprimiráhello Situación 2
    • 597. 532 if name == 'main ': print('hello') import os class C: pass def f(x): x += 2 return x print(f) #<functionfat0x029976B0> print(f. name ) # f print(C) #<class' main .C'> print(C. name ) # C print(os) # <module 'os' from '/spam/eggs/'> print(os. name ) # os def f(): pass print(f. name ) # f - as expected g = f print(g. name ) # f - even though the variable is named g, the function is still named f def enter_exit_info(func): módulo2.py Ejecutando module1.py no imprimirá nada Ejecutando module2.py imprimiráhello function_class_or_module . name El atributo especial name de una función, clase o módulo es una cadena que contiene su nombre. Sin embargo, el atributo name no es el nombre de la variable que hace referencia a la clase, el método o la función, sino que es el nombre que se le asigna cuando se define. Esto se puede utilizar, entre otros, para la depuración:
    • 598. 533 logger = logging.getLogger( name ) Utilizar en el registro Al configurar la funcionalidad de logging incorporada, un patrón común es crear un registrador con el name del módulo actual: Esto significa que el nombre completo del módulo aparecerá en los registros, lo que facilitará ver de dónde provienen los mensajes. def wrapper(*arg, **kw): print '-- entering', func. name res = func(*arg, **kw) print '-- exiting', func. name return res return wrapper @enter_exit_info def f(x): print 'In:', x res = x +2 print 'Out:', res return res a = f(2) # Outputs: # -- entering f # In: 2 # Out: 4 # -- exiting f
    • 599. 534 class BaseClass(object): pass class DerivedClass(BaseClass): pass class Rectangle(): def init (self, w, h): self.w = w self.h = h def area(self): return self.w * self.h def perimeter(self): return 2 * (self.w + self.h) Capítulo 109: Las clases Introducción Python se ofrece a sí mismo no solo como un popular lenguaje de scripting, sino que también es compatible con el paradigma de programación orientado a objetos. Las clases describen datos y proporcionan métodos para manipular esos datos, todos incluidos en un solo objeto. Además, las clases permiten la abstracción al separar los detalles de implementación concretos de las representaciones abstractas de datos. El código que utiliza clases es generalmente más fácil de leer, entender y mantener. Examples Herencia basica La herencia en Python se basa en ideas similares utilizadas en otros lenguajes orientados a objetos como Java, C ++, etc. Una nueva clase puede derivarse de una clase existente de la siguiente manera. BaseClass es la clase ya existente ( principal ), y DerivedClass es la nueva clase ( secundaria ) que hereda (o subclases ) atributos de BaseClass . Nota : a partir de Python 2.2, todas las clases heredan implícitamente de la clase de object , que es la clase base para todos los tipos incorporados. Definimos una clase de Rectangle principal en el siguiente ejemplo, que se hereda implícitamente del object : La clase Rectangle se puede usar como una clase base para definir una clase Square , ya que un cuadrado es un caso especial de rectángulo.
    • 600. 535 r.area() # Output: 12 r.perimeter() # Output: 14 s.area() # Output: 4 s.perimeter() # Output: 8 # subclass check issubclass(Square, Rectangle) # Output: True # instantiate r = Rectangle(3, 4) s = Square(2) isinstance(r, Rectangle) # Output: True isinstance(r, Square) # Output: False # A rectangle is not a square isinstance(s, Rectangle) # Output: True # A square is a rectangle isinstance(s, Square) # Output: True Laclase Square heredaráautomáticamente todos losatributos delaclaseRectangle , así comola clase de objeto. super() se utiliza para llamar al init () de la clase Rectangle , esencialmente llamandoacualquier métodoanuladodelaclasebase.Nota:enPython3,super()norequiere argumentos. Los objetos de clase derivados pueden acceder y modificar los atributos de sus clases base: Funciones incorporadas que funcionan con herencia. issubclass(DerivedClass, BaseClass) : devuelve True si DerivedClass es una subclase de BaseClass isinstance(s, Class) :devuelve True sisesunainstanciadeClass ocualquieradelasclases derivadas de Class class Square(Rectangle): def init (self, s): # call parent constructor, w and h are both s super(Square, self). init (s, s) self.s = s
    • 601. 536 class C: x = 2 # class variable def init (self, y): self.y = y # instance variable C.x # 2 C.y # AttributeError: type object 'C' has no attribute 'y' c1 = C(3) c1.x # 2 c1.y # 3 c2 = C(4) c2.x # 2 c2.y # 4 c2.x = 4 c2.x # 4 C.x # 2 class D: x = [] def init (self, item): self.x.append(item) # note that this is not an assigment! d1 = D(1) d2 = D(2) d1.x # [1, 2] d2.x # [1, 2] D.x # [1, 2] Variables de clase e instancia Las variables de instancia son únicas para cada instancia, mientras que las variables de clase son compartidas por todas las instancias. Se puede acceder a las variables de clase en las instancias de esta clase, pero la asignación al atributo de clase creará una variable de instancia que sombrea la variable de clase Tenga en cuenta que la mutación de variables de clase de instancias puede llevar a algunas consecuencias inesperadas.
    • 602. 537 class A(object): def f(self, x): return 2 * x A.f # <function A.f at ...> (in Python 3.x) A.f # <unbound method A.f> (in Python 2.x) A.f. class # <type 'instancemethod'> A.f. func # <function f at ...> import inspect inspect.isfunction(A.f) # True inspect.ismethod(A.f) # False import inspect inspect.isfunction(A.f) # False inspect.ismethod(A.f) # True Métodos enlazados, no enlazados y estáticos. La idea de métodos enlazados y no enlazados se eliminó en Python 3 . En Python 3 cuando declara un método dentro de una clase, está usando una palabra clave def , creando así un objeto de función. Esta es una función regular, y la clase circundante funciona como su espacio de nombres. En el siguiente ejemplo, declaramos el método f dentro de la clase A , y se convierte en una función Af : Python 3.x 3.0 EnPython2,elcomportamientofuediferente:losobjetosdefuncióndentrodelaclasefueron reemplazadosimplícitamenteporobjetosdetipoinstancemethod ,quesedenominaronmétodosno vinculados porque no estaban vinculados a ningunainstancia de clase en particular.Fue posible acceder a la función subyacente utilizando la propiedad . func . Python 2.x 2.3 Los últimos comportamientos se confirman mediante inspección: los métodos se reconocen como funciones en Python 3, mientras que la distinción se mantiene en Python 2. Python 3.x 3.0 Python 2.x 2.3 En ambas versiones de Python function / method Af se puede llamar directamente, siempre que
    • 603. 538 A.f(1, 7) # Python 2: TypeError: unbound method f() must be called with # A instance as first argument (got int instance instead) # Python 3: 14 a = A() A.f(a, 20) # Python 2 & 3: 40 a = A() a.f # <bound method A.f of < main .A object at ...>> a.f(2) # 4 # Note: the bound method object a.f is recreated *every time* you call it: a.f is a.f # False # As a performance optimization you can store the bound method in the object's # dict , in which case the method object will remain fixed: a.f = a.f a.f is a.f # True class D(object): multiplier = 2 @classmethod def f(cls, x): return cls.multiplier * x @staticmethod def g(name): print("Hello, %s" % name) pase una instancia de clase A como primer argumento. Supongamos ahora que a es una instancia de la clase A , lo que es af entonces? Bueno, intuitivamente este debe ser el mismo métodof de clase A , sólo que debe de alguna manera "saber" que se aplica al objeto a - método en Python esto se llama unida a a . Losdetalles esenciales sonlos siguientes: writing af invoca el método magic getattribute de a , que primero verifica si a tiene un atributo llamado f (no lo hace), luego verifica la clase A si contiene un método con ese nombre (lo hace), y crea un nuevo objeto m del method de tipo que tiene la referencia al Af original en m. func , y una referencia al objeto a en m. self .Cuando este objeto se llama como una función, simplemente hace lo siguiente: m(...) => m. func (m. self , ...) . Por lo tanto, este objeto se denomina método enlazado porque, cuando se invoca, sabe que debe proporcionar el objeto al que estaba vinculado como primer argumento. (Estas cosas funcionan de la misma manera en Python 2 y 3). Finalmente, Python tiene métodos de clase y métodos estáticos , tipos especiales de métodos. Los métodos de clase funcionan de la misma manera que los métodos regulares, excepto que cuando se invocan en un objeto, se unen a la clase del objeto en lugar de al objeto. Así m. self = type(a) . Cuando llama a dicho método enlazado, pasa la clase de a como primer argumento. Los métodos estáticos son incluso más simples: no vinculan nada en absoluto, y simplemente devuelven la función subyacente sin ninguna transformación.
    • 604. 539 d = D() d.multiplier = 1337 (D.multiplier, d.multiplier) # (2, 1337) d.f # <bound method D.f of <class ' main .D'>> d.f(10) # 20 # new-style class class New(object): pass # new-style instance new = New() new. class #<class'main.New'> type(new) # <class 'main .New'> issubclass(New, object) # True Tenga en cuenta que los métodos de clase están vinculados a la clase incluso cuando se accede a ellos en la instancia: Valelapenaseñalar que enel nivel másbajo, lasfunciones,los métodos,los métodosestáticos, etc., son en realidad descriptores que invocan los métodos especiales get , set y opcionalmente del . Para más detalles sobre métodos de clase y métodos estáticos: • ¿Cuál es la diferencia entre @staticmethod y @classmethod en Python? • ¿Significado de @classmethod y @staticmethod para principiante? Clases de estilo nuevo vs. estilo antiguo Python 2.x 2.2.0 Las clases de nuevo estilo se introdujeron en Python 2.2 para unificar clases y tipos . Heredan del tipo de object nivel superior. Una clase de nuevo estilo es un tipo definido por el usuario y es muy similar a los tipos incorporados. Las clases de estilo antiguo no heredan de object . Las instancias de estilo antiguo siempre se implementan con un tipo de instance incorporado. D.f #<boundmethodtype.fof<class'main.D'>> D.f(12) # 24 D.g # <function D.g at ...> D.g("world") # Hello, world
    • 605. 540 class MyClass: pass my_inst = MyClass() type(my_inst) # <class ' main .MyClass'> my_inst. class #<class' main .MyClass'> issubclass(MyClass, object) # True class Rectangle(object): def init (self, width, height, color='blue'): self.width = width self.height = height self.color = color def area(self): return self.width * self.height # Create some instances of the class default_rectangle = Rectangle(2, 3) print(default_rectangle.color) # blue red_rectangle = Rectangle(2, 3, 'red') print(red_rectangle.color) # red Python 3.x 3.0.0 En Python 3, se eliminaron las clases de estilo antiguo. Las clases de nuevo estilo en Python 3 heredan implícitamente del object , por lo que ya no es necesario especificar MyClass(object) . Valores por defecto para variables de instancia Si la variable contiene un valor de un tipo inmutable (por ejemplo, una cadena), está bien asignar un valor predeterminado como este Hay que tener cuidado al inicializar objetos mutables como listas en el constructor. Considere el siguiente ejemplo: # old-style class class Old: pass # old-style instance old = Old() old. class # <class main .Old at ...> type(old) # <type 'instance'> issubclass(Old, object) # False
    • 606. 541 class Rectangle2D(object): def init (self, width, height, pos=None, color='blue'): self.width = width self.height = height self.pos = pos or [0, 0] # default value is [0, 0] self.color = color r1 = Rectangle2D(5,3) r2 = Rectangle2D(7,8) r1.pos[0] = 4 r1.pos # [4, 0] r2.pos # [0, 0] r2's pos hasn't changed class Foo(object): foo = 'attr foo of Foo' class Bar(object): foo = 'attr foo of Bar' # we won't see this. bar = 'attr bar of Bar' class FooBar(Foo, Bar): foobar = 'attr foobar of FooBar' Este comportamiento se debe al hecho de que en Python los parámetros predeterminados están vinculados en la ejecución de la función y no en la declaración de la función. Para obtener una variable de instancia predeterminada que no se comparte entre las instancias, se debe usar una construcción como esta: Consulte también Argumentos predeterminados mutables y “Menos asombro” y el Argumento predeterminado mutable . Herencia múltiple Python utiliza el algoritmo de linealización C3 para determinar el orden en el que resolver los atributos de clase, incluidos los métodos. Esto se conoce como Orden de resolución de métodos (MRO). Aquí hay un ejemplo simple: Ahora si creamos una instancia de FooBar, si buscamos el atributo foo, veremos que el atributo class Rectangle2D(object): def init (self, width, height, pos=[0,0], color='blue'): self.width = width self.height = height self.pos = pos self.color = color r1 = Rectangle2D(5,3) r2 = Rectangle2D(7,8) r1.pos[0] = 4 r1.pos # [4, 0] r2.pos # [4, 0] r2's pos has changed as well
    • 607. 542 fb = FooBar() >>> fb.foo 'attr foo of Foo' >>> FooBar.mro() [<class ' main .FooBar'>, <class ' main .Foo'>, <class ' main .Bar'>, <type 'object'>] class Foo(object): def foo_method(self): print "foo Method" class Bar(object): def bar_method(self): print "bar Method" class FooBar(Foo, Bar): def foo_method(self): super(FooBar, self).foo_method() class Foo(object): def init (self): print "foo init" class Bar(object): def init (self): de Foo se encuentra primero y Aquí está el MRO de FooBar: Se puede decir simplemente que el algoritmo MRO de Python es 1. Profundidad primero (por ejemplo, FooBar luego Foo ) a menos que 2. un padre compartido ( object ) está bloqueado por un hijo ( Bar )y 3. No se permiten relaciones circulares. Es decir, por ejemplo, Bar no puede heredar de FooBar, mientras que FooBar hereda de Bar. Para un ejemplo completo en Python, vea la entrada de wikipedia . Otra característica poderosa en la herencia es super . super puede obtener características de clases para padres. Herencia múltiple con el método init de clase, cuando cada clase tiene su propio método init, entonces intentamos obtener una inercia múltiple, luego solo se llama al método init de la clase que se hereda primero. para el siguiente ejemplo, solo se llama al método de inicio de clase Foo que no se llama a la clase de barra de inicio
    • 608. 543 foobar init foo init print isinstance(a,FooBar) print isinstance(a,Foo) print isinstance(a,Bar) True True True Salida: Pero eso no significa que la clase Bar no sea hereditaria. La instancia de la clase FooBar final también es una instancia de la clase Bar y la clase Foo . Salida: Descriptores y búsquedas punteadas Losdescriptores sonobjetosqueson(generalmente)atributosdeclasesyquetienencualquiera de los métodos especiales get , set o delete . Losdescriptoresdedatostienencualquierade set , o delete Estos pueden controlarla búsqueda de puntos en una instancia y se utilizanpara implementar funciones, staticmethod , classmethod y property . Una búsqueda de puntos (por ejemplo, la instancia foo de la clase Foo busca la bar atributos, es decir, foo.bar ) utiliza el siguiente algoritmo: 1. bar se mira en la clase, Foo . Si está allí y es un descriptor de datos , entonces se usa el descriptor de datos. Así es como la property puede controlar el acceso a los datos en una instancia, y las instancias no pueden anular esto. Si un descriptor de datos no está allí, entonces 2. bar se mira en la instancia dict . Es por esto que podemos anular o bloquear los métodos que seinvocan desdeunainstancia conuna búsqueda de puntos.Si existe una bar en la instancia, se utiliza. Si no, entonces nosotros 3. Busca en la clase Foo para bar . Si es un Descriptor , entonces se usa el protocolo del descriptor.Así es como se implementan las funciones (en este contexto, los métodos classmethod ), el classmethod y el staticmethod . De lo contrario, simplemente devuelve el print "bar init" class FooBar(Foo, Bar): def init (self): print "foobar init" super(FooBar, self). init () a = FooBar()
    • 609. 544 class Person(object): def init (self, first_name, last_name, age): self.first_name = first_name self.last_name = last_name self.age = age self.full_name = first_name + " " + last_name def greet(self): print("Hello, my name is " + self.full_name + ".") class Person(object): def init (self, first_name, age, last_name=None): if last_name is None: self.first_name, self.last_name = first_name.split(" ", 2) else: self.first_name = first_name self.last_name = last_name self.full_name = self.first_name + " " + self.last_name self.age = age def greet(self): print("Hello, my name is " + self.full_name + ".") objeto allí, o hay un AttributeError Métodos de clase: inicializadores alternos Los métodos de clase presentan formas alternativas para construir instancias de clases. Para ilustrar, veamos un ejemplo. Supongamos que tenemos una clase de Person relativamente simple: Podría ser útil tener una forma de crear instancias de esta clase especificando un nombre completo en lugar del nombre y apellido por separado. Una forma de hacer esto sería tener el last_name como un parámetro opcional, y suponiendo que si no se da, pasamos el nombre completo en: Sin embargo, hay dos problemas principales con este bit de código: 1. Los parámetros first_name y last_name ahora son last_name , ya que puede ingresar un nombre completo para first_name . Además, si hay más casos y / o más parámetros que tieneneste tipo de flexibilidad,la ramificación if/elif /else puede ser molesta rápidamente. 2. No es tan importante, pero aún así vale la pena señalar: ¿y si last_name es None , pero first_name no se divide en dos o más cosas a través de los espacios? Tenemos otra capa de validación de entrada y / o manejo de excepciones ... Introduzca los métodos de clase.En lugar de tener un solo inicializador, crearemos un inicializador separado, llamado from_full_name , y lo classmethod decorador de classmethod (incorporado).
    • 610. 545 In [2]: bob = Person("Bob", "Bobberson", 42) In [3]: alice = Person.from_full_name("Alice Henderson", 31) In [4]: bob.greet() Hello, my name is Bob Bobberson. In [5]: alice.greet() Hello, my name is Alice Henderson. class Country(object): Note clslugar de self como el primer argumento de from_full_name . Los métodos de clase se aplican a la clase general, no a una instancia de una clase dada (que es lo que el self generalmentedenota).Porlotanto,si clsesnuestra Persondeclase,entonceselvalordevuelto por la from_full_name método de clase es Person(first_name, last_name, age) , que utiliza la Person 's init paracrearunainstanciadelaPersondeclase.Enparticular,situviéramosquehacer una subclase Employee of Person , from_full_name también funcionaría en la clase Employee . Para mostrar que esto funciona como se esperaba, init instancias de Person de más deuna manera sin la bifurcación en init : Otras referencias: • Python @classmethod y @staticmethod para principiantes? • https://docs.python.org/2/library/functions.html#classmethod • https://docs.python.org/3.5/library/functions.html#classmethod Composición de la clase La composición de clase permite relaciones explícitas entre objetos. En este ejemplo, las personas viven en ciudades que pertenecen a países. La composición permite a las personas acceder al número de todas las personas que viven en su país: class Person(object): def init (self, first_name, last_name, age): self.first_name = first_name self.last_name = last_name self.age = age self.full_name = first_name + " " + last_name @classmethod def from_full_name(cls, name, age): if " " not in name: raise ValueError first_name, last_name = name.split(" ", 2) return cls(first_name, last_name, age) def greet(self): print("Hello, my name is " + self.full_name + ".")
    • 611. 546 class A(object): def init (self, num): self.num = num def add (self, other): return A(self.num + other.num) def init (self): self.cities=[] def addCity(self,city): self.cities.append(city) class City(object): def init (self, numPeople): self.people = [] self.numPeople = numPeople def addPerson(self, person): self.people.append(person) def join_country(self,country): self.country = country country.addCity(self) for i in range(self.numPeople): person(i).join_city(self) class Person(object): def init (self, ID): self.ID=ID def join_city(self, city): self.city = city city.addPerson(self) def people_in_my_country(self): x= sum([len(c.people) for c in self.city.country.cities]) return x US=Country() NYC=City(10).join_country(US) SF=City(5).join_country(US) print(US.cities[0].people[0].people_in_my_country()) # 15 Parche de mono En este caso, "parche de mono" significa agregar una nueva variable o método a una clase después de que se haya definido. Por ejemplo, digamos que definimos la clase A como Pero ahora queremos agregar otra función más adelante en el código. Supongamos que esta función es la siguiente.
    • 612. 547 A.get_num = get_num foo = A(42) A.get_num = get_num bar = A(6); foo.get_num() # 42 bar.get_num() # 6 dir(Class) >>> dir(list) [' add ', ' class ', ' contains ', ' delattr ', ' delitem ', ' dir ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' getitem ', ' gt ', ' hash ', ' iadd ', ' imul ', ' init ', ' iter ', ' le ', ' len ', ' lt ', ' mul ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' reversed ', ' rmul ', ' setattr ', ' setitem ', ' sizeof ', ' str ', ' subclasshook ', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>> [m for m in dir(list) if not m.startswith(' ')] ['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', Pero, ¿cómo añadimos esto como un método en A ? Eso es simple, simplemente colocamos esa función en A con una declaración de asignación. ¿Por qué funciona esto? Porque las funciones son objetos como cualquier otro objeto, y los métodos son funciones que pertenecen a la clase. La función get_num estará disponible para todos los existentes (ya creados) así como para las nuevas instancias de A Estas adiciones están disponibles en todas las instancias de esa clase (o sus subclases) automáticamente. Por ejemplo: Tenga en cuenta que, a diferencia de otros idiomas, esta técnica no funciona para ciertos tipos integrados y no se considera un buen estilo. Listado de todos los miembros de la clase La función dir() se puede usar para obtener una lista de los miembros de una clase: Por ejemplo: Es común buscar solo miembros "no mágicos". Esto se puede hacer usando una comprensión simple que enumera los miembros con nombres que no comienzan con : def get_num(self): return self.num
    • 613. 548 def rename(self, renamed): # regular method """Reassign and print the name attribute.""" self.name = renamed print("Now my name is {}".format(self.name)) # special method # instance attribute def str (self): """ThismethodisrunwhenPythontries to cast the object to a string. Return this string when using print(), etc. """ return self.name def init (self, name): # special method """This is the initializer. It's a special method (see below). """ self.name = name # docstring # class attribute class Person(object): """Asimple class.""" species = "Homo Sapiens" Advertencias: Las clases pueden definir un dir () . Si ese método existe, se llama a dir() a dir () , de lo contrario,Python intentará crear una lista de miembros de laclase.Esto significa quela función dirpuede tenerresultadosinesperados.Dos citasdeimportanciadeladocumentación oficialde python : Si el objeto no proporciona dir (), la función intenta recopilar información del atributo dict del objeto, si está definido, y de su tipo de objeto. La lista resultante no está necesariamente completa, y puede ser inexacta cuando el objeto tiene un getattr () personalizado. Nota: dado que dir () se proporciona principalmente como una conveniencia para su uso en una solicitud interactiva, intenta proporcionar un conjunto interesante de nombres más de lo que trata de proporcionar un conjunto de nombres definido de manera rigurosa o consistente, y su comportamiento detallado puede cambiar lanzamientos Por ejemplo, los atributos de metaclase no están en la lista de resultados cuando el argumento es una clase. Introducción a las clases Una clase, funciona como una plantilla que define las características básicas de un objeto en particular. Aquí hay un ejemplo: Hay algunas cosas que se deben tener en cuenta al observar el ejemplo anterior. 1. La clase se compone de atributos (datos) y métodos (funciones). 2. Los atributos y métodos se definen simplemente como variables y funciones normales. 'sort']
    • 614. 549 >>> # Instances >>> kelly = Person("Kelly") >>> joseph = Person("Joseph") >>> john_doe = Person("John Doe") >>> # Attributes >>> kelly.species 'Homo Sapiens' >>> john_doe.species 'Homo Sapiens' >>> joseph.species 'Homo Sapiens' >>> kelly.name 'Kelly' >>> joseph.name 'Joseph' 3. Como se indica en la cadena de documentación correspondiente, el init () se llama inicializador.Esequivalente al constructor enotros lenguajes orientados a objetos, y es el método que se ejecuta por primera vez cuandocrea un nuevoobjetoo una nuevainstancia de la clase. 4. Los atributos que se aplican a toda la clase se definen primero y se denominan atributos de clase . 5. Los atributos que se aplican a una instancia específica de una clase (un objeto) se denominan atributos de instancia .Generalmente se definen dentro de init (); esto no esnecesario, pero serecomienda(yaquelosatributos definidos fuerade init () corren el riesgo de ser accedidos antes de que se definan). 6. Cada método, incluido en la definición de clase, pasa el objeto en cuestión como su primer parámetro. La palabra self se usa para este parámetro (el uso de self es en realidad por convención, ya que la palabra self no tiene un significado inherente en Python, pero esta es una de las convenciones más respetadas de Python, y siempre se debe seguir). 7. Aquellos que están acostumbrados a la programación orientada a objetos en otros lenguajespuedensorprenderseporalgunas cosas.UnaesquePythonnotieneun concepto real de elementos private , por lo que todo, de manera predeterminada, imita el comportamiento de la palabra clave public C ++ / Java. Para obtener más información, consulte el ejemplo "Miembros de la clase privada" en esta página. 8. Algunos de los métodos de la clase tienen la siguiente forma: functionname (self, other_stuff) . Todos estos métodos se denominan "métodos mágicos" y son una parte importantedelas clases enPython.Porejemplo,la sobrecarga deoperadoresenPython se implementa con métodos mágicos. Para más información, consulte la documentación relevante . AhoravamosahaceralgunosejemplosdenuestraclasedePerson! Actualmente tenemos tres objetos Person , kelly , joseph y john_doe . Podemos acceder a los atributos de la clase desde cada instancia utilizando el operador de punto . Note nuevamente la diferencia entre los atributos de clase e instancia: Podemos ejecutar los métodos de la clase usando el mismo operador de punto . :
    • 615. 550 class MyClass(object): def init (self): self._my_string = "" @property def string(self): """A profoundly important string.""" return self._my_string @string.setter def string(self, new_value): assert isinstance(new_value, str), \ "Give me a string, not a %r!" % type(new_value) self._my_string = new_value @string.deleter def x(self): self._my_string = None mc = MyClass() mc.string = "String!" print(mc.string) del mc.string class Character(object): definit (name, max_hp): self._name = name self._hp = max_hp self._max_hp = max_hp Propiedades Las clases de Python admiten propiedades , que parecen variables de objetos normales, pero con la posibilidad de adjuntar comportamiento y documentación personalizados. De la clase de objeto MyClass parecerá tener tiene una propiedad .string , sin embargo su comportamiento está ahora estrictamente controlado: Además de la sintaxis útil que se mencionó anteriormente, la sintaxis de la propiedad permite la validación u otros aumentos a esos atributos. Esto podría ser especialmente útil con las API públicas, donde se debe brindar un nivel de ayuda al usuario. Otro uso común de las propiedades es permitir que la clase presente "atributos virtuales", atributos que no se almacenan en realidad, sino que se calculan solo cuando se solicitan. >>> # Methods >>> john_doe. str () 'John Doe' >>> print(john_doe) 'John Doe' >>> john_doe.rename("John") 'Now my name is John'
    • 616. 551 # Make hp read only by not providing a set method @property def hp(self): return self._hp # Make name read only by not providing a set method @property def name(self): return self.name def take_damage(self, damage): self.hp -= damage self.hp = 0 if self.hp <0 else self.hp @property def is_alive(self): return self.hp != 0 @property def is_wounded(self): return self.hp < self.max_hp if self.hp > 0 else False @property def is_dead(self): return not self.is_alive bilbo = Character('Bilbo Baggins', 100) bilbo.hp # out : 100 bilbo.hp = 200 # out : AttributeError: can't set attribute # hp attribute is read only. bilbo.is_alive # out : True bilbo.is_wounded # out : False bilbo.is_dead # out : False bilbo.take_damage( 50 ) bilbo.hp # out : 50 bilbo.is_alive # out : True bilbo.is_wounded # out : True bilbo.is_dead # out : False bilbo.take_damage( 50) bilbo.hp # out :0 bilbo.is_alive # out : False bilbo.is_wounded # out : False bilbo.is_dead
    • 617. 552 class Singleton: def new (cls): try: it =cls. it exceptAttributeError: it = cls. it = object. new (cls) return it def repr (self): return '<{}>'.format(self. class . name .upper()) def eq (self, other): return other is self class Singleton: """ A non-thread-safe helper class to ease implementing singletons. This should be used as a decorator -- not a metaclass -- to the class that should be a singleton. The decorated class can define one ` init ` function that takes only the `self` argument. Other than that, there are no restrictions that apply to the decorated class. To get the singleton instance, use the `Instance` method. Trying to use ` call ` will result in a `TypeError` being raised. Limitations: The decorated class cannot be inherited from. """ def init (self, decorated): self._decorated = decorated def Instance(self): """ Returns the singleton instance. Upon its first call, it creates a new instance of the decorated class and calls its ` init ` method. On all subsequent calls, the already created instance is returned. """ try: return self._instance except AttributeError: self._instance = self._decorated() return self._instance Clase de singleton Un singleton es un patrón que restringe la creación de instancias de una clase a una instancia / objeto. Para más información sobre los patrones de diseño singleton de python, consulte aquí . Otro método es decorar tu clase. Siguiendo el ejemplo de esta respuesta, crea una clase Singleton: # out : True
    • 618. 553 @Singleton class Single: def init (self): self.name=None self.val=0 def getName(self): print(self.name) x=Single.Instance() y=Single.Instance() x.name='I\'m single' x.getName()#outputsI'msingle y.getName()#outputsI'msingle Para usar puedes usar el método de Instance def call (self): raise TypeError('Singletons must be accessed through `Instance()`.') def instancecheck (self, inst): return isinstance(inst, self._decorated)
    • 619. 554 import csv with open('/tmp/output.tsv', 'wt') as out_file: tsv_writer = csv.writer(out_file, delimiter='\t') tsv_writer.writerow(['name', 'field']) tsv_writer.writerow(['Dijkstra', 'Computer Science']) tsv_writer.writerow(['Shelah', 'Math']) tsv_writer.writerow(['Aumann', 'Economic Sciences']) $ cat /tmp/output.tsv name field Dijkstra Computer Science Shelah Math Aumann Economic Sciences import pandas as pd d = {'a': (1, 101), 'b': (2, 202), 'c': (3, 303)} pd.DataFrame.from_dict(d, orient="index") df.to_csv("data.csv") df = pd.read_csv("data.csv") d = df.to_dict() Capítulo 110: Lectura y Escritura CSV Examples Escribiendo un archivo TSV Pitón Archivo de salida Usando pandas Escriba un archivo CSV desde un dict o un DataFrame . Lea un archivo CSV como un DataFrame y DataFrame a un dict :
    • 620. 555 lst = [1, 2, 3, 4] lst[0] # 1 lst[1] # 2 lst[4] # IndexError: list index out of range lst[-1] # 4 Capítulo 111: Lista Introducción La Lista de Python es una estructura de datos general ampliamente utilizada en los programas de Python. Se encuentran en otros idiomas, a menudo denominados arreglos dinámicos . Ambos son mutables y un tipo de datos de secuencia que les permite ser indexados y segmentados . La lista puede contener diferentes tipos de objetos, incluidos otros objetos de lista. Sintaxis • [valor, valor, ...] • lista ([iterable]) Observaciones listes un tipoparticulardeiterable, peronoesel únicoqueexisteenPython.Avecesserámejor usar set , tuple o dictionary list es el nombre dado en Python a arreglos dinámicos (similar al vector<void*> de C ++ o ArrayList<Object> de Java ArrayList<Object> ). No es una lista enlazada. El acceso a los elementos se realiza en tiempo constante y es muy rápido. Anexar elementos al final de la lista es tiempo constante amortizado, pero de vez en cuando puede implicar la asignación y copia de toda la list . Las comprensiones de listas están relacionadas con listas. Examples Acceso a los valores de la lista Las listas de Python están indexadas a cero, y actúan como matrices en otros idiomas. Intentar acceder a un índice fuera de los límites de la lista generará un IndexError . Los índices negativos se interpretan como contadores desde el final de la lista.
    • 621. 556 lst[5:8] lst[1:10] # [] since starting index is greater than length of lst, returns empty list # [2, 3, 4] same as omitting ending index lst[len(lst)-1] # 4 lst[::-1] # [4, 3, 2, 1] lst[3:1:-1] # [4, 3] reversed(lst)[0:2] # 0 = 1 -1 # 2 = 3 -1 data = 'chandan purohit 22 2000' #assuming data fields of fixed length name_slice = slice(0,19) age_slice = slice(19,21) salary_slice = slice(22,None) #now we can have more readable slices print(data[name_slice]) #chandan purohit print(data[age_slice]) #'22' print(data[salary_slice]) #'2000' Esto es funcionalmente equivalente a Las listas permiten usar notación de lst[start:end:step] como lst[start:end:step] . La salida de lanotación dedivisión esunanueva listaquecontiene elementosdesde elstarthasta el end-1del índice.Siseomitenlasopciones,startdefectoalprincipiodelalista,deendaextremodelalista y step al 1: lst[1:] # [2, 3, 4] lst[:3] # [1, 2, 3] lst[::2] # [1, 3] lst[::-1] # [4, 3, 2, 1] lst[-1:0:-1] # [4, 3, 2] Con esto en mente, puede imprimir una versión invertida de la lista llamando Cuando se usan longitudes de pasos de cantidades negativas, el índice inicial debe ser mayor que el índice final, de lo contrario, el resultado será una lista vacía. El uso de índices de pasos negativos es equivalente al siguiente código: Los índices utilizados son 1 menos que los utilizados en la indexación negativa y se invierten. Rebanado avanzado Cuando las listas se getitem () se llama al método getitem () del objeto de lista, con un objetodeslice .Pythontieneunmétododedivisiónintegradoparagenerarobjetosdedivisión. Podemos usar esto para almacenar una porción y reutilizarla más tarde como así, lst[-2] # 3 lst[-5] # IndexError: list index out of range
    • 622. 557 a = [1, 2, 3, 4, 5] # Append values 6, 7, and 7 to the list a.append(6) a.append(7) a.append(7) # a: [1, 2, 3, 4, 5, 6, 7, 7] # Append another list b = [8, 9] a.append(b) # a: [1, 2, 3, 4, 5, 6, 7, 7, [8, 9]] # Append an element of a different type, as list elements do not need to have the same type my_string = "hello world" a.append(my_string) # a: [1, 2, 3, 4, 5, 6, 7, 7, [8, 9], "hello world"] # Appending a list to another list a = [1, 2, 3, 4, 5, 6, 7, 7] b = [8, 9] a.append(b) # a: [1, 2, 3, 4, 5, 6, 7, 7, [8, 9]] a[8] # Returns: [8,9] a = [1, 2, 3, 4, 5, 6, 7, 7] b = [8, 9, 10] # Extend list by appending all elementsfrom b a.extend(b) # a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10] # Extend list with elements from a non-list enumerable: a.extend(range(3)) # a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 0, 1, 2] Esto puede ser de gran utilidad al proporcionar funcionalidad de corte a nuestros objetos al reemplazar getitem en nuestra clase. Lista de métodos y operadores soportados. Comenzando con una lista dada a : 1. append(value) : agrega un nuevo elemento al final de lalista. Tenga en cuenta que el método append() solo agrega un elemento nuevo al final de la lista. Si agrega una lista a otra, la lista que agregue se convertirá en un elemento único al final de la primera lista. 2. extend(enumerable) : extiende la lista agregando elementos de otro enumerable. Las listas también se pueden concatenar con el operador + . Tenga en cuenta que esto no
    • 623. 558 a.pop(2) # Returns: 5 # a: [0, 1, 2, 3, 4, a.pop(8) # Returns: 7 # a: [0, 1, 2, 3, 4, # With no argument: a.pop() # Returns: 10 # a: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] a = [1, 2, 3, 4, 5, 6] + [7, 7] + b # a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10] a.index(7) # Returns:6 a.index(49) # ValueError, because 49 is not in a. a.index(7, 7) # Returns: 7 a.index(7, 8) # ValueError, because there is no 7 starting at index 8 a.insert(0, 0) # insert 0 at position 0 a.insert(2, 5) # insert 5 at position 2 # a: [0, 1, 5, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10] a.remove(0) a.remove(9) # a: [1, 2, 3, 4, 5, 6, 7, 8] a.remove(10) # ValueError, because 10 is not in a modifica ninguna de las listas originales: 3. index(value, [startIndex]) índice de inicio index(value, [startIndex]) : obtiene el índice de la primera aparición del valor de entrada. Si el valor de entrada no está en la lista, se ValueError una excepción ValueError . Si se proporciona un segundo argumento, la búsqueda se inicia en ese índiceespecificado. 4. insert(index, value) : inserta un value justo antes del index especificado. Así después de la inserción el nuevo elemento ocupa el index posición. 5. pop([index]) : elimina y devuelve el elemento en el index . Sin ningún argumento, elimina y devuelve el último elemento de la lista. 5, 6, 7, 7, 8, 9, 10] 5, 6, 7, 8, 9, 10] 6. remove(value) : elimina la primera aparición del valor especificado. Si no se puede encontrar el valor proporcionado, se ValueError un ValueError . 7. reverse() : invierte la lista en el lugar y devuelve None .
    • 624. 559 import datetime class Person(object): def init (self, name, birthday, height): self.name = name self.birthday = birthday self.height = height def repr (self): return self.name l.sort(key=lambda item: item.name) # l: [Chuck Norris,John Cena,Jon Skeet] l.sort(key=lambda item: item.birthday) # l: [Chuck Norris,Jon Skeet,JohnCena] l.sort(key=lambda item: item.height) # l: [John Cena, Chuck Norris, JonSkeet] a.count(7) # Returns:2 a.sort() # a = [1, 2, 3, 4, 5, 6, 7, 8] # Sorts the list in numerical order a.sort(reverse=True) # a = [8, 7, 6, 5, 4, 3, 2, 1] import datetime l = [{'name':'John Cena', 'birthday': datetime.date(1992, 9, 12),'height': 175}, También hay otras formas de revertir una lista . 8. count(value) : cuenta el número de apariciones de algún valor en lalista. 9. sort() : ordena la lista en orden numérico y lexicográfico y devuelve None . Laslistas también sepuedenrevertir cuandoseordenanusando la reverse=True en el método sort() . Si desea ordenar por atributos de elementos, puede usar el argumento de palabra key clave: l = [Person("John Cena", datetime.date(1992, 9, 12), 175), Person("Chuck Norris", datetime.date(1990, 8, 28), 180), Person("Jon Skeet", datetime.date(1991, 7, 6), 185)] En caso de lista de dictados el concepto es el mismo: a.reverse() # a: [8, 7, 6, 5, 4, 3, 2, 1]
    • 625. https://riptutorial.com/es/home 560 import datetime l = [{'name':'John Cena', 'birthday': datetime.date(1992, 9, 12),'size': {'height': 175, 'weight': 100}}, {'name': 'Chuck Norris', 'birthday': datetime.date(1990, 8, 28),'size' : {'height': 180, 'weight': 90}}, {'name': 'Jon Skeet', 'birthday': datetime.date(1991, 7, 6), 'size': {'height': 185, 'weight': 110}}] l.sort(key=lambda item: item['size']['height']) # l: [John Cena, Chuck Norris, Jon Skeet] from operator import itemgetter,attrgetter people = [{'name':'chandan','age':20,'salary':2000}, {'name':'chetan','age':18,'salary':5000}, {'name':'guru','age':30,'salary':3000}] by_age = itemgetter('age') by_salary = itemgetter('salary') people.sort(key=by_age) #in-place sorting by age people.sort(key=by_salary) #in-place sorting by salary list_of_tuples = [(1,2), (3,4), (5,0)] list_of_tuples.sort(key=itemgetter(1)) print(list_of_tuples) #[(5, 0), (1, 2), (3, 4)] persons = [Person("John Cena", datetime.date(1992, 9, 12), 175), Person("Chuck Norris", datetime.date(1990, 8, 28), 180), Ordenar por subdivisión: Mejor manera de ordenar usando attrgetter y itemgetter Las listas también se pueden clasificar utilizando las funciones attrgetter y itemgetter del módulo del operador. Estos pueden ayudar a mejorar la legibilidad y la reutilización. Aquí hay unos ejemplos, itemgetter también se puede dar un índice. Esto es útil si desea ordenar según los índices de una tupla. Utilice el attrgetter si desea ordenar por atributos de un objeto, {'name': 'Chuck Norris', 'birthday': datetime.date(1990, 8, 28),'height': 180}, {'name': 'Jon Skeet', 'birthday': datetime.date(1991, 7, 6), 'height': 185}] l.sort(key=lambda item: item['name']) # l: [Chuck Norris, John Cena, Jon Skeet] l.sort(key=lambda item: item['birthday']) # l: [ChuckNorris,Jon Skeet, JohnCena] l.sort(key=lambda item: item['height']) # l: [JohnCena, Chuck Norris, Jon Skeet]
    • 626. 561 a.clear() # a = [] b = ["blah"] * 3 # b = ["blah", "blah", "blah"] b = [1, 3, 5] * 5 # [1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3, 5] a = list(range(10)) del a[::2] # a = [1, 3, 5, 7, 9] del a[-1] # a = [1, 3, 5, 7] del a[:] # a = [] b = a a.append(6) # b: [1, 2, 3, 4, 5, 6] 10. clear() : elimina todos los elementos de lalista 11. Replicación : multiplicar una lista existente por un número entero producirá una lista más grande que consiste en tantas copias del original. Esto puede ser útil, por ejemplo, para la inicialización de listas: Tenga cuidado al hacer esto si su lista contiene referencias a objetos (por ejemplo, una lista de listas), vea Errores comunes: multiplicación de listas y referencias comunes . 12. Eliminación de elementos : es posible eliminar varios elementos de la lista utilizando la palabra clave del y la notación de segmento: 13. Proceso de copiar La asignación predeterminada "=" asigna una referencia de la lista original al nuevo nombre. Es decir, el nombre original y el nuevo nombre apuntan al mismo objeto de lista. Los cambios realizados a través de cualquiera de ellos se reflejarán en otro. Esto a menudo no es lo que pretendías. Si desea crear una copia de la lista, tiene las siguientes opciones. Puedes cortarlo: new_list = old_list[:] Person("Jon Skeet", datetime.date(1991, 7, 6), 185)] #reusing Person class from above example person.sort(key=attrgetter('name')) #sort by name by_birthday = attrgetter('birthday') person.sort(key=by_birthday) #sort by birthday
    • 627. 562 new_list = list(old_list) import copy new_list = copy.copy(old_list) #inserts references to the objects found in the original. import copy new_list = copy.deepcopy(old_list) #inserts copies of the objects found in the original. aa = a.copy() # aa = [1, 2, 3, 4, 5] len(['one', 'two']) # returns 2 len(['one', [2, 3], 'four']) # returns 3, not 4 my_list = ['foo', 'bar', 'baz'] for item in my_list: print(item) # Output: foo Puedes usar la función integrada en la lista (): Puedes usar copy.copy genérico (): Esto es un poco más lento que list () porque primero tiene que averiguar el tipo de datos de old_list. Si la lista contiene objetos y también desea copiarlos, use copy.deepcopy genérico (): Obviamente, el método más lento y que más memoria necesita, pero a veces inevitable. Python 3.x 3.0 copy() - Devuelve una copia superficial de la lista Longitud de una lista Use len() para obtener la longitud unidimensional de una lista. len()tambiénfuncionaencadenas,diccionariosyotrasestructurasdedatossimilaresalaslistas. Tenga en cuenta que len() es una función incorporada, no un método de un objeto de lista. También tenga en cuenta que el costo de len() es O(1) , lo que significa que tomará la misma cantidad de tiempo paraobtenerlalongitud deunalista,independientemente de sulongitud. Iterando sobre una lista Python admite el uso de un bucle for directamente en una lista:
    • 628. 563 for (index, item) in enumerate(my_list): print('The item in position {} is: {}'.format(index, item)) # Output: The item in position 0 is: foo # Output: The item in position 1 is: bar # Output: The item in position 2 is: baz for i in range(0,len(my_list)): print(my_list[i]) #output: >>> foo bar baz for item in my_list: if item == 'foo': del my_list[0] print(item) # Output: foo # Output: baz lst = ['test', 'twest', 'tweast', 'treast'] 'test' in lst #Out: True 'toast' in lst # Out: False También puede obtener la posición de cada elemento al mismo tiempo: La otra forma de iterar una lista basada en el valor del índice: Tenga en cuenta que cambiar elementos en una lista mientras se iteran en ella puede tener resultados inesperados: En este último ejemplo, eliminamos el primer elemento en la primera iteración, pero eso hizo que se omitiera la bar . Comprobando si un artículo está en una lista Python hace que sea muy sencillo comprobar si un elemento está en una lista. Simplemente use el operador in . Nota:eloperadorinenconjuntosesasintóticamentemásrápidoqueenlaslistas.Si necesitausarlo muchas veces en listas potencialmente grandes,puede convertir su list en un set y probar la presencia de elementos en el set . # Output: bar # Output: baz
    • 629. 564 In [3]: rev = reversed(numbers) In [4]: rev Out[4]: [9, 8, 7, 6, 5, 4, 3, 2, 1] In [1]: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9] In [2]: numbers[::-1] Out[2]: [9, 8, 7, 6, 5, 4, 3, 2, 1] lst = [] if not lst: print("list is empty") # Output: list is empty merged = list1 + list2 alist = ['a1', 'a2', 'a3'] blist = ['b1', 'b2', 'b3'] for a, b in zip(alist, blist): Elementos de la lista de inversión Puede utilizar la función reversed que devuelve un iterador a la lista invertida: Tenga en cuenta que la lista de "números" permanece sin cambios por esta operación, y permanece en el mismo orden en que estaba originalmente. Para invertir en su lugar, también puede utilizar el método reverse . También puede revertir una lista (al obtener una copia, la lista original no se ve afectada) utilizando la sintaxis de corte, estableciendo el tercer argumento (el paso) como -1: Comprobando si la lista está vacía ElvacíodeunalistaestáasociadoalbooleanoFalse ,porloquenotienequemarcarlen(lst) == 0 , sino solo lst o notlst Concatenar y fusionar listas 1. La forma más sencilla de concatenar list1 y list2 : 2. zip devuelve una lista de tuplas , donde la i-th tupla contiene el elemento i-th de cadauna de las secuencias de argumentos o iterables: slst = set(lst) 'test' in slst # Out:True
    • 630. 565 alist = ['a1', 'a2', 'a3'] blist = ['b1', 'b2', 'b3', 'b4'] for a, b in zip(alist, blist): print(a, b) # Output: # a1 b1 # a2 b2 # a3 b3 alist = [] len(list(zip(alist, blist))) # Output: # 0 alist = ['a1', 'a2', 'a3'] blist = ['b1'] clist = ['c1', 'c2', 'c3', 'c4'] for a,b,c in itertools.zip_longest(alist, blist, clist): print(a, b, c) # Output: # a1 b1 c1 # a2 None c2 # a3 None c3 # None None c4 alist = [123, 'xyz', 'zara', 'abc'] alist.insert(3, [2009]) print("Final List :", alist) Final List : [123, 'xyz', 'zara', 2009, 'abc'] Si las listas tienen diferentes longitudes, el resultado incluirá solo tantos elementos como el más corto: Para listas de relleno de longitud desigual a la más larga con None s use itertools.zip_longest ( itertools.izip_longest en Python 2) 3. Insertar en un índice de valores específicos: Salida: Todos y cada uno print(a, b) # Output: # a1 b1 # a2 b2 # a3 b3
    • 631. 566 nums = [1, 1, 0, 1] all(nums) # False chars = ['a', 'b', 'c', 'd'] all(chars) # True nums = [1, 1, 0, 1] any(nums) # True vals = [None, None, None, False] any(vals) # False vals = [1, 2, 3, 4] any(val > 12 for val in vals) # False any((val * 2) > 6 for val in vals) # True names = ["aixk", "duke", "edik", "tofp", "duke"] list(set(names)) # Out: ['duke', 'tofp', 'aixk', 'edik'] alist = [[[1,2],[3,4]], [[5,6,7],[8,9,10], [12, 13, 14]]] Puede usar all() para determinar si todos los valores en una evaluación iterable a True Del mismo modo, any() determina si uno o más valores en una evaluación iterable a True Si bien este ejemplo utiliza una lista, es importante tener en cuenta que estos elementos integrados funcionan con cualquier iterable, incluidos los generadores. Eliminar valores duplicados en la lista Laeliminacióndevaloresduplicadosenunalistasepuedehacerconvirtiendolalistaenunset (esdecir,unacoleccióndesordenadadeobjetosdistintos).Si senecesita unaestructura dedatos delist,entoncesel conjuntosepuede convertirdenuevo a unalistausandolalist()funciones list() : Tenga en cuenta que al convertir una lista en un conjunto, el pedido original se pierde. Para preservar el orden de la lista, se puede usar un OrderedDict Acceso a valores en lista anidada Comenzando con una lista tridimensional: import collections >>> collections.OrderedDict.fromkeys(names).keys() # Out: ['aixk', 'duke', 'edik', 'tofp']
    • 632. 567 for row in range(len(alist)): #A less Pythonic way to loop through lists for col in range(len(alist[row])): print(alist[row][col]) print(alist[0][0][1]) #2 #Accesses second element in the first list in the first list print(alist[1][1][2]) #10 #Accesses the third element in the second list in the second list alist[0][0].append(11) print(alist[0][0][2]) #11 #Appends 11 to the end of the first list in the first list for row in alist: #One way to loop through nested lists for col in row: print(col) #[1, 2, 11] #[3, 4] #[5, 6, 7] #[8, 9, 10] #[12, 13, 14] [col for row in alist for col in row] #[[1, 2, 11], [3, 4], [5, 6, 7], [8, 9, 10], [12, 13, 14]] alist[1].insert(2, 15) #Inserts 15 into the third position in the second list Accediendo a los elementos de la lista: Realizando operaciones de soporte: Usando anidados para bucles para imprimir la lista: Tenga en cuenta que esta operación se puede utilizar en una lista de comprensión o incluso como un generador para producir eficiencias, por ejemplo: No todos los elementos en las listas externas tienen que ser listas ellos mismos: Otra forma de utilizar anidados para bucles. La otra forma es mejor, pero he necesitado usar esto en ocasiones: #[1, 2, 11] #[3, 4] #[5, 6, 7] #[8, 9, 10] #15 #[12, 13, 14]
    • 633. 568 print(alist[1][1:]) #[[8, 9, 10], 15, [12, 13, 14]] #Slices still work print(alist) #[[[1, 2, 11], [3, 4]], [[5, 6, 7], [8, 9, 10], 15, [12, 13, 14]]] [1, 10, 100] < [2, 10, 100] # True, because 1 < 2 [1, 10, 100] < [1, 10, 100] # False, because the lists are equal [1, 10, 100] <= [1, 10, 100] # True, because the lists are equal [1, 10, 100] < [1, 10, 101] # True, because 100 < 101 [1, 10, 100] < [0, 10, 100] # False, because 0 < 1 [1, 10] < [1, 10, 100] # True my_list = [None] * 10 my_list = ['test'] * 10 >>> my_list=[{1}] * 10 >>> print(my_list) [{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}] >>> my_list[0].add(2) >>> print(my_list) [{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}] Usando rebanadas en la lista anidada: La lista final: Comparacion de listas Es posible comparar listas y otras secuencias lexicográficamente usando operadores de comparación. Ambos operandos deben ser del mismo tipo. Si una de las listas está contenida al comienzo de la otra, la lista más corta gana. Inicializando una lista a un número fijo de elementos Para elementos inmutables (por ejemplo, None , literales de cadenas, etc.): Para elementos mutables , la misma construcción dará como resultado que todos los elementos de la lista se refieran al mismo objeto, por ejemplo, para un conjunto: En su lugar, para inicializar la lista con un número fijo de objetos mutables diferentes , use:
    • 634. 569 my_list=[{1} for _ in range(10)]
    • 635. 570 [<expression> for <element> in <iterable> if <condition>] [x for x in range(10) if x % 2 == 0] # Out: [0, 2, 4, 6, 8] Capítulo 112: Lista de Comprensiones Introducción Una lista de comprensión es una herramienta sintáctica para crearlistas de forma natural y concisa, como seilustra en el siguiente códigoparahaceruna lista de cuadradosde los números del 1 al 10: [i ** 2 for i in range(1,11)] El dummy i de un range lista existente se usa para hacerunnuevopatróndeelemento.Seusadondeunbucleforseríanecesarioenlenguajes menos expresivos. Sintaxis • [i for i in range (10)] # lista de comprensión básica • [i for i in xrange (10)] # lista de comprensión básica con objeto generador en Python 2.x • [i for i in range (20) if i% 2 == 0] # con filtro • [x + y para x en [1, 2, 3] para y en [3, 4, 5]] # bucles anidados • [i if i> 6 else 0 for i in range (10)] # expresión ternaria • [i if i> 4 else 0 para i en el rango (20) if i% 2 == 0] # con filtro y expresión ternaria • [[x + y para x en [1, 2, 3]] para y en [3, 4, 5]] # comprensión de lista anidada Observaciones La lista de comprensión se describió en PEP 202 y se introdujo en Python 2.0. Examples Lista de comprensiones condicionales Dada una lista de comprensión , puede agregar uno o más if condiciones para filtrar los valores. Para cada <element> en <iterable> ; Si <condition> evalúa como True , agregue <expression> (generalmente una función de <element> ) a la lista devuelta. Por ejemplo, esto se puede usar para extraer solo números pares de una secuencia de enteros: Demo en vivo El código anterior es equivalente a:
    • 636. 571 [x if x % 2 == 0 else None for x in range(10)] # Out: [0, None, 2, None, 4, None, 6, None, 8, None] <value-if-condition-is-true> if <condition> else <value-if-condition-is-false> [2 * (x if x % 2 == 0 else -1) + 1 for x in range(10)] # Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1] [2 * (x if x % 2 == 0 else -1) + 1 for x in xrange(10)] # Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1] numbers = [] for x in range(10): if x % 2 == 0: temp = x else: temp = -1 Además,unacomprensióncondicionaldelalistadelaforma[efor xin y ifc](dondeeycson expresionesentérminosdex)esequivalentealist(filter(lambdax:c,map(lambdax: e,y))). A pesar de proporcionar el mismo resultado, preste atención al hecho de que el ejemplo anterior es casi 2 veces más rápido que el segundo. Para aquellos que tienen curiosidad, esta es una buena explicación de la razón. Tengaencuentaqueestoesbastantediferentedelaexpresióncondicional...if...else...(a vecesconocidacomoexpresión ternaria ) quepuedeusarparalaparte<expression> delalistade comprensión. Considere el siguienteejemplo: Demo en vivo Aquí, la expresión condicional no es un filtro, sino un operador que determina el valor que se utilizará para los elementos de la lista: Esto se vuelve más obvio si lo combinas con otros operadores: Demo en vivo Siestá utilizandoPython2.7, xrangepuedesermejorqueelrange porvariosmotivos,como se describe en la documentación de xrange . El código anterior es equivalente a: even_numbers = [] for x in range(10): if x % 2 == 0: even_numbers.append(x) print(even_numbers) # Out: [0, 2, 4, 6, 8]
    • 637. 572 [x if x > 2 else '*' for x in range(10) if x % 2 == 0] # Out: ['*', '*', 4, 6, 8] [x if (x > 2 and x % 2 == 0) else '*' for x in range(10)] # Out:['*', '*', '*', '*', 4, '*', 6, '*', 8, '*'] [ expression for target1 in iterable1 [if condition1] for target2 in iterable2 [if condition2]... for targetN in iterableN [if conditionN] ] data = [[1, 2], [3, 4], [5, 6]] output = [] for each_list in data: for element in each_list: output.append(element) print(output) # Out: [1, 2, 3, 4, 5, 6] data = [[1, 2], [3, 4], [5, 6]] output = [element for each_list in data for element in each_list] print(output) # Out: [1, 2, 3, 4, 5, 6] Sepuede combinar expresiones ternarios y if las condiciones.El operadorternario trabaja en el resultado filtrado: Lo mismo no podría haberse logrado solo por el operador ternario: Vea también: Filtros , que a menudo proporcionan una alternativa suficiente a las comprensiones de listas condicionales. Lista de Comprensiones con Bucles Anidados Las Comprensiones de lista pueden usar anidados for bucles.Puede codificar cualquier número de bucles for anidados dentro de una lista por comprensión, y cada uno for bucle puede tener una opción asociada if la prueba. Al hacerlo, el orden de la for las construcciones es del mismo orden que la hora de escribir una serie de anidado for declaraciones. La estructura general de las listas de comprensión se veasí: Por ejemplo, el siguiente código aplanamiento una lista de listas utilizando múltiples for declaraciones: se puede escribir de forma equivalente como una lista de comprensión con múltiples for construcciones: numbers.append(2 * temp + 1) print(numbers) # Out: [1, -1, 5, -1, 9, -1, 13, -1, 17, -1]
    • 638. 573 In [1]: data = [[1,2],[3,4],[5,6]] In [2]: def f(): ...: output=[] ...: for each_list in data: ...: for element in each_list: ...: output.append(element) ...: returnoutput In [3]: timeitf() 1000000 loops, best of 3: 1.37 µs per loop In [4]: timeit [inner for outer in data for inner in outer] 1000000 loops, best of 3: 632 ns per loop data = [[1], [2, 3], [4, 5]] output = [element for each_list in data if len(each_list) == 2 for element in each_list if element != 5] print(output) # Out: [2, 3, 4] Demo en vivo Tanto en la forma expandida como en la lista de comprensión, el bucle externo (primero para la declaración) aparece primero. Además de ser más compacto, la comprensión anidada también es significativamente más rápida. La sobrecarga para la llamada de función anterior es de aproximadamente 140 ns . Enlíneaif sestánanidadosdemanerasimilar,ypuedeocurrirencualquierposicióndespuésde la primera for : Demo en vivo Sin embargo, por razones de legibilidad, debe considerar el uso de bucles for tradicionales. Esto es especialmente cierto cuando el anidamiento tiene más de 2 niveles de profundidad y / o la lógica de la comprensión es demasiado compleja. la comprensión de múltiples listas de bucles anidadas podría ser propensa a errores o dar un resultado inesperado. Refactorización de filtro y mapa para enumerar las comprensiones. Las funciones de filter o map menudo deben serreemplazadas porlistas de comprensión . Guido Van Rossum describe esto bien en una carta abierta en 2005 : filter(P, S) casi siempre se escribe más claro como [x for x in S if P(x)] , y esto tienelagranventajadequelosusosmáscomunesincluyenpredicadosqueson comparaciones, por ejemplo, x==42 , y la definición de un lambda para eso solo requieremuchomásesfuerzoparaellector(másellambdaesmáslentoquelalista de comprensión). Más aún para el map(F, S) que se convierte en [F(x) for x in S] . Por supuesto, en muchos casos podrías usar expresiones generadoras.
    • 639. 574 filter(lambda x: x % 2 == 0, range(10)) # even numbers < 10 map(lambda x: 2*x, range(10)) # multiply each number by two reduce(lambda x,y: x+y, range(10)) # sum of all elements in list # Filter: # P(x) = x % 2 == 0 # S = range(10) [x for x in range(10) if x % 2 == 0] # Map # F(x) = 2*x # S = range(10) [2*x for x in range(10)] # Map & Filter filtered = filter(lambda x: x % 2 == 0, range(10)) results = map(lambda x: 2*x, filtered) # List comprehension results = [2*x for x in range(10) if x % 2 == 0] map(F, S) == [F(x) for x in S] filter(P, S) == [x for x in S if P(x)] Las siguientes líneas de código se consideran " no pythonic " y generarán errores en muchos linters de python. Tomando lo que hemos aprendido de la cita anterior, podemos desglosar estas expresiones de filter y map en sus listas de comprensión equivalentes; También elimina las funciones lambda de cada una, lo que hace que el código sea más legible en el proceso. La legibilidad se vuelve aún más evidente cuando se trata de funciones de encadenamiento. Donde debido a la legibilidad, los resultados de un mapa o función de filtro deben pasarse como resultado al siguiente; con casos simples, estos pueden ser reemplazados por una sola lista de comprensión. Además, podemos decir fácilmente de la comprensión de la lista cuál es el resultado de nuestro proceso, dónde hay más carga cognitiva al razonar sobre el proceso de Mapa y Filtro encadenado. Refactorización - Referencia rápida • Mapa • Filtrar donde F y P son funciones que transforman respectivamente los valores de entrada y devuelven un bool
    • 640. 575 #List Comprehension with nested loop [x + y for x in [1, 2, 3] for y in [3, 4, 5]] #Out: [4, 5, 6, 5, 6, 7, 6, 7, 8] #Nested List Comprehension [[x + y for x in [1, 2, 3]] for y in [3, 4, 5]] #Out: [[4, 5, 6], [5, 6, 7], [6, 7, 8]] l = [] for y in [3, 4, 5]: temp = [] for x in [1, 2, 3]: temp.append(x + y) l.append(temp) matrix = [[1,2,3], [4,5,6], [7,8,9]] [[row[i] for row in matrix] for i in range(len(matrix))] # [[1, 4, 7], [2, 5, 8], [3, 6, 9]] [[[i + j + k for k in 'cd'] for j in 'ab'] for i in '12'] # Out: [[['1ac', '1ad'], ['1bc', '1bd']], [['2ac', '2ad'], ['2bc', '2bd']]] >>> list_1 = [1, 2, 3 , 4] >>> list_2 = ['a', 'b', 'c', 'd'] >>> list_3 = ['6', '7', '8', '9'] # Two lists >>> [(i, j) for i, jin zip(list_1, list_2)] [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')] # Three lists Comprensiones de lista anidadas Las comprensiones de listas anidadas, a diferencia de las comprensiones de listas con bucles anidados, son comprensiones de listas dentro de una comprensión de listas. La expresión inicial puede ser cualquier expresión arbitraria, incluida otra lista de comprensión. El ejemplo anidado es equivalente a Un ejemplo donde se puede usar una comprensión anidada para transponer una matriz. Al igual que anidado for bucles, no hay límite a cómo se pueden anidarlas comprensiones profundas. Iterar dos o más listas simultáneamente dentro de la comprensión de la lista Paraiterar más de dos listas simultáneamente dentro de lacomprensión dela lista , se puede usar zip() como:
    • 641. 576 >>> [(i, j, k) for i, j, k in zip(list_1, list_2, list_3)] [(1, 'a', '6'), (2, 'b', '7'), (3, 'c', '8'), (4, 'd', '9')] # so on ...
    • 642. 577 a, b = (1, 2) print(a) # Prints:1 print(b) # Prints: 2 a, b, c = [1] # Raises: ValueError: not enough values to unpack (expected 3, got 1) head, *tail = [1, 2, 3, 4, 5] print(head) # Prints: 1 print(tail) # Prints: [2, 3, 4, 5] l = [1, 2, 3, 4, 5] head = l[0] tail = l[1:] Capítulo 113: Lista de desestructuración (también conocido como embalaje y desembalaje) Examples Tarea de destrucción En las asignaciones, puede dividir un Iterable en valores usando la sintaxis de "desempaquetar": La destrucción como valores. Si intenta desempaquetar más de la longitud del iterable, obtendrá un error: Python 3.x 3.0 La destrucción como lista Puede desempaquetar una lista de longitud desconocida usando la siguiente sintaxis: Aquí, extraemos el primer valor como un escalar, y los otros valores como una lista: Lo que equivale a:
    • 643. 578 a, b, *other, z = [1, 2, 3, 4, 5] print(a, b, z, other) # Prints: 1 2 5 [3, 4] a, _ = [1, 2] print(a) #Prints: 1 a, _, c = (1, 2, 3) print(a) # Prints:1 print(c) # Prints: 3 a, *_ = [1, 2, 3, 4, 5] print(a) #Prints: 1 a, *_, b = [1, 2, 3, 4, 5] print(a, b) # Prints: 15 a, _, b, _, c, *_ = [1, 2, 3, 4, 5, 6] print(a, b, c) # Prints: 1 3 5 def fun1(arg1, arg2, arg3): return (arg1,arg2,arg3) También funciona con múltiples elementos o elementos del final de la lista: Ignorar valores en las tareas de desestructuración. Si solo está interesado en un valor dado, puede usar _ para indicar que no está interesado. Nota: esto aún establecerá _ , solo la mayoría de la gente no lo usa como una variable. Python 3.x 3.0 Ignorar listas en tareas de desestructuración. Finalmente, puede ignorar muchos valores usando la sintaxis *_ en la asignación: lo que no es realmente interesante, ya que podría usar la indexación en la lista. Donde se pone agradable es mantener el primer y último valor en una tarea: o extraer varios valores a la vez: Argumentos de la función de embalaje En funciones, puede definir una serie de argumentos obligatorios:
    • 644. 579 fun1(1, 2, 3) def fun2(arg1='a', arg2='b', arg3='c'): return (arg1,arg2,arg3) fun2(arg2=2, arg3=3) → (a,2,3) ... → (1,b,c) → (1,2,c) fun2(1) fun2(1, 2) l = [1,2,3] fun1(*l) # Returns: (1,2,3) fun1(*['w', 't', 'f']) # Returns: ('w','t','f') fun1(*['oops']) # Raises: TypeError: fun1() missing 2 required positional arguments: 'arg2' and 'arg3' d = { 'arg1': 1, 'arg2': 2, 'arg3': 3 } fun1(**d) # Returns: (1, 2, 3) lo que hará que la función se pueda llamar solo cuando se den los tres argumentos: y puede definir los argumentos como opcionales, utilizando valores predeterminados: por lo que puede llamar a la función de muchas maneras diferentes, como: Perotambiénpuedeusarlasintaxisdedesestructuraciónparaempacarargumentos,de modo que puede asignar variables usando una list o un dict . Empaquetando una lista de argumentos Considera que tienes una lista de valores. Puede llamar a la función con la lista de valores como un argumento usando la sintaxis * : Pero si no proporciona una lista cuya longitud coincida con el número de argumentos: Packing argumentos de palabras clave Ahora, también puede empaquetar argumentos utilizando un diccionario. Puede usar el operador ** para decirle a Python que descomprima el dict como valores de parámetros:
    • 645. 580 fun1(**{'arg1':1, 'arg2':2}) # Raises: TypeError: fun1() missing 1 required positional argument: 'arg3' fun1(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4}) # Raises: TypeError: fun1() got an unexpected keyword argument 'arg4' fun2(**d) # Returns: (1, 2, 3) fun2(**{'arg2': 2}) # Returns: ('a', 2, 'c') fun2(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4}) # Raises: TypeError: fun2() got an unexpected keyword argument 'arg4' def fun3(arg1, arg2='b', arg3='c') return (arg1, arg2, arg3) fun3(*[1]) # Returns: (1, 'b', 'c') fun3(*[1,2,3]) # Returns: (1, 2, 3) fun3(**{'arg1':1}) # Returns: (1, 'b', 'c') fun3(**{'arg1':1, 'arg2':2, 'arg3':3}) # Returns: (1, 2, 3) fun3(*[1,2], **{'arg3':3}) # Returns: (1,2,3) cuando la función solo tiene argumentos posicionales (los que no tienen valores predeterminados), necesita que el diccionario contenga todos los parámetros esperados y no tenga un parámetro adicional, o obtendrá un error: Para las funciones que tienen argumentos opcionales, puede empaquetar los argumentos como un diccionario de la misma manera: Pero allí puede omitir valores, ya que serán reemplazados por los valores predeterminados: Y al igual que antes, no puede dar valores adicionales que no sean parámetros existentes: En el uso del mundo real, las funciones pueden tener argumentos tanto posicionales como opcionales, y funciona de la misma manera: Puedes llamar a la función con solo un iterable: o con solo un diccionario: o puedes usar ambos en la misma llamada:
    • 646. 581 fun3(*[1,2], **{'arg2':42, 'arg3':3}) # Raises: TypeError: fun3() got multiple values for argument 'arg2' def fun1(*args, **kwargs): print(args, kwargs) fun1(1,2,3) # Prints: (1, 2, 3) {} fun1(a=1, b=2, c=3) # Prints: () {'a': 1, 'b': 2, 'c': 3} fun1('x', 'y', 'z', a=1, b=2, c=3) # Prints: ('x', 'y', 'z') {'a': 1, 'b': 2, 'c': 3} class MyString(str): def init (self, *args, **kwarg): print('Constructing MyString') super(MyString,self). init (*args, **kwarg) Tenga en cuenta que no puede proporcionar varios valores para el mismo argumento: Desempaquetando argumentos de funciones Cuando desee crear una función que pueda aceptar cualquier número de argumentos y no imponer la posición o el nombre del argumento en el momento de la "compilación", es posible y a continuación le indicamos cómo: Los parámetros *args y **kwargs son parámetros especiales que se establecen en una tuple y un dict , respectivamente: Si observa suficiente código de Python, descubrirá rápidamente que se está utilizando ampliamente al pasar argumentos a otra función. Por ejemplo, si desea extender la clase de cadena:
    • 647. 582 Capítulo 114: Listar comprensiones Introducción Las comprensiones de listas en Python son construcciones sintácticas concisas. Se pueden utilizar para generar listas de otras listas aplicando funciones a cada elemento de la lista. La siguiente sección explica y demuestra el uso de estas expresiones. Sintaxis • [x + 1 para x en (1, 2, 3)] # comprensión de lista, da [2, 3, 4] • (x + 1 para x en (1, 2, 3)) # expresión del generador, producirá 2, luego 3, luego 4 • [x para x en (1, 2, 3) si x% 2 == 0] # enumerar comprensión con filtro, da [2] • [x + 1 si x% 2 == 0 sino x para x en (1, 2, 3)] # lista comprensión con ternario • [x + 1 si x% 2 == 0 sino x para x en el rango (-3,4) si x> 0] # lista comprensión con ternario y filtrado • {x para x en (1, 2, 2, 3)} # establecer comprensión, da {1, 2, 3} • {k: v para k, v en [('a', 1), ('b', 2)]} # dict comprensión, da {'a': 1, 'b': 2} (python 2.7+ y 3.0+ solamente) • [x + y para x en [1, 2] para y en [10, 20]] # Bucles anidados, da [11, 21, 12, 22] • [x + y para x en [1, 2, 3] si x> 2 para y en [3, 4, 5]] # Condición verificada al principio para bucle • [x + y para x en [1, 2, 3] para y en [3, 4, 5] si x> 2] # Condición verificada en 2da para bucle • [x para x en xrange (10) si x% 2 == 0] # Condición verificada si los números en bucle son números impares Observaciones Las comprensiones son construcciones sintácticas que definen estructuras de datos o expresiones exclusivas de un idioma en particular. El uso adecuado de las comprensiones las reinterpreta en expresiones fáciles de entender. Como expresiones, se pueden utilizar: • en el lado derecho de las tareas • como argumentos para llamadas de funcion • en el cuerpo de una función lambda • como declaraciones independientes. (Por ejemplo: [print(x) for x in range(10)] ) Examples Lista de Comprensiones Una lista de comprensión crea una nueva list al aplicar una expresión a cada elemento de un iterable . La forma más básica es:
    • 648. 583 [ <expression> for <element> in <iterable> if <condition> ] squares = [x * x for x in (1, 2, 3, 4)] # squares: [1, 4, 9, 16] squares = [] for x in (1, 2, 3, 4): squares.append(x * x) # squares: [1, 4, 9, 16] # Get a list of uppercase characters from a string [s.upper() for s in "Hello World"] # ['H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'] # Strip off any commas from the end of strings in a list [w.strip(',') for w in ['these,', 'words,,', 'mostly', 'have,commas,']] # ['these', 'words', 'mostly', 'have,commas'] # Organize letters in words more reasonably - in an alphabetical order sentence = "Beautiful is better than ugly" ["".join(sorted(word, key=lambdax: x.lower()))for wordin sentence.split()] # ['aBefiltuu', 'is', 'beertt', 'ahnt', 'gluy'] También hay una condición opcional "si": Cada <element> en el <iterable> se conecta a la <expression> si el <condition> (opcional) se evalúa como verdadero . Todos los resultados se devuelven a la vez en la nueva lista. Las expresiones de los generadores se evalúan perezosamente, pero las comprensiones de la lista evalúan todo el iterador inmediatamente, consumiendo memoria proporcional a la longitud del iterador. Para crear una list de enteros cuadrados: Laexpresiónforestablecexacadavalorporturnode(1,2,3,4).Elresultadodelaexpresión x * x seanexaaunalistinterna. Lalistinternaseasignaalossquaresvariablescuandose completa. Además de un aumento de velocidad (como se explica aquí ), una comprensión de la lista es aproximadamente equivalente al siguiente bucle for: La expresión aplicada a cada elemento puede ser tan compleja como sea necesario: más else se puede utilizar en las construcciones de comprensión de listas, pero tenga cuidado con la sintaxis. Las cláusulas if / else deben usarse antes for bucle, no después: [ <expression> for <element> in <iterable> ]
    • 649. 584 def foo(i): return i, i + 0.5 for i in range(3): for x in foo(i): yield str(x) [str(x) for i in range(3) for x in foo(i) ] Tenga en cuenta que esto utiliza una construcción de lenguaje diferente, una expresión condicional , que en sí misma no es parte de la sintaxis de comprensión .Considerando que el if after the for…in es parte de la lista de comprensión y se utiliza para filtrar elementos de la fuente iterable. Doble iteración Elordendedoble iteración [... for x in ... for y in ...]esnaturalocontraintuitivo.Laregla de oro es seguir un equivalente for bucle: Esto se convierte en: Esto se puede comprimir en una línea como [str(x) for i in range(3) for x in foo(i)] Mutación in situ y otros efectos secundarios Antes de usar la comprensión de lista, comprenda la diferencia entre las funciones solicitadas por sus efectos secundarios (funciones mutantes o en el lugar ) que generalmente devuelven None y las funciones que devuelven un valor interesante. Muchas funciones (especialmente funciones puras ) simplemente toman un objeto y devuelven algún objeto. Una función en el lugar modifica el objeto existente, que se denomina efecto secundario . Otros ejemplos incluyen operaciones de entrada y salida, como la impresión. list.sort() ordena una lista en el lugar (lo que significa que modifica la lista original) y devuelve el # create a list of characters in apple, replacing non vowels with '*' # Ex - 'apple' --> ['a', '*', '*', '*' ,'e'] [x for x in 'apple' if x in 'aeiou' else '*'] #SyntaxError: invalid syntax #Whenusingif/else togetherusethembeforethe loop [x if x in 'aeiou' else '*' for x in 'apple'] #['a', '*', '*', '*', 'e']
    • 650. 585 [x.sort() for x in [[2, 1], [4, 3], [0, 1]]] # [None, None,None] [sorted(x) for x in [[2, 1], [4, 3], [0, 1]]] # [[1, 2], [3, 4], [0, 1]] [print(x) for x in (1, 2, 3)] for x in (1, 2, 3): print(x) from random import randrange [randrange(1, 7) for _ in range(10)] # [2, 3, 2, 1, 1, 5, 2, 4, 3, 5] [ x for x in 'foo' if x not in 'bar' ] valor None . Por lo tanto, no funcionará como se espera en una lista de comprensión: En su lugar, sorted() devuelve una list ordenada en lugar de ordenar in situ: Es posible el uso de comprensiones para efectos secundarios, como I / O o funciones in situ. Sin embargo, un bucle for suele ser más legible. Mientras esto funciona en Python 3: En su lugar, utilice: En algunas situaciones, las funciones de efectos secundarios son adecuadas para la comprensión de listas. random.randrange() tiene el efecto secundario de cambiar el estado del generadordenúmerosaleatorios,perotambiéndevuelveunvalorinteresante.Además,se puede llamar a next() en un iterador. El siguiente generador de valores aleatorios no es puro, pero tiene sentido ya que el generador aleatorio se restablece cada vez que se evalúa la expresión: Los espacios en blanco en la lista de comprensión Las comprensiones de listas más complicadas pueden alcanzar una longitud no deseada o volverse menos legibles. Aunque es menos común en los ejemplos, es posible dividir una lista de comprensión en varias líneas, como por ejemplo:
    • 651. 586 {x: x * x for x in (1, 2, 3, 4)} # Out: {1: 1, 2: 4, 3: 9, 4: 16} dict((x, x * x) for x in (1, 2, 3, 4)) # Out: {1: 1, 2: 4, 3: 9, 4: 16} {name:len(name)for name in ('Stack', 'Overflow', 'Exchange')if len(name)> 6} # Out: {'Exchange': 8, 'Overflow': 8} dict((name, len(name)) for name in ('Stack', 'Overflow', 'Exchange') if len(name) > 6) # Out: {'Exchange': 8, 'Overflow': 8} initial_dict = {'x': 1, 'y': 2} {key: value for key, value in initial_dict.items() if key == 'x'} # Out: {'x': 1} my_dict = {1: 'a', 2: 'b', 3: 'c'} Diccionario de Comprensiones Una comprensión de diccionario es similar a una comprensión de lista, excepto que produce un objeto de diccionario en lugar de una lista. Un ejemplo básico: Python 2.x 2.7 que es solo otra forma de escribir: Al igual que con una lista de comprensión, podemos usar una declaración condicional dentro de la comprensión de dict para producir solo los elementos de dict que cumplan con algún criterio. Python 2.x 2.7 O, reescrito usando una expresión generadora. Comenzando con un diccionario y utilizando la comprensión del diccionario como un filtro de par clave-valor Python 2.x 2.7 Tecla de conmutación y valor del diccionario (diccionario invertido) Si tiene un dict que contiene valores hashables simples (los valores duplicados pueden tener resultados inesperados): y quería intercambiar las claves y los valores, puede adoptar varios enfoques dependiendo de su
    • 652. 587 {**dict1, **dict2} # Out: {'w': 1, 'x': 2, 'y': 2, 'z': 2} print(swapped) # Out: {a: 1, b: 2, c: 3} dict1 = {'w': 1, 'x': 1} dict2 = {'x': 2, 'y': 2, 'z': 2} {k: v for d in [dict1, dict2] for k, v in d.items()} # Out: {'w': 1, 'x': 2, 'y': 2, 'z': 2} # list comprehension [x**2 for x in range(10)] # Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] estilo de codificación: • swapped = {v: k for k, v in my_dict.items()} • swapped = dict((v, k) for k, v in my_dict.iteritems()) • swapped = dict(zip(my_dict.values(), my_dict)) • swapped = dict(zip(my_dict.values(), my_dict.keys())) • swapped = dict(map(reversed, my_dict.items())) Python 2.x 2.3 Si su diccionario es grande, considere la importación itertools y utilizar izip o imap . Fusionando diccionarios Combine diccionarios y, opcionalmente, anule valores antiguos con una comprensión de diccionario anidado. Sin embargo, el desempaque del diccionario ( PEP 448 ) puede ser el preferido. Python 3.x 3.5 Nota : las comprensiones de diccionarios se agregaron en Python 3.0 y se respaldaron a 2.7+, a diferencia de las comprensiones de listas, que se agregaron en 2.0. Las versiones <2.7 pueden usar expresiones generadoras y el dict() incorporado para simular el comportamiento de las comprensiones de diccionario. Expresiones del generador Las expresiones generadoras son muy similares a las listas de comprensión. La principal diferencia es que no crea un conjunto completo de resultados a la vez; crea un objeto generador que luego puede ser iterado. Por ejemplo, vea la diferencia en el siguiente código: Python 2.x 2.4
    • 653. 588 for i in [x**2 for x in range(10)]: print(i) """ g = (x**2 for x in xrange(10)) print(g[0]) Traceback (most recent call last): File "<stdin>", line 1, in<module> TypeError: 'generator' object has no attribute ' getitem ' Traceback (most recent call last): File "<stdin>", line 1, in<module> StopIteration Estos son dos objetos muy diferentes: • lalistadecomprensióndevuelveunobjetodelistmientrasquelacomprensióndel generador devuelve un generator . • generator objetos generator no se pueden indexar y hace uso de la next función para ordenar los artículos. Nota : Utilizamos xrange ya que también crea un objeto generador. Si usaríamos el rango, se crearía una lista. Además, xrange solo existe en la versión posterior de python 2. En python 3, range solo devuelve un generador. Para obtener más información, consulte el ejemplo de Diferencias entre las funciones de rango y rango . Python 2.x 2.4 g.next() # 0 g.next() # 1 g.next() # 4 ... g.next() # 81 g.next() # Throws StopIteration Exception Python 3.x 3.0 NOTA: La función g.next() debe sustituirse por next(g) y xrange con range ya que Iterator.next() y xrange() no existen en Python 3. Aunqueambospuedenseriteradosdemanerasimilar: # generator comprehension (x**2 for x in xrange(10)) # Output: <generator object <genexpr> at 0x11b4b7c80>
    • 654. 589 for i in (x**2 for x in xrange(10)): print(i) """ Out: 0 1 4 . . . 81 """ for square in (x**2 for x in range(1000000)): #do something def get_objects(): """Gets objects from an API one by one""" while True: yield get_next_item() def object_matches_pattern(obj): # perform potentially complex calculation return matches_pattern def right_item_exists(): items = (object_matched_pattern(each) for each in get_objects()) for item in items: if item.is_the_right_one: Python 2.x 2.4 Casos de uso Las expresiones del generador se evalúan perezosamente, lo que significa que generan y devuelven cada valor solo cuando el generador está iterado. Esto suele ser útil cuando se itera a través de grandes conjuntos de datos, evitando la necesidad de crear un duplicado del conjunto de datos en la memoria: Otro caso de uso común es evitar la iteración en todo un iterable si no es necesario hacerlo. En este ejemplo, un elemento se recupera de una API remota con cada iteración de get_objects() . Pueden existir miles de objetos, deben recuperarse uno por uno, y solo necesitamos saber si existe un objeto que coincida con un patrón. Al usar una expresión generadora, cuando encontramos un objeto que coincide con el patrón. Out: 0 1 4 ... 81 """
    • 655. 590 # A set containing every value in range(5): {x for x in range(5)} # Out: {0, 1, 2, 3, 4} # A set of even numbers between 1 and 10: {x for x in range(1, 11) if x % 2 == 0} # Out: {2, 4, 6, 8, 10} # Unique alphabetic characters in a string of text: text = "When in the Course of human events it becomes necessary for one people..." {ch.lower() for ch in text if ch.isalpha()} # Out: set(['a', 'c', 'b', 'e', 'f', 'i', 'h', 'm', 'l', 'o', # 'n', 'p', 's', 'r', 'u', 't', 'w', 'v', 'y']) set(x for x in range(5)) # Out: {0, 1, 2, 3, 4} >>> [f(x)for x in range(1000) if f(x) > 10] [16, 25, 36, ...] # Simulate expensive function import time time.sleep(.1) return x**2 ... ... ... >>> def f(x): Establecer Comprensiones La comprensión del conjunto es similar a la lista y la comprensión del diccionario , pero produce un conjunto , que es una colección desordenada de elementos únicos. Python 2.x 2.7 Demo en vivo Tenga en cuenta que los conjuntos están desordenados. Esto significa que el orden de los resultados en el conjunto puede diferir del presentado en los ejemplos anteriores. Nota : la comprensión de configuración está disponible desde python 2.7+, a diferencia de las comprensiones de lista, que se agregaron en 2.0. En Python 2.2 a Python 2.6, la función set() se puede usar con una expresión generadora para producir el mismo resultado: Python 2.x 2.2 Evite operaciones repetitivas y costosas usando cláusula condicional Considere la siguiente lista de comprensión: Esto da como resultado dos llamadas a f(x) para 1,000 valores de x : una llamada para generar return True return False
    • 656. 591 >>> [v for v in (f(x) for x in range(1000)) if v > 10] [16, 25, 36, ...] >>> [v for v in map(f, range(1000)) if v > 10] [16, 25, 36, ...] >>> [v for x in range(1000) for v in [f(x)] if v > 10] [16, 25, 36, ...] >>> def process_prime_numbers(iterable): ... for x in iterable: ... if is_prime(x): ... yield f(x) ... >>> [x for x in process_prime_numbers(range(1000)) ifx > 10] [11, 13, 17, 19, ...] l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] elvalorylaotraparaverificarlacondiciónif.Sif(x)esunaoperaciónparticularmentecostosa, estopuedetenerimplicacionessignificativasenelrendimiento.Peoraún,sillamaraf()tiene efectos secundarios, puede tener resultados sorprendentes. En su lugar, debe evaluar la operación costosa solo una vez para cada valor de x generando un iterable intermedio ( expresión del generador ) de la siguiente manera: O, usando el mapa incorporado equivalente: Otra forma que podría resultar en un código más legible es colocar el resultado parcial ( v en el ejemplo anterior) en un iterable (como una lista o una tupla) y luego iterar sobre él. Como v será el único elemento en el iterable, el resultado es que ahora tenemos una referencia a la salida de nuestra función lenta calculada solo una vez: Sin embargo, en la práctica, la lógica del código puede ser más complicada y es importante mantenerlo legible. En general, se recomienda una función de generador por separado en un complejo de una sola línea: Otramaneradeevitar el cálculodef(x) variasveces es utilizar el @functools.lru_cache() (Python 3.2+)decoradorenf(x).Deestamanera, dadoquelasalidadefparalaentradax yaseha calculadouna vez, lainvocación dela segunda función de la comprensión dela lista original será tanrápidacomolabúsquedadeundiccionario.Esteenfoqueutilizalamemoriaparamejorarla eficiencia, que es comparable al uso de expresiones generadoras. Di que tienes que aplanar una lista Algunos de los métodos podrían ser:
    • 657. 592 [item for sublist in l for item in sublist] [x + y for x, y in [(1, 2), (3, 4), (5, 6)]] # Out: [3, 7, 11] [x + y for x, y in zip([1, 3, 5], [2, 4, 6])] # Out: [3, 7, 11] for x, y in [(1,2), (3,4), (5,6)]: print(x+y) # 3 # 7 # 11 [x, y for x, y in [(1, 2), (3, 4), (5, 6)]] # SyntaxError: invalid syntax [(x, y) for x, y in [(1, 2), (3, 4), (5, 6)]] # Out: [(1, 2), (3, 4), (5, 6)] Sin embargo, la comprensión de la lista proporcionaría la mejor complejidad de tiempo. Los accesos directos basados en + (incluido el uso implícito en la suma) son, por necesidad, O (L ^ 2) cuando hay L sublistas: a medida que la lista de resultados intermedios se hace más larga, en cada paso se obtiene un nuevo objeto de lista de resultados intermedios. asignados, y todos los elementos en el resultado intermedio anterior deben copiarse (así como algunos nuevos agregados al final). Entonces (por simplicidad y sin pérdida de generalidad real) digamos que tiene L sublistas de I elementos cada uno: los primeros elementos I se copian una y otra vez L-1 veces, el segundo I elementos L-2 veces, y así sucesivamente; el número total de copias es I veces la suma de x para x de 1 a L excluidas, es decir, I * (L ** 2) / 2. La lista de comprensión solo genera una lista, una vez, y copia cada elemento (de su lugar de residencia original a la lista de resultados) también una sola vez. Comprensiones que involucran tuplas La cláusula for de una lista de comprensión puede especificar más de una variable: Esto es como regular for bucles: Sin embargo, tenga en cuenta que si la expresión que comienza la comprensión es una tupla, debe estar entre paréntesis: Contando Ocurrencias Usando Comprensión reduce(lambda x, y: x+y, l) sum(l, []) list(itertools.chain(*l))
    • 658. 593 # Count the numbers in `range(1000)` that are even and contain the digit `9`: print (sum( 1 for x in range(1000) if x % 2 == 0 and '9' in str(x) )) # Out: 95 # Convert a list of strings to integers. items = ["1","2","3","4"] [int(item) for item in items] # Out: [1, 2, 3, 4] # Convert a list of strings to float. items = ["1","2","3","4"] map(float, items) # Out:[1.0, 2.0, 3.0, 4.0] Cuando queremos contar el número de elementos en un iterable, que cumplan con alguna condición, podemos usar la comprensión para producir una sintaxis idiomática: El concepto básico se puede resumir como: 1. Iterar sobre los elementos en range(1000) . 2. Concatenar todo lo necesario if condiciones. 3. Utilice 1 como expresión para devolver un 1 por cada elemento que cumpla con las condiciones. 4. Resuma todos los 1 s para determinar la cantidad de elementos que cumplen con las condiciones. Nota : Aquí no estamos recolectando los 1 s en una lista (note la ausencia de corchetes), pero pasamos los directamente a la función de sum que los está sumando. Esto se denomina expresión generadora , que es similar a una comprensión. Cambio de tipos en una lista Los datos cuantitativos a menudo se leen como cadenas que deben convertirse en tipos numéricos antesde procesarlos.Los tiposde todos loselementos delalistasepueden convertir con una Comprensión de lista o la función map() .
    • 659. 594 class Node: def init (self, val): self.data = val self.next = None def getData(self): return self.data def getNext(self): return self.next def setData(self, val): self.data = val def setNext(self, val): self.next = val class LinkedList: def init (self): self.head= None def isEmpty(self): """Check if the list is empty""" return self.head is None def add(self, item): """Add the item to the list""" new_node = Node(item) new_node.setNext(self.head) self.head = new_node def size(self): """Return the length/size of the list""" count = 0 current = self.head while current is not None: count += 1 Capítulo 115: Listas enlazadas Introducción Una lista enlazada es una colección de nodos, cada uno compuesto por una referencia y un valor. Los nodos se unen en una secuencia utilizando sus referencias. Las listas vinculadas se pueden utilizar para implementar estructuras de datos más complejas como listas, pilas, colas y matrices asociativas. Examples Ejemplo de lista enlazada única Este ejemplo implementa una lista enlazada con muchos de los mismos métodos que el objeto de lista integrado.
    • 660. 595 current = current.getNext() return count def search(self,item): """Search foritemin list.Iffound,returnTrue.If notfound,returnFalse""" current = self.head found = False while current is not None and not found: if current.getData() is item: found = True else: current = current.getNext() return found def remove(self, item): """Remove item from list. If item is not found in list, raise ValueError""" current = self.head previous = None found = False while current is not None and not found: if current.getData() is item: found = True else: previous = current current = current.getNext() if found: if previous is None: self.head = current.getNext() else: previous.setNext(current.getNext()) else: raise ValueError print 'Value not found.' def insert(self, position, item): """ Insert item at position specified. If position specified is out of bounds, raise IndexError """ if position > self.size() - 1: raise IndexError print "Index out of bounds." current = self.head previous = None pos = 0 if position is 0: self.add(item) else: new_node = Node(item) while pos < position: pos += 1 previous = current current = current.getNext() previous.setNext(new_node) new_node.setNext(current) def index(self, item): """ Return the index where item isfound. If item is not found, return None. """
    • 661. 596 current = self.head pos = 0 found = False while current is not None and not found: if current.getData() is item: found = True else: current = current.getNext() pos += 1 if found: pass else: pos = None return pos def pop(self, position = None): """ If no argument is provided, return and remove the item at the head. If position is provided, return and remove the item at that position. If index is out of bounds, raise IndexError """ if position > self.size(): print 'Index out of bounds' raise IndexError current = self.head if position is None: ret = current.getData() self.head = current.getNext() else: pos = 0 previous = None while pos < position: previous = current current = current.getNext() pos += 1 ret = current.getData() previous.setNext(current.getNext()) print ret return ret def append(self, item): """Append item to the end of the list""" current = self.head previous = None pos = 0 length = self.size() while pos < length: previous = current current = current.getNext() pos += 1 new_node = Node(item) if previous is None: new_node.setNext(current) self.head = new_node else: previous.setNext(new_node) def printList(self): """Print the list""" current = self.head
    • 662. 597 ll=LinkedList() ll.add('l') ll.add('H') ll.insert(1,'e') ll.append('l') ll.append('o') ll.printList() H e l l o El uso funciona muy parecido al de la lista incorporada. while current is not None: print current.getData() current = current.getNext()
    • 663. 598 BsonDocument argsBson = BsonDocument.Parse("{ 'x' : '1', 'y' : '2' }"); string argsFile = string.Format("{0}\\{1}.txt", Path.GetDirectoryName(pyScriptPath), Guid.NewGuid()); filename = sys.argv[ 1 ] with open( filename ) as data_file: input_args = json.loads( data_file.read() ) x, y = [ float(input_args.get( key )) for key in [ 'x', 'y' ] ] print json.dumps( { 'sum' : x + y , 'subtract' : x - y } ) Capítulo 116: Llama a Python desde C # Introducción La documentación proporciona una implementación de muestra de la comunicación entre procesos entre C # y los scripts de Python. Observaciones Tenga en cuenta que en el ejemplo anterior, los datos se serializan utilizando la biblioteca MongoDB.Bson que se puede instalar a través del administrador NuGet. De lo contrario, puede utilizar cualquier biblioteca de serialización JSON de su elección. A continuación se presentan los pasos de implementación de la comunicación entre procesos: • Los argumentos de entrada se serializan en una cadena JSON y se guardan en un archivo de texto temporal: • Python interpreter python.exe ejecuta la secuencia de comandos de python que lee la cadena JSON desde un archivo de texto temporal y los argumentos de entrada de retroceso: • El script de Python se ejecuta y el diccionario de salida se serializa en una cadena JSON y se imprime en la ventana de comandos: • Lea la cadena JSON de salida de la aplicación C #:
    • 664. 599 import sys import json # load input arguments from the text file filename = sys.argv[ 1 ] with open( filename ) as data_file: input_args = json.loads( data_file.read()) # cast strings to floats Estoy utilizando la comunicación entre procesos entre C # y los scripts de Python en uno de mis proyectos que permite llamar a los scripts de Python directamente desde hojas de cálculo de Excel. El proyecto utiliza el complemento ExcelDNA para C # - enlace Excel. El código fuente se almacena en el repositorio de GitHub. A continuación se encuentran enlaces a páginas wiki que brindan una descripción general del proyecto y ayudan a comenzar en 4 sencillos pasos . • Empezando • Descripción general de la implementación • Ejemplos • Asistente de objetos • Funciones Espero que encuentre útil el ejemplo y el proyecto. Examples Script de Python para ser llamado por la aplicación C # using (StreamReader myStreamReader = process.StandardOutput) { outputString = myStreamReader.ReadLine(); process.WaitForExit(); }
    • 665. 600 Código C # llamando al script Python using MongoDB.Bson; using System; using System.Diagnostics; using System.IO; namespace python_csharp { class Program { static void Main(string[] args) { // full path to .py file string pyScriptPath = "......../sum.py"; // convert input arguments to JSON string BsonDocument argsBson=BsonDocument.Parse("{ 'x' : '1', 'y' :'2' }"); bool saveInputFile = false; string argsFile = string.Format("{0}\\{1}.txt", Path.GetDirectoryName(pyScriptPath), Guid.NewGuid()); string outputString = null; // create new process start info ProcessStartInfo prcStartInfo = new ProcessStartInfo { }; try { // full path of the Python interpreter 'python.exe' FileName="python.exe",//string.Format(@"""{0}""","python.exe"), UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = false // write input arguments to .txt file using (StreamWriter sw = new StreamWriter(argsFile)) { sw.WriteLine(argsBson); prcStartInfo.Arguments = string.Format("{0} {1}", string.Format(@"""{0}""", pyScriptPath), string.Format(@"""{0}""", argsFile)); } // start process using (Process process = Process.Start(prcStartInfo)) { // read standard output JSON string using (StreamReader myStreamReader = process.StandardOutput) { outputString = myStreamReader.ReadLine(); process.WaitForExit(); } } } finally x, y = [ float(input_args.get( key )) for key in [ 'x', 'y' ] ] print json.dumps( { 'sum' : x + y , 'subtract' : x - y } )
    • 666. 601 { //delete/save temporary.txtfile if (!saveInputFile) { File.Delete(argsFile); } } Console.WriteLine(outputString); } } }
    • 667. 602 finally: # --- Cleanup on exit --- stdscr.keypad(0) curses.echo() curses.nocbreak() curses.endwin() # print trace back log of the error except: traceback.print_exc() import curses import traceback try: # -- Initialize -- stdscr = curses.initscr() # initialize curses screen curses.noecho() # turn off auto echoing of keypress on to screen curses.cbreak() # enter break mode where pressing Enter key # after keystroke is not required for it to register stdscr.keypad(1) # enable special Key values such as curses.KEY_LEFT etc # -- Perform an action with Screen -- stdscr.border(0) stdscr.addstr(5, 5, 'Hello from Curses!', curses.A_BOLD) stdscr.addstr(6, 5, 'Press q to close this screen', curses.A_NORMAL) while True: # stay in this loop till the user presses 'q' ch = stdscr.getch() if ch == ord('q'): break # -- End of user code -- Capítulo 117: Maldiciones básicas con pitón Observaciones Curses es un módulo básico de manejo de terminal (o visualización de caracteres) de Python. Esto se puede utilizar para crear interfaces de usuario basadas en terminal o TUI. Este es un puerto python de una biblioteca C más popular 'ncurses' Examples Ejemplo básico de invocación La función de ayuda wrapper (). Si bien la invocación básica anterior es bastante fácil, el paquete curses proporciona la wrapper(func, ...)ayudade wrapper(func, ...).Elsiguienteejemplocontieneelequivalentede arriba:
    • 668. 603 Aquí, la envoltura inicializará las cursas, creará stdscr , un objeto WindowObject y pasará ambos stdscr, y cualquier argumento adicional a func . Cuando la func vuelve, la wrapper restaurará el terminal antes de que el programasalga. main(scr, *args): # -- Perform an action with Screen -- scr.border(0) scr.addstr(5, 5, 'Hello from Curses!', curses.A_BOLD) scr.addstr(6, 5, 'Press q to close this screen', curses.A_NORMAL) while True: # stay in this loop till the user presses 'q' ch = scr.getch() if ch == ord('q'): curses.wrapper(main)
    • 669. 604 import xml.etree.ElementTree as ET tree = ET.parse("yourXMLfile.xml") root = tree.getroot() for child in root: print(child.tag, child.attrib) print(root[0][1].text) print(root.findall("myTag")) print(root[0].find("myOtherTag")) import xml.etree.ElementTree as ET tree = ET.parse('sample.xml') root=tree.getroot() element = root[0] #get first child of root element Capítulo 118: Manipulando XML Observaciones No todos los elementos de la entrada XML terminarán como elementos del árbol analizado. Actualmente, este módulo omite los comentarios XML, las instrucciones de procesamiento y las declaraciones de tipo de documento en la entrada. Sin embargo, los árboles construidos utilizando la API de este módulo en lugar de analizar a partir de texto XML pueden tener comentarios e instrucciones de procesamiento; Se incluirán al generar la salida XML. Examples Abriendo y leyendo usando un ElementTree Importe el objeto ElementTree, abra el archivo .xml relevante y obtenga la etiqueta raíz: Hay algunas maneras de buscar a través del árbol. Primero es por iteración: De lo contrario, puede hacer referencia a ubicaciones específicas como una lista: Para buscar etiquetas específicas por nombre, use .find o .findall : Modificar un archivo XML Importar módulo de árbol de elementos y abrir archivo xml, obtener un elemento xml El objeto elemento se puede manipular cambiando sus campos, agregando y modificando atributos, agregando y eliminando elementos secundarios
    • 670. 605 root.remove(element) tree.write('output.xml') import xml.etree.ElementTree as ET p=ET.Element('parent') c = ET.SubElement(p, 'child1') ET.dump(p) # Output will be like this #<parent><child1 /></parent> tree = ET.ElementTree(p) tree.write("output.xml") comment = ET.Comment('user comment') p.append(comment) #this comment will be appended to parent element Si desea eliminar un elemento use el método Element.remove () Método ElementTree.write () utilizado para generar un objeto xml en archivos xml. Crear y construir documentos XML Módulo de árbol de elementos de importación La función Element () se utiliza para crear elementos XML Función de elemento secundario () utilizada para crear subelementos a un elemento dado La función dump () se utiliza para volcar elementos xml. Si desea guardar en un archivo, cree un árbol xml con la función ElementTree () y guarde en un archivo con el método write () La función Comentario () se utiliza para insertar comentarios en un archivo xml. Abrir y leer archivos XML grandes utilizando iterparse (análisisincremental) A veces no queremos cargar el archivo XML completo para obtener la información que necesitamos. En estos casos, es útil poder cargar incrementalmente las secciones relevantes y luego eliminarlas cuando hayamos terminado. Con la función iterparse puede editar el árbol de element.set('attribute_name', 'attribute_value') #set the attribute to xml element element.text="string_text"
    • 671. 606 for event, elem in ET.iterparse("yourXMLfile.xml"): ... do something ... events=("start", "end", "start-ns", "end-ns") for event, elem in ET.iterparse("yourXMLfile.xml", events=events): ... do something ... for event, elem in ET.iterparse("yourXMLfile.xml", events=("start","end")): if elem.tag == "record_tag" and event == "end": print elem.text elem.clear() ... do something else ... <Catalog> <Books> <Book id="1" price="7.95"> <Title>Do Androids Dream of Electric Sheep?</Title> <Author>Philip K. Dick</Author> </Book> <Book id="5" price="5.95"> <Title>The Colour of Magic</Title> <Author>Terry Pratchett</Author> </Book> <Book id="7" price="6.95"> <Title>The Eye of The World</Title> <Author>Robert Jordan</Author> </Book> </Books> </Catalog> elementos que se almacena mientras se analiza el XML. Importe el objeto ElementTree: Abra el archivo .xml e itere sobre todos los elementos: Alternativamente, solo podemos buscar eventos específicos, como etiquetas de inicio / finalización o espacios de nombres. Si esta opción se omite (como anteriormente), solo se devuelven eventos "finales": Aquí está el ejemplo completo que muestra cómo borrar elementos del árbol en memoria cuando terminemos con ellos: Buscando el XML con XPath A partir de la versión 2.7, ElementTree tiene un mejor soporte para consultas XPath. XPath es una sintaxis que le permite navegar a través de un xml como SQL se utiliza para buscar a través de una base de datos. Tanto las funciones find y findall son compatibles con XPath. El siguiente XML se utilizará para este ejemplo. import xml.etree.ElementTree as ET
    • 672. 607 import xml.etree.cElementTree as ET tree = ET.parse('sample.xml') tree.findall('Books/Book') tree.find("Books/Book[Title='The Colour of Magic']") # always use '' in the right side of the comparison tree.find("Books/Book[@id='5']") # searches with xml attributes must have '@' before the name tree.find("Books/Book[2]") # indexes starts at 1, not 0 tree.find("Books/Book[last()]") # 'last' is the only xpath function allowed in ElementTree tree.findall(".//Author") #searches with // must use a relative path Buscando todos los libros: Buscando el libro con el título = 'El color de la magia': Buscando el libro con id = 5: Busca el segundo libro: Buscar el último libro: Búsqueda de todos los autores:
    • 673. 608 import cmath z = 2+3j # A complex number cmath.phase(z) # 0.982793723247329 cmath.polar(z) # (3.605551275463989, 0.982793723247329) cmath.rect(2, cmath.pi/2) # (0+2j) cmath.exp(z) # (-7.315110094901103+1.0427436562359045j) cmath.log(z) # (1.2824746787307684+0.982793723247329j) cmath.log10(-100) # (2+1.3643763538418412j) cmath.sqrt(z) # (1.6741492280355401+0.8959774761298381j) cmath.sin(z) # (9.15449914691143-4.168906959966565j) cmath.cos(z) # (-4.189625690968807-9.109227893755337j) cmath.tan(z) # (-0.003764025641504249+1.00323862735361j) cmath.asin(z) # (0.5706527843210994+1.9833870299165355j) cmath.acos(z) # (1.0001435424737972-1.9833870299165355j) cmath.atan(z) # (1.4099210495965755+0.22907268296853878j) cmath.sin(z)**2 + cmath.cos(z)**2 # (1+0j) Capítulo 119: Matemáticas complejas Sintaxis • cmath.rect (AbsoluteValue, Phase) Examples Aritmética compleja avanzada El módulo cmath incluye funciones adicionales para usar números complejos. Este módulo puede calcular la fase de un número complejo, en radianes: Permite la conversión entre las representaciones cartesianas (rectangulares) y polares de números complejos: El módulo contiene la versión compleja de • Funciones exponenciales y logarítmicas (como es habitual, log es el logaritmo natural y log10 el logaritmo decimal): • Raíces cuadradas: • Funciones trigonométricas y sus inversos:
    • 674. 609 cmath.sinh(z) # (-3.59056458998578+0.5309210862485197j) cmath.cosh(z) # (-3.7245455049153224+0.5118225699873846j) cmath.tanh(z) # (0.965385879022133-0.009884375038322495j) cmath.asinh(z) # (0.5706527843210994+1.9833870299165355j) cmath.acosh(z) # (1.9833870299165355+1.0001435424737972j) cmath.atanh(z) # (0.14694666622552977+1.3389725222944935j) cmath.cosh(z)**2 - cmath.sin(z)**2 # (1+0j) cmath.cosh((0+1j)*z) - cmath.cos(z) # 0j z = 2+3j # A complex number w = 1-7j # Another complex number z + w # (3-4j) z - w # (1+10j) z * w # (23-11j) z / w # (-0.38+0.34j) z**3 # (-46+9j) z.real # 2.0 z.imag # 3.0 abs(z) # 3.605551275463989 z.conjugate() # (2-3j) • Funciones hiperbólicas y sus inversos: Aritmética compleja básica Python ha incorporado soporte para aritmética compleja. La unidad imaginaria se denota por j : Los números complejos pueden sumarse, restarse, multiplicarse, dividirse y exponerse: Python también puede extraer las partes reales e imaginarias de números complejos, y calcular su valor absoluto y su conjugado:
    • 675. 610 # Imports the Flask class from flask import Flask # Creates an app and checks if its the main or imported app = Flask( name ) # Specifies what URL triggers hello_world() @app.route('/') # The function run on the index route def hello_world(): # Returns the text to be displayed return "Hello World!" # If this script isn't an import if name == " main ": # Run the app until stopped app.run() Capítulo 120: Matraz Introducción Flask es un marco micro web de Python que se utiliza para ejecutar los principales sitios web, incluidos Pintrest, Twilio y Linkedin. Este tema explica y demuestra la variedad de características que Flask ofrece para el desarrollo web tanto en la parte frontal como en la posterior. Sintaxis • @ app.route ("/ urlpath", métodos = ["GET", "POST", "DELETE", "PUTS", "HEAD", "OPTIONS"]) • @ app.route ("/ urlpath / <param>", methods = ["GET", "POST", "DELETE", "PUTS", "HEAD", "OPTIONS"]) Examples Los basicos El siguiente ejemplo es un ejemplo de un servidor básico: La ejecución de este script (con todas las dependencias correctas instaladas) debe iniciar un servidor local. El host es 127.0.0.1 comúnmente conocido como localhost . Este servidor se ejecuta por defecto en el puerto 5000 .Para acceder a suservidor web, abra un navegador web e ingrese la URL localhost:5000 o 127.0.0.1:5000 (no hay diferencia). Actualmente, solo su computadora puede acceder al servidor web. app.run() tiene tres parámetros, host , puerto y depuración . El host es 127.0.0.1 forma predeterminada, pero si lo establece en 0.0.0.0 podrá acceder a su servidor web desde cualquier dispositivo de su red usando su dirección IP privada en la URL. el puerto es por defecto 5000, pero si el parámetro se establece en el puerto 80 , los usuarios no necesitarán especificar un
    • 676. 611 if name == " main ": app.run(host="0.0.0.0", port=80, debug=True) @app.route("/") def index(): return "You went to www.example.com" @app.route("/about") def about(): return "You went to www.example.com/about" @app.route("/users/guido-van-rossum") return "You went to www.example.com/guido-van-rossum" @app.route("/users/<username>") def profile(username): return "Welcome to the profile of " + username cities = ["OMAHA", "MELBOURNE", "NEPAL", "STUTTGART", "LIMA", "CAIRO", "SHANGHAI"] @app.route("/stores/locations/<city>") def storefronts(city): if city in cities: return "Yes! We are located in " + city else: return "No. We are not located in " + city número de puerto ya que los navegadores usan el puerto 80 de manera predeterminada. En cuanto a la opción de depuración, durante el proceso de desarrollo (nunca en producción), ayuda a establecer este parámetro en Verdadero, ya que su servidor se reiniciará cuando se realicen cambios en su proyecto de Flask. URL de enrutamiento Con Flask, el enrutamiento de URL se realiza tradicionalmente con decoradores. Estos decoradores se pueden usar para enrutamiento estático, así como enrutamiento de URL con parámetros. Para el siguiente ejemplo, imagine que este script de Flask está ejecutando el sitio web www.example.com . Con esa última ruta, puede ver que dada una URL con / users / y el nombre del perfil, podríamos devolver un perfil. Como sería horriblemente ineficiente y desordenado incluir una @app.route() para cada usuario, Flask ofrece tomar parámetros de la URL: Métodos HTTP Los dos métodos HTTP más comunes son GET y POST . Flask puede ejecutar un código diferente de la misma URL dependiendo del método HTTP utilizado. Por ejemplo, en un servicio web con cuentas, es más conveniente enrutar la página de inicio de sesión y el proceso de inicio de sesión a través de la misma URL. Una solicitud GET, la misma que se realiza al abrir una URL en su navegador, debe mostrar el formulario de inicio de sesión, mientras que una solicitud POST (que lleva datos de inicio de sesión) debe procesarse por separado. También se crea una ruta
    • 677. 612 @app.route("/login", methods=["GET"]) def login_form(): return "This is the login form" @app.route("/login", methods=["POST"]) def login_auth(): return "Processing your data" @app.route("/login", methods=["DELETE", "PUT"]) def deny(): return "This method is not allowed" from flask import request @app.route("/login", methods=["GET", "POST", "DELETE", "PUT"]) def login(): if request.method == "DELETE" or request.method == "PUT": return "This method is not allowed" elif request.method == "GET": return "This is the login forum" elif request.method == "POST": return "Processing your data" from flask import request @app.route("/login", methods=["GET", "POST", "DELETE", "PUT"]) def login(): if request.method == "DELETE" or request.method == "PUT": return "This method is not allowed" elif request.method == "GET": return "This is the login forum" elif request.method == "POST": return "Username was " + request.form["username"] + " and password was " + request.form["password"] from flask import Flask from flask import render_template app = Flask( name ) @app.route("/about") def about(): return render_template("about-us.html") if name == " main ": app.run(host="0.0.0.0", port=80, debug=True) para manejar el método DELETE y PUT HTTP. Para simplificar un poco el código, podemos importar el paquete de request desde el matraz. Para recuperar datos de la solicitud POST, debemos usar el paquete de request : Archivos y plantillas EnlugardeescribirnuestromarcadoHTMLenlasdeclaracionesdedevolución,podemos usarla función render_template() : Esto utilizará nuestro archivo de plantilla about-us.html . Para garantizar que nuestra aplicación
    • 678. 613 - application.py /templates - about-us.html - login-form.html /static /styles - about-style.css - login-style.css /scripts - about-script.js - login-script.js @app.route("/users/<username>) def profile(username): joinedDate = get_joined_date(username) # This function's code is irrelevant awards = get_awards(username) # This function's code is irrelevant # The joinDate is a string and awards is an array of strings return render_template("profile.html", username=username, joinDate=joinDate, awards=awards) <!DOCTYPE html> <html> <head> # if username <title>Profile of {{ username }}</title> # else <title>No User Found</title> # endif <head> <body> pueda encontrar este archivo, debemos organizar nuestro directorio en el siguiente formato: Lo más importante, las referencias a estos archivos en el HTML deben tener este aspecto: <link rel="stylesheet" type="text/css", href="{{url_for('static', filename='styles/aboutstyle.css')}}"> que dirigirá la aplicación para buscar about-style.css en la carpeta de estilos debajo de la carpeta estática. El mismo formato de ruta se aplica a todas las referencias a imágenes, estilos, scripts o archivos. Jinja Templando Al igual que Meteor.js, Flask se integra bien con los servicios de plantillas front-end. Frasco utiliza por defecto la plantilla de jinja. Las plantillas permiten que se utilicen pequeños fragmentos de código en el archivo HTML, como condicionales o bucles. Cuando representamos una plantilla, todos los parámetros más allá del nombre del archivo de la plantilla se pasan al servicio de plantillas HTML. La siguiente ruta pasará el nombre de usuario y la fecha de ingreso (desde una función en otro lugar) al HTML. Cuando esta plantilla se representa, puede usar las variables que se le pasan desde la función render_template() . Aquí están los contenidos deprofile.html :
    • 679. 614 from flask import request @app.route("/api/users/<username>") def user_api(username): try: token = request.args.get("key") if key == "pA55w0Rd": if isUser(username): # The code of this method is irrelevant joined = joinDate(username) # The code of this method is irrelevant return "User " + username + " joined on " + joined else: return "User not found" else: return "Incorrect key" # If there is no key parameter except KeyError: Los siguientes delimitadores se utilizan para diferentes interpretaciones: • {% ... %} denota una declaración • {{... }} denota una expresión donde se emite una plantilla • {# ... #} denota un comentario (no incluido en la salida de la plantilla) • {# ... ## implica que el resto de la línea debe interpretarse como una declaración El objeto de solicitud El objeto de request proporciona información sobre la solicitud que se realizó a la ruta. Para utilizar este objeto, debe importarse desde el módulo del matraz: Parámetros de URL En ejemplos anteriores se utilizaron request.method y request.form , sin embargo, también podemos usarla propiedad request.args pararecuperar un diccionariodelas claves / valoresen los parámetros de laURL. {% if username %} <h1>{{ username }} joined on the date {{ date }}</h1> {% if len(awards) > 0 %} <h3>{{ username }} has the following awards:</h3> <ul> {% for award in awards %} <li>{{award}}</li> {% endfor %} </ul> {% else %} <h3>{{ username }} has no awards</h3> {% endif %} {% else %} <h1>No user was found under that username</h1> {% endif %} {# This is a comment and doesn't affect the output #} </body> </html>
    • 680. 615 @app.route("/upload", methods=["POST"]) def upload_file(): f = request.files["wordlist-upload"] f.save("/var/www/uploads/" + f.filename) # Store with the original filename @app.route("/home") def home(): try: username = request.cookies.get("username") return "Your stored username is " + username except KeyError: return "No username cookies was found") Para autenticarse correctamente en este contexto, se necesitaría la siguiente URL (reemplazando el nombre de usuario con cualquier nombre de usuario): www.example.com/api/users/guido-van-rossum?key=pa55w0Rd Cargas de archivos Si la carga de un archivo era parte del formulario enviado en una solicitud POST, los archivos se pueden manejar usando el objeto de request : Galletas La solicitud también puede incluir cookies en un diccionario similar a los parámetros de URL. return "No key provided"
    • 681. 616 lst=[[1,2,3],[4,5,6],[7,8,9]] print (lst[0]) #output: [1, 2, 3] print (lst[1]) #output: [4, 5, 6] print (lst[2]) #output: [7, 8, 9] print (lst[0][0]) #output: 1 print (lst[0][1]) #output: 2 lst[0]=[10,11,12] lst[1][2]=15 Capítulo 121: Matrices multidimensionales Examples Listas en listas Una buena manera de visualizar una matriz 2D es como una lista de listas. Algo como esto: aquílalistaexternalsttienetres cosasenél. cadaunadeesascosasesotralista:laprimeraes: [1,2,3] , la segunda es: [4,5,6] y la tercera es: [7,8,9] . Puede acceder a estas listas de la misma manera que accedería a otro elemento de una lista, como este: A continuación, puede acceder a los diferentes elementos en cada una de esas listas de la misma manera: Aquí el primer número dentro de los corchetes [] significa obtener la lista en esa posición. En el ejemplo anterior, usamos el número 0 para obtener la lista en la posición 0, que es [1,2,3] . El segundo conjunto de []corchetes significa obtener el elemento en esa posiciónde lalista interna. En este caso, utilizamos 0 y 1 la posición 0 en la lista que obtuvimos es el número 1 y en la 1ª posición es 2 También puede establecer valores dentro de estas listas de la misma manera: Ahora la lista es [[10,11,12],[4,5,6],[7,8,9]] . En este ejemplo, cambiamos toda la primera lista para que sea una lista completamente nueva.
    • 682. 617 [[[111,112,113],[121,122,123],[131,132,133]],\ [[211,212,213],[221,222,223],[231,232,233]],\ [[311,312,313],[321,322,323],[331,332,333]]] myarray[1]=new_n-1_d_list myarray[2][1]=new_n-2_d_list myarray[1][0][2]=new_n-3_d_list #or a single number if you're dealing with 3D arrays etc. Ahora la lista es [[10,11,12],[4,5,15],[7,8,9]] . En este ejemplo, cambiamos un solo elemento dentro de una de las listas internas. Primero ingresamos a la lista en la posición 1 y cambiamos el elemento dentro de la posición 2, que era 6 ahora es 15. Listas en listas en listas en ... Este comportamiento puede ser extendido. Aquí hay una matriz tridimensional: [[[111,112,113],[121,122,123],[131,132,133]],[[211,212,213],[221,222,223],[231,232,233]],[[311,312,313 Como probablemente sea obvio, esto se vuelve un poco difícil de leer. Usa barras invertidas para dividir las diferentes dimensiones: Al anidar las listas como esta, puede extenderse a dimensiones arbitrariamente altas. El acceso es similar a las matrices 2D: Y la edición también es similar: print(myarray) print(myarray[1]) print(myarray[2][1]) print(myarray[1][0][2]) etc.
    • 683. 618 Dummy = type('OtherDummy', (), dict(x=1)) Dummy. class # <type 'type'> Dummy(). class . class # <type 'type'> class mytype(type): def init (cls, name, bases, dict): # call the base initializer type. init (cls, name, bases, dict) # perform custom initialization... cls. custom_attribute = 2 MyDummy = mytype('MyDummy', (), dict(x=2)) MyDummy. class # <class ' main .mytype'> MyDummy(). class . class # <class ' main .mytype'> MyDummy. custom_attribute # 2 Capítulo 122: Metaclases Introducción Las metaclases le permiten modificar profundamente el comportamiento de las clases de Python (en términos de cómo se definen, se crean instancias, se accede a ellas, y más) al reemplazar la metaclase de type que las nuevas clases usan de forma predeterminada. Observaciones Al diseñar su arquitectura, tenga en cuenta que muchas cosas que se pueden lograr con las metaclases también se pueden lograr utilizando una semántica más simple: • La herencia tradicional es a menudo más que suficiente. • Los decoradores de clase pueden combinar la funcionalidad en una clase con un enfoque ad hoc. • Python 3.6 introduce init_subclass () que permite a una clase participar en la creación de su subclase. Examples Metaclases basicas Cuando se llama a type con tres argumentos, se comporta como la clase (meta) que es y crea una nueva instancia, es decir. produce una nueva clase / tipo. Es posible subclase type para crear una metaclase personalizado. Ahora, tenemos una nueva metaclase mytype personalizada que se puede utilizar para crear clases de la misma manera que el type .
    • 684. 619 >>> class Foo(object): ... pass >>> type(Foo) type class MyDummy(object): metaclass = mytype type(MyDummy) # <class ' main .mytype'> class MyDummy(metaclass=mytype): pass type(MyDummy) # <class ' main .mytype'> class SingletonType(type): def call (cls, *args, **kwargs): try: return cls. instance except AttributeError: cls. instance = super(SingletonType, cls). call (*args, **kwargs) return cls. instance class MySingleton(object): metaclass = SingletonType Cuando creamos una nueva clase utilizando la palabra clave de class la metaclase se elige de forma predeterminada en función de las clases básicas. En el ejemplo anterior, la única clase de base es el object por lo que nuestra metaclase será el tipo de object , que es el type . Es posible anular el valor predeterminado, sin embargo, depende de si usamos Python 2 o Python3: Python 2.x 2.7 Un atributo de nivel de clase especial metaclass se puede usar para especificar la metaclase. Python 3.x 3.0 Un argumento especial de palabra clave de metaclass especifica la metaclase. Cualquierargumentodepalabraclave(excepto metaclass)enladeclaración declasesepasaráa lametaclase.Así,laclass MyDummy(metaclass=mytype, x=2)pasaráx=2 comoargumentodepalabra clave al constructor mytype. Lea esta descripción detallada de las meta-clases de python para más detalles. Singletons utilizando metaclases Un singleton es un patrón que restringe la creación de instancias de una clase a una instancia / objeto. Para más información sobre los patrones de diseño singleton de python, consulte aquí . Python 2.x 2.7
    • 685. 620 class MySingleton(metaclass=SingletonType): pass MySingleton() is MySingleton() # True, only one instantiation occurs class MyClass(object): metaclass = SomeMetaclass class MyClass(metaclass=SomeMetaclass): pass import six class MyClass(six.with_metaclass(SomeMetaclass)): pass class VerboseMetaclass(type): def new (cls, class_name, class_parents, class_dict): print("Creating class ", class_name) new_class = super(). new (cls, class_name, class_parents, class_dict) return new_class class Spam(metaclass=VerboseMetaclass): def eggs(self): print("[insert example string here]") s = Spam() s.eggs() Python 3.x 3.0 Usando una metaclase Sintaxis de metaclase Python 2.x 2.7 Python 3.x 3.0 Compatibilidad de Python 2 y 3 con six Funcionalidad personalizada con metaclases. La funcionalidad de las metaclases se puede cambiar de modo que cada vez que se construye una clase, se imprime una cadena en la salida estándar o se lanza una excepción. Esta metaclase imprimirá el nombre de la clase que se está construyendo. Puedes usar la metaclase así:
    • 686. 621 Creating class Spam [insert example string here] >>> type(5) <type 'int'> >>> type(str) <type 'type'> >>> type([1, 2, 3]) <type 'list'> >>> class C(object): ... pass ... >>> type(C) <type 'type'> class SimplestMetaclass(type): pass class MyClass(object): metaclass = SimplestMetaclass >>> type(MyClass) <class ' main .SimplestMetaclass'> La salida estándar será: Introducción a las metaclases ¿Qué es una metaclase? En Python, todo es un objeto: enteros, cadenas, listas, incluso las funciones y las clases en sí son objetos. Y cada objeto es una instancia de una clase. Para verificar la clase de un objeto x, se puede llamar al type(x) , entonces: La mayoría de las clases en python son instancias de type . type sí mismo es también una clase. Tales clases cuyas instancias son también clases se llaman metaclases. La metaclase mas simple OK, entonces ya hay una metaclase en Python: type . ¿Podemos crear otro? Eso no agrega ninguna funcionalidad, pero es una nueva metaclase, vea que MyClass ahora es una instancia de SimplestMetaclass: Una metaclase que hace algo Una metaclase el que hace algo por lo general prevalece sobre type 's new , modificar algunas
    • 687. 622 class AnotherMetaclass(type): def new (cls, name, parents, dct): # cls is this class # name is the name of the class to be created # parents is the list of the class's parent classes # dct is the list of class's attributes (methods, static variables) # here all of the attributes can be modified before creating the class, e.g. dct['x'] = 8 # now the class will have a static variable x = 8 # return value is the new class. super will take care of that return super(AnotherMetaclass, cls). new (cls, name, parents, dct) >>> type(1) int >>> class Foo(object): ... pass ... >>> bar = Foo() >>> type(bar) Foo >>> type(Foo) type >>> type(type) type propiedades de la clase que se creen, antes de llamar al original new que crea la clase: La metaclase por defecto. Es posible que hayas oído que todo en Python es un objeto. Es cierto, y todos los objetos tienen una clase: El literal 1 es una instancia de int . Vamos a declarar una clase: Ahora vamos a instanciarlo: ¿Cuál es la clase de bar ? Agradable, el bar es una instancia de Foo . Pero, ¿cuál es la clase de Foo sí? Ok, Foo sí es una instancia de type . ¿Qué tal el type sí mismo? Entonces, ¿qué es una metaclase? Por ahora, simulemos que es solo un nombre elegante para la clase de una clase. Para llevar:
    • 688. 623 • Todo es un objeto en Python, así que todo tiene una clase. • La clase de una clase se llama metaclase. • La metaclase predeterminada es de type y, con mucho, es la metaclase más común. Pero ¿por qué debería saber acerca de las metaclases? Bueno, Python en sí mismo es bastante "hackeable", y el concepto de metaclase es importante si estás haciendo cosas avanzadas como meta-programación o si quieres controlar cómo se inicializan tus clases.
    • 689. 624 class Parent(object): def introduce(self): print("Hello!") def print_name(self): print("Parent") class Child(Parent): def print_name(self): print("Child") p = Parent() c = Child() p.introduce() p.print_name() c.introduce() c.print_name() $ python basic_override.py Hello! Parent Hello! Child Capítulo 123: Método Anulando Examples Método básico anulando Este es un ejemplo de anulaciónbásica enPython (por motivosdeclaridady compatibilidadcon Python 2 y 3, usando una nueva clase de estilo e print con() ): Cuando el Child se crea la clase, que hereda los métodos de la Parent clase. Esto significa que cualquier método que tenga la clase padre, la clase hija también tendrá. En el ejemplo, la introduce se define para la clase Child porque está definida para Parent , a pesar de no estar definida explícitamente en la definición de clase de Child . En este ejemplo, la anulación se produce cuando Child define su propio método print_name .Si este método no fue declarado, entonces c.print_name() habría impreso "Parent" . Sin embargo, Child ha anulado el Parent definición 's de print_name , y por eso ahora al llamar c.print_name() , la palabra "Child" se imprime.
    • 690. 625 Capítulo 124: Métodos de cuerda Sintaxis • str.capitalize () -> str • str.casefold () -> str [solo para Python> 3.3] • str.center (ancho [, fillchar]) -> str • str.count (sub [, start [, end]]) -> int • str.decode (encoding = "utf-8" [, errores]) -> unicode [solo en Python 2.x] • str.encode (codificación = "utf-8", errores = "estricto") -> bytes • str.endswith (sufijo [, inicio [, final]]) -> bool • str.expandtabs (tabsize = 8) -> str • str.find (sub [, start [, end]]) -> int • str.format (* args, ** kwargs) -> str • str.format_map (mapeo) -> str • str.index (sub [, start [, end]]) -> int • str.isalnum () -> bool • str.isalpha () -> bool • str.isdecimal () -> bool • str.isdigit () -> bool • identificador str. () -> bool • str.islower () -> bool • str.isnumeric () -> bool • str.isprintable () -> bool • str.isspace () -> bool • str.istitle () -> bool • str.isupper () -> bool • str.join (iterable) -> str • str.ljust (ancho [, fillchar]) -> str • str.lower () -> str • str.lstrip ([caracteres]) -> str • str.maketrans estático (x [, y [, z]]) • str.partition (sep) -> (head, sep, tail) • str.replace (antiguo, nuevo [, cuenta]) -> str • str.rfind (sub [, start [, end]]) -> int • str.rindex (sub [, inicio [, final]]) -> int • str.rjust (ancho [, fillchar]) -> str • str.rpartition (sep) -> (head, sep, tail) • str.rsplit (sep = None, maxsplit = -1) -> lista de cadenas • str.rstrip ([caracteres]) -> str • str.split (sep = None, maxsplit = -1) -> lista de cadenas • str.splitlines ([keepends]) -> lista de cadenas • str.startswith (prefijo [, inicio [, final]]) -> libro • str.strip ([caracteres]) -> str
    • 691. 626 "XßΣ".casefold() # 'xssσ' "XßΣ".lower() # 'xßς' • str.swapcase () -> str • str.title () -> str • str.translate (tabla) -> str • str.upper () -> str • str.zfill (ancho) -> str Observaciones Los objetos de cadena son inmutables, lo que significa que no se pueden modificar en su lugar como lo hace una lista. Debido a esto, los métodos en el tipo incorporado str siempre devuelven un nuevo objeto str , que contiene el resultado de la llamada al método. Examples Cambiar la capitalización de una cadena El tipo de cadena de Python proporciona muchas funciones que actúan sobre la capitalización de una cadena. Éstos incluyen : • str.casefold • str.upper • str.lower • str.capitalize • str.title • str.swapcase Con cadenas de Unicode (el valor predeterminado en Python 3), estas operaciones no son asignaciones 1: 1 o reversibles. La mayoría de estas operaciones están destinadas a fines de visualización, en lugar de a la normalización. Python 3.x 3.3 str.casefold() str.casefold crea una cadena en minúsculas que es adecuada para comparaciones que no distinguen entre mayúsculas y minúsculas. Esto es más agresivo que str.lower y puede modificar cadenas que ya están en minúsculas o hacer que las cadenas crezcan en longitud, y no está diseñada para fines de visualización. Las transformaciones que tienen lugar en Casefolding están definidas por Unicode Consortium en el archivo CaseFolding.txt en su sitio web.
    • 692. 627 "This is a 'string'.".upper() # "THIS IS A'STRING'." "This IS a 'string'.".lower() # "this is a 'string'." "this Is A 'String'.".capitalize() # Capitalizes the first character and lowercases all others # "This is a 'string'." "this Is a 'String'".title() # "This Is A'String'" "this iS A STRiNG".swapcase() #Swaps case of each character # "THIS Is a strIng" str.upper() str.uppertoma todos los caracteresde unacadenaylos convierte asu equivalente en mayúsculas, por ejemplo: str.lower() str.lower hace locontrario;toma todos los caracteres deunacadenaylos conviertea su equivalente en minúsculas: str.capitalize() str.capitalize devuelve una versión en mayúscula de la cadena, es decir, hace que el primer carácter tenga mayúsculas y el resto sea inferior: str.title() str.title devuelve el título de la versión de la cadena, es decir, todas las letras al principio de una palabra están en mayúsculas y las demás enminúsculas: str.swapcase() str.swapcase devuelve un nuevo objeto de cadena en el que todos los caracteres en minúsculas se cambian a mayúsculas y todos los caracteres en mayúsculas a inferiores: Uso como métodos de clase str Vale la pena señalar que estos métodos pueden llamarse en objetos de cadena (como se muestra arriba) o como un método de clase de la clase str (con una llamada explícita a str.upper , etc.)
    • 693. 628 map(str.upper,["These","are","some","'strings'"]) # ['THESE', 'ARE', 'SOME', "'STRINGS'"] >>>" ".split() [] ['This','is','a','sentence.'] >>> " Thisis a sentence. ".split() >>>"Thisis a sentence.".split() ['This', 'is', 'a', 'sentence.'] ['', 'This', 'is', '', '', '', 'a', 'sentence.', '', ''] >>>"Thisis asentence.".split('e') ['This is a s', 'nt', 'nc', '.'] >>>"Thisisasentence.".split('en') ['This is a s', 't','ce.'] >>> " Thisis a sentence. ".split(' ') >>>"Thisis a sentence.".split(' ') ['This', 'is', 'a', 'sentence.'] >>> "Earth,Stars,Sun,Moon".split(',') ['Earth', 'Stars', 'Sun', 'Moon'] Esto es más útil cuando se aplica uno de estos métodos a muchas cadenas a la vez, por ejemplo, una función de map . Dividir una cadena basada en un delimitador en una lista de cadenas str.split(sep=None, maxsplit=-1) str.split toma una cadena y devuelve una lista de subcadenas de la cadena original. El comportamiento difiere dependiendo de si el argumento sep se proporciona u omite. Si no se proporciona sep , o es None , entonces la división tiene lugar donde hay espacios en blanco.Sinembargo,los espacios en blanco inicialesy finales seignoran,y varios caracteresde espacios en blanco consecutivos se tratan igual que un solo espacio en blanco: El parámetro sep se puede usar para definir unacadena delimitadora. La cadena original se divide donde se produce la cadena delimitadora, y el propio delimitador se descarta. Varios delimitadores consecutivos no se tratan de la misma manera que una solaocurrencia, sino que hacen que se creen cadenas vacías. El valor predeterminado es dividir en cada aparición del delimitador, sin embargo, el parámetro maxsplit limita el número de divisiones que se producen. El valor predeterminado de -1 significa que no hay límite: str.upper("This is a 'string'") # "THIS IS A 'STRING'"
    • 694. 629 >>> "Thisis a sentence.".rsplit('e', maxsplit=1) ['This is a sentenc', '.'] >>>"Thisisasentence.".rsplit('e',maxsplit=2) ['This is a sent', 'nc', '.'] >>> "Make sure to foo your sentence.".replace('foo', 'spam') "Make sure to spam your sentence." >>> "It can foo multiple examples of foo if you want.".replace('foo', 'spam') "It can spam multiple examples of spam if you want." str.rsplit(sep=None, maxsplit=-1) str.rsplit ("división derecha") difiere de str.split ("división izquierda") cuando se especifica maxsplit . La división comienza al final de la cadena en lugar de al principio: Nota : Python especifica el número máximo de divisiones realizadas, mientras que la mayoría de los otros lenguajes de programación especifican el número máximo de subcadenas creadas. Esto puede crear confusión al portar o comparar código. Reemplace todas las ocurrencias de una subcadena por otra subcadena El tipo str dePython también tiene un método para reemplazarlas ocurrencias de una subcadena con otra subcadena en una cadena dada. Para casos más exigentes, uno puede usar re.sub . str.replace(old, new[, count]) : str.replace toma dos argumentos old y new que contiene el old sub-secuencia que va a ser reemplazado por el new sub-secuencia.El count argumentos opcional especifica el número de reemplazos que se realizarán: Por ejemplo, para reemplazar 'foo' con 'spam' en la siguiente cadena, podemos llamar a str.replace con old = 'foo' y new = 'spam' : Si la cadena dada contiene múltiples ejemplos que coinciden con el old argumento, todas las apariciones se reemplazan por el valor suministrado en new : >>> "This is a sentence.".split('e', maxsplit=0) ['This is a sentence.'] >>> "This is a sentence.".split('e', maxsplit=1) ['This is a s', 'ntence.'] >>> "This is a sentence.".split('e', maxsplit=2) ['This is a s', 'nt', 'nce.'] >>>"Thisisasentence.".split('e',maxsplit=-1) ['This is a s', 'nt', 'nc', '.']
    • 695. 630 >>> """It can foo multiple examples of foo if you want, \ ... or you can limit the foo with the third argument.""".replace('foo', 'spam', 1) 'It can spam multiple examples of foo if you want, or you can limit the foo with the third argument.' "10 1.5 foo ['a', 1, 2] {'a': 1, 2: 'foo'}" >>> "{} {} {} {} {}".format(i, f, s, l, d) >>> str.format("{} {} {} {} {}", i, f, s, l, d) >>> "{0} {1} {2} {3} {4}".format(i, f, s, l, d) >>> "{0:d} {1:0.1f} {2} {3!r} {4!r}".format(i, f, s, l, d) >>> "{i:d} {f:0.1f} {s} {l!r} {d!r}".format(i=i, f=f, s=s, l=l, d=d) >>> f"{i} {f} {s} {l} {d}" >>> f"{i:d} {f:0.1f} {s} {l!r} {d!r}" "%d %0.1f %s %r %r" % (i, f, s, l, d) "%(i)d %(f)0.1f %(s)s %(l)r %(d)r" % dict(i=i, f=f, s=s, l=l, d=d) A menos que, por supuesto, proporcionemos un valor para el count .En este caso, las ocurrencias de count serán reemplazadas: str.format y f-strings: formatea valores en una cadena Python proporciona interpolación de cadenas y funcionalidad de formato a través de la función str.format , introducida en laversión 2.6 y f-cadenas introducidas en la versión3.6. Dadas las siguientes variables: Las siguientes afirmaciones son todas equivalentes Para referencia, Python también admite calificadores de estilo C para el formato de cadenas. Los ejemplos a continuación son equivalentes a los anteriores, pero se prefieren las versiones de str.format debido a los beneficios en flexibilidad, consistencia de notación y extensibilidad: Lasllavesqueseusanparalainterpolación enstr.format destr.format tambiénsepueden numerar para reducirla duplicación al formatear cadenas.Por ejemplo, los siguientes son equivalentes: i = 10 f = 1.5 s = "foo" l = ['a', 1, 2] d = {'a': 1, 2: 'foo'}
    • 696. 631 >>> "I am from {}. I love cupcakes from {}!".format("Australia", "Australia") >>> "I am from {0}. I love cupcakes from {0}!".format("Australia") "{'a': 5, 'b': 6}" >>> "{{'{}': {}, '{}': {}}}".format("a", 5, "b", 6) >>> f"{{'{'a'}': {5}, '{'b'}': {6}}" >>> s = "She sells seashells by the seashore." >>> s.count("sh") 2 >>> s.count("se") 3 >>> s.count("sea") 2 >>> s.count("seashells") 1 >>> s.count("sea", start) 1 Si bien la documentación oficial de Python es, como es habitual, lo suficientemente exhaustiva, pyformat.info tiene un gran conjunto de ejemplos con explicaciones detalladas. Además, los caracteres { y } pueden escaparse utilizando corchetes dobles: Consulte Formato de cadena para obtener información adicional. str.format() se propuso en PEP 3101 y f-strings en PEP 498 . Contando el número de veces que una subcadena aparece en una cadena Hayun métododisponible paracontar el númerodeapariciones deunastr.counten otracadena, str.count . str.count(sub[, start[, end]]) str.count devuelve unint indica el númerode apariciones nosuperpuestas delastr.count suben otracadena.Losargumentosopcionalesstartyendindicanelprincipioyelfinalenelquese realizará la búsqueda. De forma predeterminada, start =0 y end=len(str) significa que se buscará en toda la cadena: Al especificar un valor diferente para el start , al end , podemos obtener una búsqueda más localizada y contar, por ejemplo, si el start es igual a 13 la llamadaa: es equivalente a: "I am from Australia. I love cupcakes from Australia!"
    • 697. 632 >>> s = "This is a test string" >>> s.startswith("T") True >>>s.startswith("Thi") True >>> s.startswith("thi") False >>> s.startswith("is", 2) True >>> s.startswith(('This', 'That')) True >>> s.startswith(('ab', 'bc')) False >>> s = "this ends in a full stop." >>> s.endswith('.') True >>> s.endswith('!') False Prueba los caracteres iniciales y finales de una cadena. Para probar el principio y el final de una cadena dada en Python, uno puede usar los métodos str.startswith() y str.endswith() . str.startswith(prefix[, start[, end]]) Como su nombre lo indica, str.startswith se usa para probar si una cadena dada comienza con los caracteres dados en el prefix. Los argumentos opcionales de start y end especifican los puntos de inicio y finalización a partir de los cuales se iniciarán y finalizarán las pruebas.En el siguiente ejemplo, al especificar un valor de inicio de 2 , se buscará nuestra cadena desde la posición 2 y después: Esto da como resultado True desde s[2] == 'i' y s[3] == 's' . También puede usar una tuple para verificar si comienza con alguna de un conjunto de cadenas str.endswith(prefix[, start[, end]]) str.endswith es exactamente similar a str.startswith la única diferencia es que busca caracteres finales y no caracteres iniciales. Por ejemplo, para probar si una cadena termina en una parada completa, se podría escribir: >>> t = s[start:] >>> t.count("sea") 1
    • 698. 633 >>> s.endswith('stop.') True >>> s.endswith('Stop.') False >>> s.endswith(('.', 'something')) True >>> s.endswith(('ab', 'bc')) False >>> "HeLLO WORLD".isupper() False >>> "HELLO WORLD".isupper() True >>> "".isupper() False al igual que con startswith se pueden usar más de un carácter como secuencia final: También puede usar una tuple para verificar si termina con cualquiera de un conjunto de cadenas Probando de qué está compuesta una cuerda EltipostrdePythontambiénpresentaunaseriedemétodosquesepuedenusarparaevaluarel contenido de una cadena. Estos son str.isalpha , str.isdigit , str.isalnum , str.isspace . La capitalización se puede probar con str.isupper , str.islower y str.istitle . str.isalpha str.isalpha no toma argumentos y devuelve True si todos los caracteres de una cadena dada son alfabéticos, por ejemplo: >>> "Hello World".isalpha() False >>> "Hello2World".isalpha() False >>> "HelloWorld!".isalpha() False >>> "HelloWorld".isalpha() True # contains a space # contains a number # contains punctuation Comouncasodeborde,lacadenavacíaseevalúacomoFalse cuandoseusacon"".isalpha() . str.isupper , str.islower , str.istitle Estos métodos prueban el uso de mayúsculas en una cadena dada. str.isupper es un método quedevuelve True si todos los caracteres de una cadena dada están en mayúsculas y False caso contrario.
    • 699. 634 isdecimal isdigit isnumeric >>> "Hello world".islower() False >>> "hello world".islower() True >>> "".islower() False >>>"hello world".istitle() False >>> "Hello world".istitle() False >>> "HelloWorld".istitle() True >>> "".istitle() False Alainversa, str.islower es un método que devuelve True si todos los caracteres de una cadena dada son minúsculas y Falsecontrario. str.istitle devuelve True si la cadena dada es un título cargado; es decir, cada palabra comienza con un carácter en mayúscula seguido de caracteres en minúscula. str.isdecimal , str.isdigit , str.isnumeric str.isdecimal devuelve si la cadena es una secuencia de dígitos decimales, adecuada para representar un número decimal. str.isdigit incluye dígitos que no están en una forma adecuada para representar un número decimal, como los dígitos en superíndice. str.isnumeric incluye cualquiervalor numérico,incluso si no son dígitos, como valores fuera del rango 0-9. 12345 True True True □2□□5 True True True ①²³□₅ False True True ⑩□ False False True Five False False False Bytestrings(bytesenPython3,strenPython2),soloadmiteisdigit,quesoloverificalosdígitos ASCII básicos. Al igual que con str.isalpha , la cadena vacía se evalúa como False . str.isalnum Esta es una combinación de str.isalpha y str.isnumeric , específicamente se evalúa como True si todos los caracteres en la cadena dada son alfanuméricos , es decir, consisten en caracteres
    • 700. 635 >>> "Hello2World".isalnum() True >>> "HelloWorld".isalnum() True >>> "2016".isalnum() True >>> "Hello World".isalnum() # contains whitespace False >>> "\t\r\n".isspace() True >>> " ".isspace() True >>> "".isspace() False >>> my_str = '' >>> my_str.isspace() False >>> my_str.isspace() or not my_str True >>> not my_str.strip() True str.translate(table[, deletechars]) alfabéticos o numéricos: str.isspace Se evalúa como True si la cadena solo contiene caracteres de espacio en blanco. A veces, una cadena se ve "vacía" pero no sabemos si es porque solo contiene espacios en blanco o ningún carácter. Para cubrir este caso necesitamos una prueba adicional. Pero la forma más corta de probar si una cadena está vacía o simplemente contiene caracteres de espacio en blanco es usar la strip (sin argumentos elimina todos los caracteres de espacio en blanco iniciales y finales) str.translate: Traducir caracteres en una cadena Python admite un método de translate en el tipo str que le permite especificar la tabla de traducción(utilizadaparalos reemplazos),asícomocualquier carácterquedebaeliminarseenel proceso.
    • 701. 636 >>> 'this syntax is very useful'.translate(None, 'aeiou') 'ths syntx s vry sfl' >>> translation_table = str.maketrans("aeiou", "12345") >>> my_string = "This is a string!" >>> translated = my_string.translate(translation_table) 'Th3s 3s 1 str3ng!' 'a line with leading and trailing space' >>> " a line with leading and trailing space ".strip() >>> ">>> a Python prompt".strip('> ') # strips '>' character and space character 'a Python prompt' Parámetro Descripción table Es una tabla de búsqueda que define la asignación de un carácter a otro. deletechars Una lista de caracteres que se eliminarán de la cadena. El método maketrans ( str.maketrans en Python 3 y string.maketrans en Python 2) le permite generar una tabla de traducción. El método de translate devuelve una cadena que es una copia traducida de la cadena original. Puede establecer el argumento de la table en None si solo necesita eliminar caracteres. Eliminar caracteres iniciales / finales no deseados de una cadena Se proporcionan tres métodos que ofrecen la posibilidad de eliminar los caracteres str.strip y finales de una cadena: str.strip , str.rstrip y str.lstrip . Los tres métodos tienen la misma firma y los tres devuelven un nuevo objeto de cadena con caracteres no deseados eliminados. str.strip([chars]) str.strip actúa sobre una cadena dada y elimina (elimina) cualquier carácter str.strip o final contenido en los charsargumento;Si no se suministranchars o es None , todos los caracteresde espacios en blanco se eliminan de forma predeterminada. Por ejemplo: Si se proporcionan chars , todos los caracteres contenidos en él se eliminan de la cadena, que se devuelve. Por ejemplo: str.rstrip([chars]) y str.lstrip([chars]) Estosmétodostienenunasemánticayargumentossimilaresconstr.strip() ,sudiferenciaradica en la dirección desde la que comienzan. str.rstrip() comienza desde el final de la cadena,
    • 702. 637 'spaciousstring ' >>> " spacious string ".rstrip() >>> "ß".lower() 'ß' >>> "ß".upper().lower() 'ss' >>> help(str.casefold) """ Help on method_descriptor: casefold(...) S.casefold() -> str Return a version of S suitable for caseless comparisons. """ >>> "ê" == " ê" mientrasquestr.lstrip() dividedesdeelprincipiodelacadena. Por ejemplo, usando str.rstrip : Mientras, usando str.lstrip : Comparaciones de cadenas insensibles al caso La comparación de cadenas en una forma que no distingue entre mayúsculas y minúsculas parece algo trivial, pero no lo es. Esta sección solo considera las cadenas Unicode (la predeterminada en Python 3). Tenga en cuenta que Python 2 puede tener debilidades sutiles en relación con Python 3; el manejo de Unicode de este último es mucho más completo. Loprimeroquehayquetener encuentaesquelasconversionesdeeliminacióndecasosen Unicode no son triviales. Hay texto para el que text.lower() != text.upper().lower() , como "ß" : Pero digamos que quería comparar "BUSSE" y "Buße" .Demonios, es probable que también quieras comparar "BUSSE" y "BU□E" iguales, esa es la forma de capital más nueva.La forma recomendada es usar casefold : Python 3.x 3.3 No se limite a usar lower . Si la casefold no está disponible, hacer .upper().lower() ayuda (pero solo un poco). Entoncesdeberíasconsiderarlosacentos.Si suprocesadordefuentesesbueno,probablemente piense que "ê" == "ê" , pero no lo hace: spacious string ".rstrip() spacious string' >>>" '
    • 703. 638 >>> import unicodedata >>> [unicodedata.name(char) for char in "ê"] ['LATINSMALLLETTEREWITHCIRCUMFLEX'] >>> [unicodedata.name(char) for char in "ê"] ['LATIN SMALL LETTER E', 'COMBINING CIRCUMFLEX ACCENT'] >>> unicodedata.normalize("NFKD", "ê") == unicodedata.normalize("NFKD", "ê") True import unicodedata def normalize_caseless(text): return unicodedata.normalize("NFKD", text.casefold()) def caseless_equal(left, right): return normalize_caseless(left) == normalize_caseless(right) >>> " ".join(["once","upon","a","time"]) "once upon a time" >>> "---".join(["once", "upon", "a", "time"]) "once---upon---a---time" >>> import string Esto es porque en realidad son La forma más sencilla de lidiar con esto es unicodedata.normalize . Probablemente desee utilizar la normalización NFKD , pero no dude en consultar la documentación. Entonces uno hace Para finalizar, aquí esto se expresa en funciones: Unir una lista de cadenas en una cadena Una cadena puede usarse como separador para unir una lista de cadenas en una sola cadena usando el método join() . Por ejemplo, puede crear una cadena en la que cada elemento de una lista esté separado por un espacio. El siguiente ejemplo separa los elementos de cadena con tres guiones. Constantes útiles del módulo de cadena El módulo de string de Python proporciona constantes para operaciones relacionadas con cadenas. Para usarlos, importa el módulo de string: False
    • 704. 639 >>> string.ascii_letters 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.ascii_lowercase 'abcdefghijklmnopqrstuvwxyz' >>> string.ascii_uppercase 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.digits '0123456789' >>> string.hexdigits '0123456789abcdefABCDEF' >>> string.octaldigits '01234567' string.ascii_letters : Concatenación de ascii_lowercase y ascii_uppercase : string.ascii_lowercase Contiene todos los caracteres ASCII en minúsculas: string.ascii_uppercase : Contiene todos los caracteres ASCII en mayúsculas: string.digits : Contiene todos los caracteres de dígitos decimales: string.hexdigits : Contiene todos los caracteres de dígitos hexadecimales: string.octaldigits : Contiene todos los caracteres de dígitos octales: string.punctuation :
    • 705. 640 >>> string.punctuation '!"#$%&\'()*+,- ./:;<=>?@[\\]^_`{|}~' >>> string.whitespace ' \t\n\r\x0b\x0c' >>> string.printable '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,- ./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c' >>> reversed('hello') <reversed object at 0x0000000000000000> >>>[charfor charin reversed('hello')] ['o', 'l', 'l', 'e', 'h'] >>> ''.join(reversed('hello')) 'olleh' >>> def reversed_string(main_string): ... return main_string[::-1] ... >>> reversed_string('hello') Contiene todos los caracteres que se consideran puntuación en la configuración regional de C : string.whitespace : Contiene todos los caracteres ASCII considerados espacios en blanco: Enelmododescript, print(string.whitespace) imprimiráloscaracteres reales,usestrpara obtener la cadena devueltaarriba. string.printable : Contiene todos los caracteres que se consideran imprimibles; una combinación de string.digits , string.ascii_letters , string.punctuation y string.whitespace . Invertir una cadena Una cadena puede revertirse usando la función reversed() incorporada, que toma una cadena y devuelve un iterador en orden inverso. reversed() puede envolverse en una llamada a ''.join() para crear una cadena desde el iterador. Si bienel uso de reversed()puede ser máslegible paralos usuariosnoiniciados dePython,el uso del corte extendido con un paso de -1es más rápido y conciso.Aquí, intenteimplementarlo como función:
    • 706. 641 interstates_lengths = { 5: (1381, 2222), } for road, length in interstates_lengths.items(): miles,kms = length print('{} -> {} mi. ({} km.)'.format(str(road).rjust(4), str(miles).ljust(4), str(kms).ljust(4))) # You get "© abc" encoded in UTF-8 from a file, network, or other data source s = '\xc2\xa9 abc' # s is a byte array, not a string of characters # Doesn't know the original was UTF-8 Justificar cuerdas Python proporciona funciones para justificar cadenas, permitiendo el relleno de texto para que la alineación de varias cadenas sea mucho más fácil. A continuación se muestra un ejemplo de str.ljust y str.rjust : 19: (63, 102), 40: (2555, 4112), 93: (189,305), 40 -> 2555 mi. (4112 km.) 19 -> 63 mi. (102 km.) 5 -> 1381 mi. (2222 km.) 93 -> 189 mi. (305 km.) ljust y rjust son muy similares. Ambos tienen un parámetro de width y un parámetro de fillchar opcional.Cualquier cadena creada porestas funcioneses al menos tanlarga comoel parámetro dewidthquesepasóalafunción.Silacadenaesmáslargaqueelwidthalread,nosetrunca.El argumentofillchar,quepordefectoeselcarácterdeespacio' 'debeserunsolocarácter,no una cadena de caracteresmúltiples. La función ljust el final de la cadena con la que se llama con el fillchar hasta que tenga una width caracteres.Lafunciónrjustelprincipiodelacadenadeuna manerasimilar.Porlotanto,ly renlosnombresdeestasfuncionesserefierenalladoenelquelacadenaoriginal,noelfillchar , está posicionado en la cadena de salida. Conversión entre str o bytes de datos y caracteres Unicode El contenido de los archivos y mensajes de la red puede representar caracteres codificados. A menudo necesitan ser convertidos a Unicode para una visualización adecuada. EnPython2,esposible quenecesiteconvertirdatosdestr acaracteresUnicode.Elvalor predeterminado('', "",etc.)esunacadenaASCII,concualquiervalorfueradelrangoASCII mostrado como valores escapados. Las cadenas Unicode sonu''(o u"" , etc.). Python 2.x 2.3 'olleh'
    • 707. 642 characters. # b'\xc2\xa9 abc' # str.encode produces a byte array, showing ASCII-range bytes as unescaped u.encode('utf-8') # You get from file or network "© abc" encoded in UTF-8 s = b'\xc2\xa9 abc' # s is a byte array, not characters # In Python 3, the default string literal is Unicode; byte array literals need a leading b s[0] # b'\xc2' - meaningless byte (without context such as an encoding) type(s) # bytes - now that byte arrays are explicit, Python can show that. u = s.decode('utf-8') # '© abc' on a Unicode terminal # bytes.decode converts a byte array to a string (which will, in Python 3, be Unicode) u[0] # '\u00a9' - Unicode Character 'COPYRIGHT SIGN' (U+00A9)'©' type(u) # str # The default string literal in Python 3 is UTF-8 Unicode >>> "foo" in "foo.baz.bar" True >>> "" in "test" EnPython3 es posiblequenecesiteconvertir matrices debytes (denominadas 'literal debyte')a cadenasdecaracteresUnicode.ElvalorpredeterminadoesahoraunacadenaUnicode,ylos literales de bytestring ahora debeningresarse como b'' , b"" ,etc. Unliteral de byte devolverá True a isinstance(some_val, byte) , asumiendo que some_val es una cadena que podría estar codificada como bytes. Python 3.x 3.0 Cadena contiene Python hace que sea extremadamente intuitivo comprobar si una cadena contiene una subcadena dada. Solo usa el operador in : Nota: probar una cadena vacía siempre resultará en True : characters # '\xc2\xa9 abc' # unicode.encode produces a string with escaped bytes for non-ASCII u.encode('utf-8') u = s.decode('utf-8') # u'\xa9 abc' # Now we have a Unicode string, which can be read as UTF-8 and printed properly # In Python 2, Unicode string literals need a leading u # str.decode converts a string which may contain escaped bytes to a Unicode string u[0] # u'\xa9' - Unicode Character 'COPYRIGHT SIGN' (U+00A9) '©' type(u) # unicode # Default form of string literals in Python 2 # '\xc2' - meaningless byte (without context such as an encoding) # str - even though it's not a useful one w/o having a known encoding s[0] type(s)
    • 708. 643 True
    • 709. 644 class A(object): # func: A user-defined function object # # Note that func is a function object when it's defined, # and an unbound method object when it'sretrieved. def func(self): pass # classMethod: A class method @classmethod def classMethod(self): pass class B(object): # unboundMeth: A unbound user-defined method object # # Parent.func is an unbound user-defined method object here, # because it's retrieved. unboundMeth = A.func a = A() b = B() print A.func # output: <unbound method A.func> print a.func # output: <bound method A.func of < main .A object at 0x10e9ab910>> print B.unboundMeth # output: <unbound method A.func> print b.unboundMeth # output: <unbound method A.func> print A.classMethod #output:<boundmethodtype.classMethodof<class'main.A'>> print a.classMethod # output: <bound method type.classMethod of <class 'main .A'>> Capítulo 125: Métodos definidos por el usuario Examples Creando objetos de método definidos por el usuario Los objetos de método definidos por el usuario pueden crearse cuando se obtiene un atributo de una clase (quizás a través de una instancia de esa clase), si ese atributo es un objeto de función definido por el usuario, un objeto de método definido por el usuario no vinculado o un objeto de método de clase. Cuando el atributo es un objeto de método definido por el usuario, un nuevo objeto de método solo se crea si la clase de la cual se está recuperando es la misma clase que la clase almacenada en el objeto de método original, o una clase derivada de la misma; de lo contrario, el objeto del método original se usa tal como es.
    • 710. 645 Ejemplo de tortuga El siguiente es un ejemplo del uso de una función definida por el usuario para ser llamada varias veces (∞) en un script con facilidad. import turtle, time, random #tell python we need 3 different modules turtle.speed(0) #set draw speed to the fastest turtle.colormode(255) #special colormode turtle.pensize(4) #size of the lines that will be drawn def triangle(size): #This is our own function, in the parenthesis is a variable we have defined that will be used in THIS FUNCTION ONLY. This fucntion creates a right triangle turtle.forward(size) #to begin this function we go forward, the amount to go forward by is the variable size turtle.right(90) #turn right by 90 degree turtle.forward(size) #go forward, again with variable turtle.right(135) #turn right again turtle.forward(size * 1.5) #close the triangle. thanks to the Pythagorean theorem we know that this line must be 1.5 times longer than the other two(if they are equal) while(1): #INFINITE LOOP turtle.setpos(random.randint(-200, 200), random.randint(-200, 200)) #set the draw point to a random (x,y) position turtle.pencolor(random.randint(1, 255), random.randint(1, 255), random.randint(1, 255)) #randomize the RGB color triangle(random.randint(5, 55)) #use our function, because it has only one variable we can simply put a value in the parenthesis. The value that will be sent will be random between 5 - 55, end the end it really just changes ow big the triangle is. turtle.pencolor(random.randint(1, 255), random.randint(1, 255), random.randint(1, 255)) #randomize color again # False, new object created # False, new object created # False, new object created # True, original object used print Parent.func is Parent.func print Parent.func2 is Parent.func2 print Child.func is Child.func print AnotherClass.func is AnotherClass.func # Parent: The class stored in the original method object class Parent(object): # func: The underlying function of original method object def func(self): pass func2 = func # Child: A derived class of Parent class Child(Parent): func = Parent.func # AnotherClass: A different class, neither subclasses nor subclassed class AnotherClass(object): func = Parent.func
    • 711. 646 class Vehicle(object): """A generic vehicle class.""" def init (self, position): self.position = position def travel(self, destination): route = calculate_route(from=self.position, to=destination) self.move_along(route) class Car(Vehicle): ... class Boat(Vehicle): ... class Plane(Vehicle): Capítulo 126: Mixins Sintaxis • class ClassName ( MainClass , Mixin1 , Mixin2 , ...): # Se utiliza para declarar una clase con el nombre ClassName , main (first) class MainClass y mixins Mixin1 , Mixin2 , etc. • class ClassName ( Mixin1 , MainClass , Mixin2 , ...): # La clase 'main' no tiene que ser la primera clase; Realmente no hay diferencia entre esto y la mezcla Observaciones Agregarunmixinaunaclaseseparecemuchoaagregarunasuperclase,porqueesmáso menoseso.UnobjetodeunaclaseconlamezclaFootambiénseráunainstanciadeFoo,e isinstance(instance, Foo) devolverá verdadero Examples Mezclar Un Mixin es un conjunto de propiedades y métodos que se pueden usar en diferentes clases, que no provienen de una clase base. En los lenguajes de programación orientada a objetos, normalmente se usa la herencia para dar a los objetos de diferentes clases la misma funcionalidad; si un conjunto de objetos tiene alguna habilidad, pones esa habilidad en una clase base de la cual ambos objetos heredan . Por ejemplo, supongamos que tiene las clases Car , Boat y Plane . Los objetos de todas estas clases tienen la capacidad de viajar, por lo que obtienen la función de travel . En este escenario, todos viajan de la misma manera básica, también; consiguiendo una ruta, y moviéndose a lo largo de ella. Para implementar esta función, podría derivar todas las clases de Vehicle y poner la función en esa clase compartida:
    • 712. 647 class Foo(main_super, mixin): ... class RadioUserMixin(object): def init (self): self.radio = Radio() def play_song_on_station(self, station): self.radio.set_station(station) self.radio.play_song() class Car(Vehicle, RadioUserMixin): ... class Clock(Vehicle, RadioUserMixin): ... Con este código, puedellamar a travel en un automóvil ( car.travel("Montana") ), barco ( boat.travel("Hawaii") ), y avión ( plane.travel("France") ) Sin embargo, ¿qué sucede si tiene una funcionalidad que no está disponible para una clase base? Digamos, por ejemplo, que quieres darle a Car una radio y la posibilidad de usarla para reproducir una canción en una estación de radio, con play_song_on_station , pero también tienes un Clock que puede usar una radio. Car y Clock podrían compartir una clase base ( Machine ). Sin embargo, no todas las máquinas pueden reproducir canciones; Boat y Plane no pueden (al menos en este ejemplo). Entonces, ¿cómo lograr sin duplicar el código? Puedes usar un mixin. En Python, dar una mezcla a una clase es tan simple como agregarla a la lista de subclases, como esto Foo heredará todas las propiedades y métodos de main_super , pero también los de mixin . Por lo tanto, para dar a las clases Car y reloj la posibilidad de usar una radio, puede anular Car del último ejemplo y escribir esto: Ahora puedes llamar a car.play_song_on_station(98.7) y clock.play_song_on_station(101.3) , pero no a algo como boat.play_song_on_station(100.5) Lo importante con los mixins es que le permiten agregar funcionalidad a objetos muy diferentes, que no comparten una subclase "principal" con esta funcionalidad, pero aún así comparten el código para ello. Sin los mixins, hacer algo como el ejemplo anterior sería mucho más difícil y / o podría requerir alguna repetición. Métodos de anulación en Mixins Los mixins son una clase de clase que se usa para "mezclar" propiedades y métodos adicionales en una clase. Por lo general, esto está bien porque muchas veces las clases mixtas no se anulan entre sí, o los métodos de la clase base. Pero si anula métodos o propiedades en sus combinaciones, esto puede llevar a resultados inesperados porque en Python la jerarquía de ...
    • 713. 648 >>> x = MyClass() >>> x.test() Base clases se define de derecha a izquierda. Por ejemplo, tome las siguientes clases En este caso, la clase Mixin2 es la clase base, extendida por Mixin1 y finalmente por BaseClass. Por lo tanto, si ejecutamos el siguiente fragmento de código: Vemos que el resultado devuelto es de la clase Base. Esto puede provocar errores inesperados en la lógica de su código y debe tenerse en cuenta y tenerse en cuenta. class Mixin1(object): def test(self): print "Mixin1" class Mixin2(object): def test(self): print "Mixin2" class BaseClass(object): def test(self): print "Base" class MyClass(BaseClass, Mixin1, Mixin2): pass
    • 714. 649 def add_student(): try: students['count'] += 1 except KeyError: students['count'] = 1 def add_student(): students['count'] = students.get('count', 0) + 1 x = True y = False x, y = y, x x # False y # True # Good examples, using implicit truth testing if attr: # do something if not attr: # do something #Bad examples, using specific types if attr == 1: Capítulo 127: Modismos Examples Inicializaciones clave del diccionario Prefiera el métododict.get sinoestá seguro si laclave está presente.Le permite devolver un valorpredeterminadosinoseencuentralaclave.Elmétodotradicionaldict[key]generaríauna excepción KeyError . En lugar de hacer Hacer Variables de conmutacion Para cambiar el valor de dos variables puede usar el desempaquetado de la tupla. Use la prueba de valor de verdad Python convertirá implícitamente cualquier objeto a un valor booleano para la prueba, así que úsalo siempre que sea posible.
    • 715. 650 import sys def main(): # Your code starts here # Don't forget to provide a return code return 0 if name == " main": sys.exit(main()) python my_program.py # But you can run main() explicitly if you really want it to run: my_program.main() # main() is not run # A new program file import my_program Esto generalmente produce un código más legible, y generalmente es mucho más seguro cuando se trata de tipos inesperados. Haga clic aquí para obtener una lista de lo que se evaluará como False . Prueba de " main " para evitar la ejecución inesperada del código Es una buena práctica probar la variable name del programa que llama antes de ejecutar su código. El uso de este patrón asegura que su código solo se ejecute cuando espera que lo sea; por ejemplo, cuando ejecuta su archivo explícitamente: Sin embargo, el beneficio viene si decide import su archivo a otro programa (por ejemplo, si lo está escribiendo como parte de una biblioteca). Luego puede import su archivo, y la trampa main se asegurará de que no se ejecute ningún código inesperadamente: # do something if attr == True: # do something if attr != '': # do something # If you are looking to specifically check forNone, use 'is' or'is not' if attr is None: # do something
    • 716. 651 import random laughs = ["Hi", "Ho", "He"] random.shuffle(laughs) # Shuffles in-place! Don't do: laughs =random.shuffle(laughs) print(laughs) # Out: ["He", "Hi", "Ho"] # Output may vary! print(random.choice(laughs)) # Out: He # Output may vary! Capítulo 128: Módulo aleatorio Sintaxis • random.seed (a = Ninguna, versión = 2) (la versión solo está disponible para Python 3.x) • random.getstate () • random.setstate (estado) • random.randint (a, b) • random.randrange (detener) • random.randrange (inicio, parada, paso = 1) • elección aleatoria • random.shuffle (x, random = random.random) • muestra aleatoria (población, k) Examples Aleatorio y secuencias: barajar, selección y muestra. barajar() Puedeusarrandom.shuffle() para mezclar/aleatorizarloselementos en una secuencia mutable e indexable . Por ejemplo una list : elección() Toma un elemento aleatorio de una secuencia arbitraria: muestra()
    • 717. 652 # Output may vary! laughs , 1 )) # Take one element # |--sequence--|--number--| print(random.sample( # Out: ['Ho'] import random random.randint(x, y) random.randint(1, 8) # Out: 8 random.rangrange(10, 20, 3) # Random integer between 10 and 19 with step 3 (10, 13, 16 and 19) # Random integer between 0 and 99 # Random integer between 20 and 49 random.randrange(100) random.randrange(20, 50) Como choice , toma elementos aleatorios de una secuencia arbitraria , pero puedes especificar cuántos: no tomará el mismo elemento dos veces: print(random.sample(laughs, 3)) # Take 3 random element from the sequence. # Out: ['Ho', 'He', 'Hi'] print(random.sample(laughs, 4)) # Output may vary! # Take 4 random element from the 3-item sequence. ValueError: Muestra más grande que la población Creación de enteros y flotadores aleatorios: randint, randrange, random y uniform randint () Devuelve un entero aleatorio entre x y y (inclusive): Por ejemplo obteniendo un número aleatorio entre 1 y 8 : randrange () random.randrange tiene la misma sintaxis que range y, a diferencia de random.randint , el último valor no es inclusivo:
    • 718. 653 random.random() # Out: 0.66486093215306317 random.uniform(1, 8) # Out: 3.726062641730108 aleatorio Devuelve un número de punto flotante aleatorio entre 0 y 1: uniforme Devuelve un número de punto flotante aleatorio entre x y y (inclusive): Números aleatorios reproducibles: semilla y estado Establecer una semilla específica creará una serie fija de números aleatorios:
    • 719. 654 random.seed(5) # Reset the random module to the same fixed state. print(random.randrange(0, 10)) # Out: 9 print(random.randrange(0, 10)) # Out: 4 save_state = random.getstate() # Get the current state print(random.randrange(0, 10)) # Out: 5 print(random.randrange(0, 10)) # Out: 8 random.setstate(save_state) # Reset to saved state print(random.randrange(0, 10)) # Out: 5 print(random.randrange(0, 10)) # Out: 8 random.seed(None) random.seed() Restablecer la semilla creará la misma secuencia "aleatoria" de nuevo: Dado que la semilla está fija, estos resultados son siempre 9 y 4 .Si no es necesario tener números específicos solo que los valores serán los mismos, también puede usar getstate y setstate para recuperar un estado anterior: Para pseudoaleatorizar de nuevo la secuencia, se seed con None : O llame al método seed sinargumentos: Crear números aleatorios criptográficamente seguros Por defecto, el módulo aleatorio de Python usa el PRNG Mersenne Twister para generar números aleatorios que, aunque son adecuados en dominios como simulaciones, no cumplen con los requisitos de seguridad en entornos más exigentes. Para crear un número pseudoaleatorio seguro criptográficamente, se puede usar SystemRandom que, mediante el uso de os.urandom , puede actuar como un generador de número pseudoaleatorio seguro criptográficamente, CPRNG . La forma más fácil de usarlo consiste simplemente en inicializar la clase SystemRandom . Los métodos proporcionados son similares a los exportados por el módulo aleatorio. random.seed(5) # Create a fixed state print(random.randrange(0, 10)) # Get a random integer between 0 and 9 # Out: 9 print(random.randrange(0, 10)) # Out: 4
    • 720. 655 print([secure_rand_gen.randrange(10) for i in range(10)]) # [9, 6, 9, 2, 2, 3, 8, 0, 9, 9] print(secure_rand_gen.randint(0, 20)) # 5 from string import punctuation, ascii_letters, digits symbols = ascii_letters + digits + punctuation secure_random = random.SystemRandom() password = "".join(secure_random.choice(symbols) for i in range(10)) print(password) # '^@g;J?]M6e' Paracrearunasecuenciaaleatoriade10int senelrango[0, 20],simplementesepuedellamar a randrange() : Para crear un entero aleatorio en un rango dado, uno puede usar randint : y, en consecuencia para todos los demás métodos. La interfaz es exactamente la misma, el único cambio es el generador de números subyacente. También puede usar os.urandom directamente para obtener bytes aleatorios criptográficamente seguros. Creando una contraseña de usuario aleatoria Paracrearunacontraseñade usuarioaleatoria,podemosutilizarlos símbolosproporcionadosen el módulo de string . Específicamente punctuation para los símbolos de puntuación, ascii_letters para las cartas y digits para dígitos: Luego podemos combinar todos estos símbolos en un nombre llamado symbols : Elimine cualquiera de estos para crear un conjunto de símbolos con menos elementos. Después de esto, podemos usar random.SystemRandom para generar una contraseña. Para una contraseña de 10 longitudes: Tenga en cuenta que otras rutinas puestos a disposición de inmediato por el random módulo - como random.choice , random.randint , etc. - no son adecuados para los propósitos criptográficos. Detrás de las cortinas, estas rutinas utilizan el PRNG de Mersenne Twister , que no satisface los requisitos de un CSPRNG . Por lo tanto, en particular, no debe usar ninguno de ellos para generar contraseñas que planea usar. Siempre use una instancia de SystemRandom como se muestra arriba. from random import SystemRandom secure_rand_gen = SystemRandom()
    • 721. 656 import string alphabet = string.ascii_letters + string.digits while True: password =''.join(choice(alphabet)fori in range(10)) if (any(c.islower() for c in password) and any(c.isupper() for c in password) and sum(c.isdigit() for c in password) >= 3): break import random probability = 0.3 if random.random() < probability: print("Decision with probability 0.3") else: print("Decision with probability 0.7") Python 3.x 3.6 A partir de Python 3.6, el módulo de secrets está disponible, lo que expone la funcionalidad criptográficamente segura. Al citar la documentación oficial , para generar "una contraseña alfanumérica de diez caracteres con al menos un carácter en minúscula, al menos un carácter en mayúscula y al menos tres dígitos" , podría: Decisión Binaria Aleatoria
    • 722. 657 import asyncio async def main(): print(await func()) async def func(): # Do time intensive stuff... return "Hello, world!" if name == " main ": loop = asyncio.get_event_loop() loop.run_until_complete(main()) import asyncio @asyncio.coroutine def main(): print((yield from func())) @asyncio.coroutine def func(): # Do time intensive stuff.. return "Hello, world!" if name == " main ": loop = asyncio.get_event_loop() loop.run_until_complete(main()) Capítulo 129: Módulo asyncio Examples Sintaxis de Coroutine y Delegación Antes de que se lanzara Python asyncio , el módulo asyncio usaba generadores para imitar las llamadas asíncronas y, por lo tanto, tenía una sintaxis diferente a la versión actual de Python 3.5. Python 3.x 3.5 Python 3.5 introdujo el async y await palabras clave. Tenga en cuenta la falta de paréntesis alrededor de la llamada await func() . Python 3.x 3.3 3.5 Antesde Python 3.5, el decorador @asyncio.coroutine se usabaparadefinir unacoroutine. El rendimientodelaexpresiónseusóparaladelegacióndelgenerador.Notelosparéntesis alrededor del yield from func() . Python 3.x 3.5 Aquí hay un ejemplo que muestra cómo dos funciones pueden ejecutarse de forma asíncrona:
    • 723. 658 import asyncio from concurrent.futures import ThreadPoolExecutor def func(a, b): # Do time intensive stuff... return a + b async def main(loop): executor = ThreadPoolExecutor() result = await loop.run_in_executor(executor, func, "Hello,", " world!") print(result) if name == " main ": loop = asyncio.get_event_loop() loop.run_until_complete(main(loop)) import asyncio from concurrent.futures import ThreadPoolExecutor def func(a, b): # Do time intensive stuff... return a + b Ejecutores asincronos Nota: utiliza la sintaxis de Python 3.5+ async / await asyncio admite el uso de objetos Executor que se encuentran en concurrent.futures para programar tareas de formaasíncrona. Losbuclesdeeventostienen la función run_in_executor() que toma un objeto Executor , un Callable y los parámetros del Callable. Programando una tarea para un Executor CadaciclodeeventostambiéntieneunaranuradeExecutor"predeterminada"quesepuede asignar a un Executor . Para asignar un Executor y programar tareas desde el bucle, utiliceel método set_default_executor() . import asyncio async def cor1(): print("cor1 start") for i in range(10): await asyncio.sleep(1.5) print("cor1", i) async def cor2(): print("cor2 start") for i in range(15): await asyncio.sleep(1) print("cor2", i) loop = asyncio.get_event_loop() cors = asyncio.wait([cor1(), cor2()]) loop.run_until_complete(cors)
    • 724. 659 import asyncio import uvloop if name == " main ": asyncio.set_event_loop(uvloop.new_event_loop()) # Do your stuff here ... import asyncio import uvloop if name == " main ": asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) loop = asyncio.new_event_loop() Hay dos tipos principales de Executor en concurrent.futures , ThreadPoolExecutor y ProcessPoolExecutor . ThreadPoolExecutor contiene unconjunto desubprocesosque sepueden establecer manualmenteenunnúmeroespecífico desubprocesosatravésdel constructoropor defectoelnúmerodenúcleos enlostiemposdelamáquina 5.ElThreadPoolExecutorutilizael conjuntodesubprocesos paraejecutartareasasignadasa él Engeneral, esmejor en operaciones vinculadasa laCPU en lugarde operaciones vinculadasdeE /S Contraste esocon el ProcessPoolExecutor que genera un nuevo proceso para cada tarea asignada. ProcessPoolExecutor solo puede tomar tareas y parámetros que son seleccionables. Las tareas no recolectables más comunes son los métodos de los objetos. Si debe programar el método de un objeto como una tarea en un Executor , debe usar un ThreadPoolExecutor . Usando UVLoop uvloop esunaimplementaciónparaasyncio.AbstractEventLoop basadaenlibuv(utilizadapor nodejs).Cumpleconel99%deasyncio funcionesdeasyncio yesmuchomásrápidoqueel asyncio.EventLoop tradicional. asyncio.EventLoop . uvloop actualmente no está disponible en Windows, instálelo con pip install uvloop . También se puede cambiar la fábrica de bucles de eventos configurando EventLoopPolicy a la de uvloop . Primitiva de sincronización: Evento Concepto async def main(loop): # NOTE: Using `None` as the first parameter designates the `default` Executor. result = await loop.run_in_executor(None, func, "Hello,", " world!") print(result) if name == " main ": loop = asyncio.get_event_loop() loop.set_default_executor(ThreadPoolExecutor()) loop.run_until_complete(main(loop))
    • 725. 660 import asyncio # event trigger function def trigger(event): print('EVENT SET') event.set() # wake up coroutines waiting # event consumers async def consumer_a(event): consumer_name = 'Consumer A' print('{} waiting'.format(consumer_name)) await event.wait() print('{} triggered'.format(consumer_name)) async def consumer_b(event): consumer_name = 'Consumer B' print('{} waiting'.format(consumer_name)) await event.wait() print('{} triggered'.format(consumer_name)) # event event = asyncio.Event() # wrap coroutines in one future main_future = asyncio.wait([consumer_a(event), consumer_b(event)]) # event loop event_loop = asyncio.get_event_loop() event_loop.call_later(0.1, functools.partial(trigger, event)) # trigger event in 0.1 sec # complete main_future done, pending = event_loop.run_until_complete(main_future) Utilice un Event para sincronizar la programación de múltiples coroutines . En pocas palabras, un evento es como el disparo en una carrera: permite que los corredores salgan de los bloques de salida. Ejemplo Salida: Consumidor B en espera Consumidor A esperando SET DE EVENTOS Consumidor B activado Consumidor A activado Un simple websocket Aquí hacemos un simple websocket eco utilizando asyncio . Definimos las rutinas para conectarse a un servidor y enviar / recibir mensajes. Las comunicaciones del websocket se ejecutan en una
    • 726. 661 if name == ' main ': # The main loop loop = asyncio.get_event_loop() loop.run_until_complete(main()) # "Hello World!" async def main(): echo = EchoWebsocket() await echo.connect() await echo.send("Hello World!") print(await echo.receive()) async def connect(self): self.websocket = await session.ws_connect("wss://echo.websocket.org") async def send(self, message): self.websocket.send_str(message) async def receive(self): result = (await self.websocket.receive()) return result.data # handles the context manager import asyncio import aiohttp session = aiohttp.ClientSession() class EchoWebsocket: rutina main , que se ejecuta mediante un bucle de eventos. Este ejemplo es modificado de una publicación anterior . Error común sobre asyncio Probablemente, la idea errónea más común acerca de asnycio es que le permite ejecutar cualquier tarea en paralelo: eludir el GIL (bloqueo global del intérprete) y, por lo tanto, ejecutar trabajos de bloqueo en paralelo (en subprocesos separados). no lo hace! asyncio (y las bibliotecas creadas para colaborar con asyncio ) se basan en coroutines: funciones que (en colaboración) devuelven el flujo de control a la función de llamada. asyncio.sleep en cuenta asyncio.sleep en los ejemplos anteriores. este es un ejemplo de una coroutina no bloqueanteque espera 'en el fondo' y devuelveel flujode control ala función de llamada (cuando se llama con await ). time.sleep es un ejemplo de una función de bloqueo. el flujo de ejecución del programa se detendrá allí y solo regresará después de que time.sleep hayaterminado. un ejemplo real es la biblioteca de requests que consiste (por el momento) solo en funciones de bloqueo. no hay concurrencia si llama a cualquiera de sus funciones dentro de asyncio . aiohttp por otro lado fue construido con asyncio en mente. sus coroutines correrán concurrentemente. • Si tiene tareas vinculadas a la CPU de larga ejecución que le gustaría ejecutar en paralelo, asyncio no es para usted. Para eso necesitas threads o multiprocessing . • Si tiene trabajos en ejecución enlazados a IO, puede ejecutarlos simultáneamente usando asyncio .
    • 727. 662
    • 728. 663 from Queue import Queue question_queue = Queue() for x in range(1,10): temp_dict = ('key', x) question_queue.put(temp_dict) while(not question_queue.empty()): item = question_queue.get() print(str(item)) ('key', 1) ('key', 2) ('key', 3) ('key', 4) ('key', 5) ('key', 6) ('key', 7) ('key', 8) ('key', 9) Capítulo 130: Módulo de cola Introducción El módulo Queue implementa colas multi-productor, multi-consumidor. Es especialmente útil en la programación de subprocesos cuando la información se debe intercambiar de forma segura entre varios subprocesos. Hay tres tipos de colas que proporciona el módulo de colas, que son las siguientes: 1. Cola 2. LifoQueue 3. Excepción de PriorityQueue que podría venir: 1. Completa (desbordamiento de cola) 2. Vacía (desbordamiento de cola) Examples Ejemplo simple Salida:
    • 729. 664 import collections counts = collections.Counter([1,2,3]) >>> collections.Counter('Happy Birthday') Counter({'a': 2, 'p': 2, 'y': 2, 'i': 1, 'r': 1, 'B': 1, ' ': 1, 'H': 1, 'd': 1, 'h': 1, 't': 1}) Capítulo 131: Módulo de colecciones Introducción El paquete de collections incorporado proporciona varios tipos de colección flexibles y especializados que tienenun alto rendimientoy ofrecen alternativas a los tipos de colección generales de dict , list ,tupley set .El módulo también define clases básicas abstractas que describen diferentes tipos de funcionalidad de colección (como MutableSet y ItemsView ). Observaciones Hay otros tres tipos disponibles en el módulo de colecciones , a saber: 1. UserDict 2. Lista de usuarios 3. UserString Cada una de ellas actúa como una envoltura alrededor del objeto atado, por ejemplo, UserDict actúa como una envoltura alrededor de un objeto dict . En cada caso, la clase simula su tipo nombrado. El contenido de la instancia se mantiene en un objeto de tipo regular, al que se puede acceder a través del atributo de datos de la instancia de contenedor. En cada uno de estos tres casos, la necesidad de estos tipos ha sido parcialmente suplantada por la capacidad de subclasificar directamente del tipo básico; sin embargo, puede ser más fácil trabajar con la clase contenedora porque el tipo subyacente es accesible como un atributo. Examples colecciones. Contador es una subclase de dict que le permite contar objetos fácilmente. Tiene métodos de utilidad para trabajar con las frecuencias de los objetos que está contando. elcódigoanterior crea un objeto, cuenta, que tienelas frecuenciasdetodos loselementos pasados al constructor. Este ejemplo tiene el valor Counter({1: 1, 2: 1, 3: 1}) Ejemplos de constructor Contador de cartas
    • 730. 665 >>> collections.Counter('I am Sam Sam I am That Sam-I-am That Sam-I-am! I do not like that Sam-I-am'.split()) Counter({'I': 3, 'Sam': 2, 'Sam-I-am': 2, 'That': 2, 'am': 2, 'do': 1, 'Sam-I-am!': 1, 'that': 1, 'not': 1, 'like': 1}) >>> c = collections.Counter({'a': 4, 'b': 2, 'c': -2, 'd': 0}) >>> c['a'] 4 >>> c['c'] = -3 >>> c Counter({'a': 4, 'b': 2, 'd': 0, 'c': -3}) >>> sum(c.itervalues()) # negative numbers are counted! 3 >>> list(c.elements()) ['a', 'a', 'a', 'a', 'b', 'b'] >>> c - collections.Counter() Counter({'a': 4, 'b': 2}) >>> c.clear() >>> c Counter() >>> c.update({'a': 3, 'b':3}) >>> c.update({'a': 2, 'c':2}) # adds to existing, sets if they don't exist >>> c Counter({'a': 5, 'b': 3, 'c': 2}) >>> c.subtract({'a': 3, 'b': 3, 'c': 3}) # subtracts (negative values are allowed) Contador de palabras Recetas Consigue la cuenta del elemento individual. Establecer la cuenta del elemento individual Obtener el número total de elementos en el contador (4 + 2 + 0 - 3) Obtener elementos (solo se mantienen los que tienen un contador positivo) Eliminar claves con 0 o valor negativo. Quitar todo Añadir eliminar elementos individuales
    • 731. 666 >>> state_capitals = collections.defaultdict(str) >>> state_capitals defaultdict(<class 'str'>, {}) >>> str() '' >>> int() 0 >>> list [] >>> state_capitals['Alaska'] '' >>> state_capitals defaultdict(<class 'str'>, {'Alaska': ''}) >>> fruit_counts = defaultdict(int) >>> fruit_counts['apple'] += 2 # No errors should occur >>> fruit_counts default_dict(int, {'apple': 2}) >>> fruit_counts['banana'] # No errors should occur 0 >>> fruit_counts # A new key is created default_dict(int, {'apple': 2, 'banana': 0}) >>> state_capitals['Alabama'] = 'Montgomery' >>> state_capitals defaultdict(<class 'str'>, {'Alabama': 'Montgomery', 'Alaska': ''}) colecciones.defaultdict collections.defaultdict (default_factory) devuelve una subclase de dict que tiene un valor predeterminado para las claves que faltan. El argumento debe ser una función que devuelve el valor predeterminado cuando se llama sin argumentos. Si no se pasa nada, el valor predeterminado es None . devuelve una referencia a un defaultdict que creará un objeto de cadena con su método default_factory. Un uso típico de defaultdict es usar uno de los tipos incorporados como str , int , list o dict como default_factory, ya que estos devuelven tipos vacíos cuando se les llama sin argumentos: Llamar al valor predeterminado con una clave que no existe no produce un error como lo haría en un diccionario normal. Otroejemploconint: Los métodos de diccionario normales funcionan con el diccionario predeterminado >>> c Counter({'a': 2, 'b': 0, 'c': -1})
    • 732. 667 >>> s = [('NC', 'Raleigh'), ('VA', 'Richmond'), ('WA', 'Seattle'), ('NC', 'Asheville')] >>> dd = collections.defaultdict(list) >>> for k, v in s: ... dd[k].append(v) >>> dd defaultdict(<class 'list'>, {'VA': ['Richmond'], 'NC': ['Raleigh', 'Asheville'], 'WA': ['Seattle']}) >>> d = {'foo': 5, 'bar': 6} >>> print(d) {'foo': 5, 'bar': 6} >>> d['baz'] = 7 >>> print(a) {'baz': 7, 'foo': 5, 'bar': 6} >>> d['foobar'] = 8 >>> print(a) {'baz': 7, 'foo': 5, 'bar': 6, 'foobar': 8} ``` >>> from collections import OrderedDict >>> d = OrderedDict([('foo', 5), ('bar', 6)]) >>> print(d) OrderedDict([('foo', 5), ('bar', 6)]) >>> d['baz'] = 7 >>> print(d) OrderedDict([('foo', 5), ('bar', 6), ('baz', 7)]) >>> d['foobar'] = 8 >>> print(d) OrderedDict([('foo', 5), ('bar', 6), ('baz', 7), ('foobar', 8)]) El uso de list como default_factory creará una lista para cada nueva clave. colecciones.OrdenedDict El orden de las claves en los diccionarios de Python es arbitrario: no se rigen por el orden en el que se agregan. Por ejemplo: (El orden arbitrario implícito arriba significa que puede obtener resultados diferentes con el código anterior al que se muestra aquí). El orden en que aparecen las teclas es el orden en el que se iterarían, por ejemplo, utilizando un bucle for . La clase collections.OrderedDict proporciona objetos de diccionario que conservan el orden de las claves. OrderedDict sse puedecrear comose muestraa continuaciónconunaserie deartículos ordenados (aquí, una lista de pares clave-valor de tupla): O podemos crear un OrderedDict vacío y luego agregar elementos:
    • 733. 668 >>> d['foo'] = 4 >>> print(d) OrderedDict([('foo', 4), ('bar', 6), ('baz', 7), ('foobar', 8)]) Person = namedtuple('Person', ['age', 'height', 'name']) Person = namedtuple('Person', 'age, height, name') Person = namedtuple('Person', 'age height name') dave = Person(30, 178, 'Dave') jack = Person(age=30, height=178, name='Jack S.') print(jack.age) # 30 print(jack.name) # 'Jack S.' La OrderedDict través de un OrderedDict permite el acceso de claves en el orden en que se agregaron. ¿Qué sucede si asignamos un nuevo valor a una clave existente? La clave conserva su lugar original en el OrderedDict . colecciones.namedu tupla Defina un nuevo tipo de Person usando namedtuple como este: El segundo argumento es la lista de atributos que tendrá la tupla. También puede enumerar estos atributos como espacios o cadenas separadas por comas: o Una vez definido, se puede crear una instancia de una tupla con nombre llamando al objeto con los parámetros necesarios, por ejemplo: Los argumentos con nombre también se pueden utilizar: Ahora puedes acceder a los atributos de la pareja nombrada: Elprimerargumentoparaelconstructordeelementosnombrados(ennuestroejemplo'Person') esel typename .Estípicousarlamismapalabraparaelconstructoryelnombretipográfico,pero >>> o = OrderedDict() >>> o['key1'] = "value1" >>> o['key2'] = "value2" >>> print(o) OrderedDict([('key1', 'value1'), ('key2', 'value2')])
    • 734. 669 Human = namedtuple('Person', 'age, height, name') dave = Human(30, 178, 'Dave') print(dave) # yields: Person(age=30, height=178, name='Dave') #return and remove the leftmost item # list the contents of the deque # peek at leftmost item >>>d.pop() # return and remove the rightmost item 'j' >>> d.popleft() 'f' >>> list(d) ['g', 'h', 'i'] >>> d[0] 'g' ... print elem.upper() G H I >>> d.append('j') # add a new entry to the right side >>> d.appendleft('f') # add a new entry to the left side >>>d # show the representation of the deque deque(['f', 'g', 'h', 'i', 'j']) # make a new deque with three items # iterate over the deque's elements >>> from collections import deque >>> d = deque('ghi') >>> for elem in d: pueden ser diferentes: colecciones.deque Devuelve unnuevo objeto deque inicializado de izquierdaa derecha (utilizando append ()) con datos de iterable. Si iterable no está especificado, el nuevo deque está vacío. Deques es una generalización de pilas y colas (el nombre se pronuncia "deck" y es la abreviatura de "cola doble"). Deques es compatible con subprocesos seguros y eficientes con la memoria y hace estallar desde cualquier lado del deque con aproximadamente el mismo rendimiento O (1) en cualquier dirección. Aunque los objetos de la lista admiten operaciones similares, están optimizados para operaciones rápidas de longitud fija e incurren en costos de movimiento de memoria O (n) para operaciones pop (0) e insertar (0, v) que cambian el tamaño y la posición de la representación de datos subyacente . Nuevo en la versión 2.4. Si maxlen no está especificado o es None , los deques pueden crecer hasta una longitud arbitraria. De lo contrario, el deque se limita a la longitud máxima especificada. Una vez que el deque longitud acotada está lleno, cuando se agregan nuevos elementos, un número correspondiente de elementos se descarta del extremo opuesto. Los deques de longitud limitada proporcionan una funcionalidad similar al filtro de cola en Unix. También son útiles para rastrear transacciones y otros grupos de datos donde solo interesa la actividad más reciente. Cambiado en la versión 2.6: Se agregó el parámetro maxlen.
    • 735. 670 Fuente: https://docs.python.org/2/library/collections.html colecciones.ChainMap ChainMap es nuevo en la versión 3.3 Devuelve un nuevo objeto ChainMap dado un número de maps . Este objeto agrupa varios dicts u otras asignaciones para crear una vista única y actualizable. ChainMap son útiles para administrar contextos y superposiciones anidadas. Un ejemplo en el mundo de python se encuentra en la implementación de la clase de Context en el motor de plantillas de Django. Es útil para vincular rápidamente varias asignaciones para que el resultado se pueda tratar como una sola unidad. A menudo es mucho más rápido que crear un nuevo diccionario y ejecutar varias llamadas de update() . Cada vez que uno tiene una cadena de valores de búsqueda, puede haber un caso para ChainMap . Un ejemplo incluye tener valores especificados por el usuario y un diccionario de valores predeterminados. Otro ejemplo son los mapas de parámetros POST y GET que se encuentran en el uso web, por ejemplo, Django o Flask. Mediante el uso de ChainMap uno devuelve una vista combinada de dos diccionarios distintos. La lista de parámetros de maps se ordena desde la primera búsqueda hasta la última búsqueda. Las búsquedas buscan sucesivamente las asignaciones subyacentes hasta que se encuentra una clave. Por el contrario, las escrituras, actualizaciones y eliminaciones solo funcionan en la primera >>> d.extendleft('abc') # extendleft() reverses the input order >>> d deque(['c', 'b', 'a']) File "<pyshell#6>", line 1, in -topleveld.pop() IndexError: pop from an empty deque #makeanewdequeinreverseorder # empty the deque # cannot pop from an empty deque >>> deque(reversed(d)) deque(['l', 'k', 'j', 'i', 'h', 'g']) >>> d.clear() >>> d.pop() Traceback (most recent call last): >>> d.rotate(-1) # left rotation >>> d deque(['g', 'h', 'i', 'j', 'k', 'l']) >>> d.rotate(1) # right rotation >>> d deque(['l', 'g', 'h', 'i', 'j', 'k']) deque(['g', 'h', 'i', 'j', 'k','l']) # list the contents of a deque in reverse # search the deque # add multiple elements at once >>>list(reversed(d)) ['i', 'h', 'g'] >>> 'h' in d True >>> d.extend('jkl') >>> d >>> d[-1] # peek at rightmost item 'i'
    • 736. 671 import collections # define two dictionaries with at least some keys overlapping. dict1 = {'apple': 1, 'banana': 2} dict2 = {'coconut': 1, 'date': 1, 'apple': 3} # create two ChainMaps with different ordering of those dicts. combined_dict = collections.ChainMap(dict1, dict2) reverse_ordered_dict = collections.ChainMap(dict2, dict1) for k, v in combined_dict.items(): print(k, v) date 1 apple 1 banana 2 coconut 1 for k, v in reverse_ordered_dict.items(): print(k, v) date 1 apple 3 banana 2 coconut 1 asignación. Tenga en cuenta el impacto del orden en el que el valor se encuentra primero en la búsqueda posterior
    • 737. 672 >>> from functools import partial >>> unhex = partial(int, base=16) >>> unhex. doc = 'Convert base16 string to int' >>> unhex('ca11ab1e') 3390155550 In [2]: from functools import partial In [3]: def f(a, b, c, x): ...: return 1000*a + 100*b + 10*c + x ...: In [4]: g = partial(f, 1, 1, 1) In [5]: print g(2) 1112 @total_ordering Capítulo 132: Módulo de funciones Examples parcial La función partial crea una aplicación de función parcial desde otra función. Se utiliza para vincular valores a algunos de los argumentos de la función (o argumentos de palabras clave) y producir una llamada sin los argumentos ya definidos. partial() , como su nombre indica, permite una evaluación parcial de una función. Veamos el siguiente ejemplo: Cuandosecreag,f,quetomacuatroargumentos( a, b, c, x),tambiénseevalúaparcialmente paralosprimerostresargumentos, a, b, c,Evaluacióndefsecompletacuandogesllamado, g(2) , que pasa el cuarto argumento a f . Una forma de pensar en partial es un registro de desplazamiento; empujando en un argumento en el momento en alguna función. partial es útil para los casos en que los datos entran como flujo y no podemos pasar más de unargumento. ordenamiento total Cuando queremos crear una clase ordenable, normalmente necesitamos definir los métodos eq() , lt () , le () , gt () y ge (). Eldecoradordetotal_ordering,aplicadoaunaclase,permiteladefinicióndeeq()ysolouno entre lt () , le () , gt () y ge () , y aún permite todas las operaciones de ordenamiento en la clase.
    • 738. 673 from functools import reduce def factorial(n): return reduce(lambda a, b: (a*b), range(1, n+1)) @lru_cache(maxsize=None) # Boundless cache def fibonacci(n): if n < 2: return n return fibonacci(n-1) + fibonacci(n-2) >>> fibonacci(15) El decorador utiliza una composición de los métodos proporcionados y las operaciones algebraicasparaderivarlosotrosmétodosdecomparación.Porejemplo,sidefinimos lt ()y eq() y queremos derivar gt () , simplemente podemos verificar not lt () and not eq() . Nota : la función total_ordering solo está disponible desde Python 2.7. reducir EnPython 3.x, la función de reduce ya explicada aquí se ha eliminado de las funciones integradas y ahora debe importarse desde functools . lru_cache El decorador @lru_cache se puede usar para envolver una función costosa y de uso intensivo de computación con un caché deuso menos reciente .Estopermite quelas llamadas de funciónse memoricen, de modo que las llamadas futuras con los mismos parámetros puedan retornar instantáneamente en lugar de tener que volver a calcularse. En el ejemplo anterior, el valor de fibonacci(3) solo se calcula una vez, mientras que si fibonacci no tuviera un caché LRU, fibonacci(3) se habría calculado más de 230 veces. Por lo tanto, @lru_cache es especialmente bueno para funciones recursivas o programación dinámica, donde unafunción costosa podría llamarse varias veces con los mismosparámetros exactos. @lru_cache tiene dos argumentos • maxsize : Número de llamadas a guardar. Cuando el número de llamadas únicas supera el maxsize , el caché LRU eliminará las llamadas menos utilizadas recientemente. • typed (agregado en 3.3): marca para determinar si los argumentos equivalentes de class Employee: ... def eq (self, other): return ((self.surname, self.name) == (other.surname, other.name)) def lt (self, other): return ((self.surname, self.name) < (other.surname, other.name))
    • 739. 674 >>> fib.cache_info() CacheInfo(hits=13, misses=16, maxsize=None, currsize=16) diferentes tipos pertenecen a diferentes registros de caché (es decir, si 3.0 y 3 cuentan como argumentos diferentes) Podemos ver las estadísticas de caché también: NOTA :Ya que @lru_cache usa los diccionarios para almacenar en caché los resultados, todos los parámetros para la función deben estar habilitados para que la caché funcione. Documentos oficiales de Python para @lru_cache . @lru_cache fue agregado en 3.2. cmp_to_key Python cambió sus métodos de clasificación para aceptar una función clave. Esas funciones toman un valor y devuelven una clave que se usa para ordenar las matrices. Las antiguas funciones de comparación utilizadas para tomar dos valores y devolver -1, 0 o +1 si el primer argumento es pequeño, igual o mayor que el segundo argumento, respectivamente. Esto es incompatible con la nueva función clave. Ahí es donde entra functools.cmp_to_key : Ejemplo tomado y adaptado de la documentación de la biblioteca estándar de Python . >>> import functools >>> import locale >>> sorted(["A", "S", "F", "D"], key=functools.cmp_to_key(locale.strcoll)) ['A', 'D', 'F', 'S']
    • 740. 675 x = 1.55 y = -1.55 # round to the nearest integer round(x) # 2 round(y) # -2 # the second argument gives how many decimal placesto round to (defaults to 0) round(x, 1) # 1.6 round(y, 1) # -1.6 #math is amodule so import it first, then use it. import math # get the largest integer less than x math.floor(x) # 1 math.floor(y) # -2 # get the smallest integer greater than x math.ceil(x) # 2 math.ceil(y) # -1 # drop fractional part of x math.trunc(x) # 1, equivalent to math.floor for positive numbers math.trunc(y) # -1, equivalent to math.ceil for negative numbers round(1.3) # 1.0 round(0.5) # 1.0 round(1.5) # 2.0 Capítulo 133: Módulo de matemáticas Examples Redondeo: redondo, suelo, ceil, trunc Ademásdela función roundincorporada, el módulo mathproporciona las funciones floor , ceil y trunc . Python 2.x 2.7 floor , el ceil , el trunc y el round siempre devuelven un float . round siempre rompe empates lejos de cero. Python 3.x 3.0 floor , ceil y trunc siempre devuelven un valor Integral , mientras que round devuelve un valor Integral si se llama con un argumento.
    • 741. 676 round(0.5) # 0 round(1.5) # 2 round(2.675, 2) # 2.67, not 2.68! >>> math.floor(-1.7) -2.0 >>> -5 // 2 -3 math.log(math.e) # 1.0 math.log(1) # 0.0 math.log(100) # 4.605170185988092 math.log(1 + 1e-20) # 0.0 math.log1p(1e-20) # 1e-20 math.log10(10) # 1.0 Rupturas round empates hacia el número par más cercano.Esto corrige el sesgo hacia números más grandes cuando se realizan una gran cantidad de cálculos. ¡Advertencia! Al igual que con cualquier representación de punto flotante, algunas fracciones no se pueden representar exactamente . Esto puede llevar a algún comportamiento de redondeo inesperado. Advertencia sobre la división de números negativos en el piso, corte y número entero Python (y C ++ y Java) se alejan de cero para los números negativos. Considerar: Logaritmos math.log(x) da el logaritmo natural (base e ) de x . math.log puede perder precisión con números cercanos a 1, debido a las limitaciones de los números de punto flotante. Para calcular con precisión los registros cercanos a 1, use math.log1p , que evalúa el logaritmo natural de 1 más el argumento: math.log10 puede usarse para logs base 10: Python 2.x 2.3.0 Cuando se usa con dos argumentos, math.log(x, base) da el logaritmo de x en la base dada (es round(1.33, 1) # 1.3 round(1.3) # 1
    • 742. 677 math.log(100, 10) #2.0 math.log(27, 3) # 3.0 math.log(1, 10) # 0.0 math.hypot(2, 4) # Just a shorthand for SquareRoot(2**2 + 4**2) # Out: 4.47213595499958 math.radians(45) # Convert 45 degrees to radians # Out: 0.7853981633974483 math.degrees(math.asin(1)) # Convert the result of asin to degrees # Out: 90.0 # "= pi / 2" math.asin(1) # Out: 1.5707963267948966 math.asin(1)/ math.pi # Out: 0.5 # Sine of 90 degrees # Sine and arc sine math.sin(math.pi / 2) # Out: 1.0 math.sin(math.radians(90)) # Out: 1.0 decir, log(x) / log(base) . Copiando carteles En Python 2.6 y superior, math.copysign(x, y) devuelve x con el signo de y . El valor devuelto es siempre un float . Python 2.x 2.6 math.copysign(-2, 3) # 2.0 math.copysign(3, -3) # -3.0 math.copysign(4, 14.2) # 4.0 math.copysign(1, -0.0) # -1.0, on a platform which supports signed zero Trigonometría Cálculo de la longitud de la hipotenusa. Convertir grados a / desde radianes Todas las funciones math esperan radianes, por lo que necesitas convertir grados a radianes: Todos los resultados de las funciones trigonométricas inversas devuelven el resultado en radianes, por lo que es posible que deba volver a convertirlo en grados: Funciones seno, coseno, tangente e inversa.
    • 743. 678 math.atan(math.inf) # Out: 1.5707963267948966 # This is just "pi / 2" math.atan(float('inf')) # Out: 1.5707963267948966 # This is just "pi / 2" math.atan2(1, 2) # Equivalent to "math.atan(1/2)" # Out: 0.4636476090008061 # ≈ 26.57 degrees, 1st quadrant math.atan2(-1, -2) # Not equal to "math.atan(-1/-2)" == "math.atan(1/2)" # Out: -2.677945044588987 # ≈ -153.43 degrees (or 206.57 degrees), 3rd quadrant math.atan2(1, 0) # math.atan(1/0) would raise ZeroDivisionError # Out: 1.5707963267948966 # This is just "pi / 2" # Hyperbolic sine function math.sinh(math.pi) # = 11.548739357257746 math.asinh(1) # =0.8813735870195429 # Hyperbolic cosine function math.cosh(math.pi) # = 11.591953275521519 math.acosh(1) # = 0.0 # Hyperbolic tangent function math.tanh(math.pi) # = 0.99627207622075 math.atanh(0.5) # =0.5493061443340549 Python 3.x 3.5 Aparte de math.atan también hay una función math.atan2 dos argumentos, que calcula el cuadrante correcto y evita los escollos de la división por cero: Seno hiperbólico, coseno y tangente. Constantes math módulos math incluyen dos constantes matemáticas de uso común. • math.pi - La constante matemática pi • math.e - La constante matemática e (base del logaritmo natural) # Cosine and arc cosine: math.cos(math.pi /2) # Out: 6.123233995736766e-17 # Almost zero but not exactly because "pi" is a float with limited precision! math.acos(1) # Out: 0.0 # Tangent and arc tangent: math.tan(math.pi/2) # Out: 1.633123935319537e+16 # Very large but not exactly "Inf" because "pi" is a float with limited precision
    • 744. 679 pos_inf = math.inf neg_inf = -math.inf not_a_num = math.nan math.inf == float('inf') # Out: True -math.inf == float('-inf') # Out: True # NaN never compares equal to anything, even itself math.nan == float('nan') # Out: False # Equivalent to the square root of -1. # = (-1+0j) 1j 1j * 1j pos_inf = float('inf') # positive infinity neg_inf = float('-inf') # negative infinity not_a_num = float('nan') #NaN("notanumber") pos_inf, neg_inf, not_a_num # Out: (inf, -inf, nan) Python 3.5 y superiortienen constantespara infinito yNaN ("noes unnúmero"). La sintaxis anterior de pasar una cadena a float() aún funciona. Python 3.x 3.5 Números imaginarios Los números imaginarios en Python están representados por una "j" o "J" detrás del número objetivo. Infinito y NaN ("no es un número") En todas las versiones de Python, podemos representar infinito y NaN ("no un número") de la siguiente manera: En Python 3.5 y superior, también podemos usar las constantes definidas math.inf y math.nan : Python 3.x 3.5 Las representaciones de cadena se muestran como inf y -inf y nan : >>> from math import pi, e >>> pi 3.141592653589793 >>> e 2.718281828459045 >>>
    • 745. 680 math.isinf(pos_inf) # Out: True math.isinf(neg_inf) # Out: True neg_inf == float('-inf') # or ==-math.infinPython 3.5+ # Out: True neg_inf == pos_inf # Out: False pos_inf == float('inf') # or == math.inf in Python 3.5+ # Out: True math.isfinite(pos_inf) # Out: False math.isfinite(0.0) # Out: True import sys sys.float_info.max # Out: 1.7976931348623157e+308 (this is system-dependent) pos_inf > sys.float_info.max # Out: True neg_inf < -sys.float_info.max # Out: True pos_inf == sys.float_info.max * 1.0000001 # Out: True neg_inf == -sys.float_info.max * 1.0000001 # Out: True Podemos probar el infinito positivo o negativo con el método isinf : Podemos probar específicamente el infinito positivo o el infinito negativo por comparación directa: Python 3.2 y superior también permite verificar la finitud: Python 3.x 3.2 Los operadores de comparación funcionan como se espera para el infinito positivo y negativo: Pero si una expresión aritmética produce un valor más grande que el máximo que se puede representar como un float , se convertirá en infinito: Sinembargo, la divisiónpor cero no da un resultado de infinito (o infinito negativo cuando sea apropiado), sino que genera una excepción ZeroDivisionError .
    • 746. 681 -5.0 * pos_inf == neg_inf # Out: True -5.0 * neg_inf == pos_inf # Out: True pos_inf * neg_inf == neg_inf # Out: True 0.0 * pos_inf # Out: nan 0.0 * neg_inf # Out: nan pos_inf /pos_inf # Out: nan not_a_num == not_a_num # Out: False math.isnan(not_a_num) Out: True not_a_num>5.0 or not_a_num < 5.0 or not_a_num == 5.0 # Out: False not_a_num != 5.0 # or any random value # Out: True 5.0 * not_a_num # Out: nan float('-nan') # Out: nan Las operaciones aritméticas en el infinito solo dan resultados infinitos, o algunas veces NaN: NaN nunca es igual a nada, ni siquiera a sí mismo. Podemos probar que es con el método isnan : NaN siempre se compara como "no igual", pero nunca menor o mayor que: Las operaciones aritméticas en NaN siempre dan NaN. Esto incluye la multiplicación por -1: no hay "NaN negativo". Python 3.x 3.5 try: x = 1.0 / 0.0 print(x) except ZeroDivisionError: print("Division by zero") # Out: Division by zero
    • 747. 682 math.inf is math.inf, math.nan is math.nan # Out: (True, True) float('inf') is float('inf'), float('nan') is float('nan') # Out: (False, False) > python -m timeit 'for x in xrange(50000): b = x**3' 10 loops, best of 3: 51.2 msec per loop > python -m timeit 'from math import pow' 'for x in xrange(50000): b = pow(x,3)' 100 loops, best of 3: 9.15 msec per loop > from math import pow > pow(5,5) 3125.0 z = 1 + 3j 1j * 1j Out: (-1+0j) 1j ** 1j Hay una diferencia sutil entre las versiones float antiguas de NaN e infinito y las constantes de la biblioteca math Python 3.5+: Python 3.x 3.5 Pow para una exponenciación más rápida Usando el módulo timeit desde la línea de comando: El operador ** integrado a menudo es útil, pero si el rendimiento es esencial, use math.pow. Sin embargo, asegúrese de tener en cuenta que pow devuelve flotantes, incluso si los argumentos son enteros: Números complejos y el módulo cmath. El módulo cmath es similar al módulo math , pero define funciones adecuadamente para el plano complejo. En primer lugar, los números complejos son un tipo numérico que forma parte del lenguaje Python en lugar de ser proporcionado por una clase de biblioteca. Por lo tanto, no necesitamos import cmath para expresiones aritméticas ordinarias. Tenga en cuenta que usamos j (o J ) y no i . Debemos usar 1j ya que j sería el nombre de una variable en lugar de un literal numérico. -math.nan # Out: nan
    • 748. 683 # z.conjugate() == z.real - z.imag * 1j z.conjugate() # Out: (1-3j) # real part and imaginary part are bothfloat type z.real, z.imag # Out: (1.0, 3.0) complex(1) # Out: (1+0j) complex(imag=1) # Out: (1j) complex(1, 1) # Out: (1+1j) # square root of 2 abs(1 + 1j) # Out: 1.4142135623730951 complex('1+1j') # Out: (1+1j) complex('1 + 1j') # Exception: ValueError: complex() arg is a malformed string import cmath cmath.sqrt(-1) # Out: 1j import math math.sqrt(-1) # Exception: ValueError: math domain error # == (sqrt(1 + 1), atan2(1, 1)) cmath.polar(1 + 1j) # Out: (1.4142135623730951, 0.7853981633974483) Tenemos la parte real y la parte imag (imaginaria), así como el complejo conjugate : Lasfuncionesintegradasabs ycomplex tambiénsonpartedellenguajeensí ynorequieren ninguna importación: La función complex puede tomar una cadena, pero no puede tener espacios: Pero para la mayoría de las funciones necesitamos el módulo, por ejemplo, sqrt : Naturalmente,el comportamiento de sqrt es diferente para números complejos y números reales. En math no complejas math la raíz cuadrada de un número negativo genera una excepción: Se proporcionan funciones para convertir hacia y desde coordenadas polares: # Out: (0.20787957635076193+0j) # "i to the i" == math.e ** -(math.pi/2)
    • 749. 684 cmath.phase(complex(-1.0, 0.0)) # Out: 3.141592653589793 cmath.phase(complex(-1.0, -0.0)) # Out: -3.141592653589793 cmath.log(1+1j) # Out: (0.34657359027997264+0.7853981633974483j) cmath.exp(1j * cmath.pi) #Out:(-1+1.2246467991473532e-16j) # e to the i pi == -1, within rounding error type(cmath.pi) # Out: <class 'float'> cmath.isinf(complex(float('inf'), 0.0)) # Out: True cmath.isnan(0.0, float('nan')) El campo matemático del análisis complejo está más allá del alcance de este ejemplo, pero muchas funciones en el plano complejo tienen un "corte de rama", generalmente a lo largo del eje real o el eje imaginario. La mayoría de las plataformas modernas admiten el "cero firmado" como se especifica en IEEE 754, que proporciona continuidad de esas funciones en ambos lados del corte de rama. El siguiente ejemplo es de la documentación de Python: El módulo cmath también proporciona muchas funciones con contrapartes directas del módulo math . Además de sqrt , existen versiones complejas de exp , log , log10 , las funciones trigonométricas y sus inverses ( sin , cos , tan , asin , acos , atan ), y las funciones hiperbólicas y sus inverses ( sinh , cosh , tanh , asinh , acosh , atanh ). Sin embargo, tenga en cuenta que no hay una contraparte compleja de math.atan2 , la forma de arctangente de dos argumentos. Se proporcionan las constantes pi y e . Tenga en cuenta que estos son float y no complex . El módulo cmath también proporciona versiones complejas de isinf , y (para Python 3.2+) es isfinite . Ver " Infinito y NaN ". Un número complejo se considera infinito si su parte real o su parte imaginaria es infinita. Asimismo, el módulo cmath proporciona una versión compleja de isnan . Ver " Infinito y NaN ". Un número complejo se considera "no un número" si su parte real o su parte imaginaria no es "un número". cmath.rect(math.sqrt(2), math.atan(1)) # Out: (1.0000000000000002+1.0000000000000002j) # same as previous calculation abs(1 + 1j), cmath.phase(1 + 1j) # Out: (1.4142135623730951, 0.7853981633974483)
    • 750. 685 z = cmath.rect(*cmath.polar(1+1j)) z # Out: (1.0000000000000002+1.0000000000000002j) cmath.isclose(z, 1+1j) # True cmath.isinf(complex(0.0, math.inf)) # Out: True cmath.isnan(complex(math.nan, 0.0)) # Out: True cmath.inf # Exception: AttributeError: module 'cmath' has no attribute 'inf' Tenga en cuenta que no hay cmath contraparte de math.nan constantes math.inf y math.nan (de Python 3.5 y superior) Python 3.x 3.5 EnPython 3.5 y superior, hay una isclose método en ambos cmath y math módulos. Python 3.x 3.5 # Out: True
    • 751. 686 Capítulo 134: Módulo de navegador web Introducción De acuerdo con la documentación estándar de Python, el módulo del navegador web proporciona una interfaz de alto nivel para permitir la visualización de documentos basados en la Web a los usuarios. Este tema explica y demuestra el uso adecuado del módulo de navegador web. Sintaxis • webbrowser.open(url, new=0, autoraise=False) • webbrowser.open_new(url) • webbrowser.open_new_tab(url) • webbrowser.get(usage=None) • webbrowser.register(name, constructor, instance=None) Parámetros Parámetro Detalles webbrowser.open() url La URL para abrir en el navegador web. nuevo 0 abre la URL en la pestaña existente, 1 abre en una nueva ventana, 2 abre en nueva pestaña autoraise si se establece en Verdadero, la ventana se moverá sobre las otras ventanas webbrowser.open_new() url La URL para abrir en el navegador web. webbrowser.open_new_tab() url La URL para abrir en el navegador web. webbrowser.get() utilizando el navegador para usar webbrowser.register() url nombre del navegador constructor ruta al navegador ejecutable ( ayuda ) ejemplo Una instancia de un navegador web devuelto por el método
    • 752. 687 Parámetro Detalles webbrowser.get() Observaciones Lasiguientetablaenumeralos tiposdenavegadorpredefinidos.Lacolumnadelaizquierda son nombres que se pueden pasar al método webbrowser.get() y la columna de la derecha enumera los nombres de clase para cada tipo de navegador. Escribe un nombre Nombre de la clase 'mozilla' Mozilla('mozilla') 'firefox' Mozilla('mozilla') 'netscape' Mozilla('netscape') 'galeon' Galeon('galeon') 'epiphany' Galeon('epiphany') 'skipstone' BackgroundBrowser('skipstone') 'kfmclient' Konqueror() 'konqueror' Konqueror() 'kfm' Konqueror() 'mosaic' BackgroundBrowser('mosaic') 'opera' Opera() 'grail' Grail() 'links' GenericBrowser('links') 'elinks' Elinks('elinks') 'lynx' GenericBrowser('lynx') 'w3m' GenericBrowser('w3m') 'windows-default' WindowsDefault 'macosx' MacOSX('default') 'safari' MacOSX('safari') 'google-chrome' Chrome('google-chrome') 'chrome' Chrome('chrome') 'chromium' Chromium('chromium') 'chromium-browser' Chromium('chromium-browser')
    • 753. 688 import webbrowser webbrowser.open("http://stackoverflow.com") import webbrowser webbrowser.open_new("http://stackoverflow.com") import webbrowser webbrowser.open_new_tab("http://stackoverflow.com") import webbrowser ff_path = webbrowser.get("C:/Program Files/Mozilla Firefox/firefox.exe") ff = webbrowser.get(ff_path) ff.open("http://stackoverflow.com/") Examples Abrir una URL con el navegador predeterminado Para abrir simplemente una URL, use el método webbrowser.open() : Si una ventana del navegador está actualmente abierta, el método abrirá una nueva pestaña en la URL especificada. Si no hay ninguna ventana abierta, el método abrirá el navegador predeterminado del sistema operativo y navegará a la URL en el parámetro. El método abierto soporta los siguientes parámetros: • url : la URL que se abrirá en el navegador web (cadena) [requerido] • new : 0 se abre en la pestaña existente, 1 abre una nueva ventana, 2 abre una nueva pestaña (entero) [predeterminado 0] • autoraise : si se establece en Verdadero, la ventana se moverá sobre las ventanas de otras aplicaciones (Booleano) [predeterminado Falso] Tengaencuentaquelosargumentosnewyautoraise raravezfuncionan,yaquelamayoríadelos navegadores modernos rechazan estos comandos. El navegador web también puede intentar abrir las URL en nuevas ventanas con el método open_new : Estemétodoescomúnmente ignoradoporlosnavegadores modernos y laURLgeneralmentese abre en una nueva pestaña.El módulo puede intentar abriruna nueva pestaña usando el método open_new_tab : Abrir una URL con diferentes navegadores El módulo del navegador web también admite diferentes navegadores que utilizan los métodos register() y get() . El método de obtención se usa para crear un controlador de navegador utilizando una ruta de archivo ejecutable específica y el método de registro se utiliza para adjuntar estos ejecutables a los tipos de navegador predeterminados para su uso futuro, generalmente cuando se usan múltiples tipos de navegador.
    • 754. 689 import webbrowser ff_path = webbrowser.get("C:/Program Files/Mozilla Firefox/firefox.exe") ff = webbrowser.get(ff_path) webbrowser.register('firefox', None, ff) # Now to refer to use Firefox in the future you can use this webbrowser.get('firefox').open("https://stackoverflow.com/") Registro de un tipo de navegador:
    • 755. 690 # p = 1, d = deque([2, 3]) # d = deque([5, 2, 3]) d = deque([1, 2, 3]) p = d.popleft() d.appendleft(5) from collections import deque Capítulo 135: Módulo Deque Sintaxis • dq = deque () # Crea un deque vacío • dq = deque (iterable) # Crea un deque con algunos elementos • dq.append (objeto) # Agrega un objeto a la derecha del deque • dq.appendleft (objeto) # Agrega un objeto a la izquierda del deque • dq.pop () -> object # Elimina y devuelve el objeto más a la derecha • dq.popleft () -> object # Elimina y devuelve el objeto más a la izquierda • dq.extend (iterable) # Agrega algunos elementos a la derecha del deque • dq.extendleft (iterable) # Agrega algunos elementos a la izquierda del deque Parámetros Parámetro Detalles iterable Crea el deque con elementos iniciales copiados de otro iterable. maxlen Limita qué tan grande puede ser el deque, eliminando elementos antiguos a medida que se agregan nuevos. Observaciones Esta clase esútilcuando necesita un objeto similaraunalista que permitaoperaciones rápidas de agregar y abrir desde cualquier lado (el nombre deque significa " cola de doble extremo "). Los métodos proporcionados son,de hecho, muy similares, excepto que algunos como el pop , el append o la extend pueden incluir con el sufijo left . La estructura de datos de deque debería ser preferible a una lista si uno necesita insertar y eliminar elementos con frecuencia en ambos extremos porque permite hacerlo en tiempo constante O (1). Examples Uso básico deque Los principales métodos que son útiles con esta clase son popleft y appendleft
    • 756. 691 from collections import deque d = deque(maxlen=3) # only holds 3 items d.append(1) # deque([1]) d.append(2) # deque([1, 2]) d.append(3) # deque([1, 2, 3]) d.append(4) # deque([2, 3, 4]) (1 is removed because its maxlen is 3) dl = deque() # deque([]) creating empty deque dl = deque([1, 2, 3, 4]) # deque([1, 2, 3, 4]) dl.append(5) # deque([1, 2, 3, 4, 5]) dl.appendleft(0) # deque([0, 1, 2, 3, 4, 5]) dl.extend([6, 7]) # deque([0, 1, 2, 3, 4, 5, 6, 7]) dl.extendleft([-2, -1]) # deque([-1, -2, 0, 1, 2, 3, 4, 5, 6, 7]) dl.pop() # 7 => deque([-1, -2, 0, 1, 2, 3, 4, 5, 6]) dl.popleft() # -1 deque([-2, 0, 1, 2, 3, 4, 5, 6]) límite de tamaño de salida Use el parámetro maxlen mientras crea un deque para limitar el tamaño del deque: Métodos disponibles en deque. Creando deque vacío: Creando deque con algunos elementos: Añadiendo elemento a deque: Añadiendo elemento del lado izquierdo del deque: Añadiendo lista de elementos a deque: Añadiendo lista de elementos desde el lado izquierdo: El uso del elemento .pop() eliminará naturalmente un elemento del lado derecho: Usando el elemento .popleft() para eliminar un elemento del lado izquierdo: Eliminar elemento por su valor:
    • 757. 692 dl.reverse() # deque([6, 5, 4, 3, 2, 0, -2]) from collections import deque def bfs(graph, root): distances = {} distances[root] = 0 q = deque([root]) while q: # The oldest seen (but not yet visited) node will be the left most one. current = q.popleft() for neighbor in graph[current]: if neighbor not in distances: distances[neighbor] = distances[current] + 1 # When we see a new node, we add it to the right side of the queue. q.append(neighbor) return distances graph = {1:[2,3], 2:[4], 3:[4,5], 4:[3,5], 5:[]} >>> bfs(graph, 1) {1: 0, 2: 1, 3: 1, 4: 2, 5: 2} >>> bfs(graph, 3) {3: 0, 4: 1, 5: 1} Invertir el orden de los elementos en deque: Amplia primera búsqueda Deque es la única estructura de datos de Python con operaciones rápidas de cola . (Tenga en cuenta queue.Queue normalmente no es adecuado, ya que está destinado a la comunicación entre subprocesos). Un caso de uso básico de una cola es la primera búsqueda de amplitud . Digamos que tenemos un gráfico dirigido simple: Ahora podemos encontrar las distancias desde alguna posición inicial: dl.remove(1) # deque([-2, 0, 2, 3, 4, 5, 6])
    • 758. 693 lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 5, 6)] testGroupBy(lst) lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 2, 6)] def testGroupBy(lst): groups = itertools.groupby(lst, key=lambda x: x[1]) for key, group in groups: print(key, list(group)) testGroupBy(lst) # 5 [('a', 5, 6)] # 2 [('b', 2, 4), ('a', 2, 5), ('c', 2, 6)] lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 2, 6)] groups = itertools.groupby(lst, key=lambda x: x[1]) for key, group in sorted(groups): print(key, list(group)) # 2 [('c', 2, 6)] # 5 [] Capítulo 136: Módulo Itertools Sintaxis • import itertools Examples Agrupando elementos de un objeto iterable usando una función Comenzar con un iterable que necesita ser agrupado. Genere el generador agrupado, agrupando por el segundo elemento en cada tupla: Sólo se agrupan grupos de elementos consecutivos. Es posible que deba ordenar por la misma clave antes de llamar a groupby For Eg, (el último elemento ha cambiado) # 5 [('a', 5, 6)] # 2 [('b', 2, 4), ('a', 2, 5)] # 5 [('c', 5, 6)] El grupo devuelto por groupby es un iterador que no será válido antes de la próxima iteración. Por ejemplo, lo siguiente no funcionará si desea que los grupos se ordenen por clave. El grupo 5 está vacío a continuación porque cuando se busca el grupo 2 invalida 5 Para realizar correctamente la clasificación, cree una lista desde el iterador antes de ordenar
    • 759. 694 results = fetch_paged_results() # returns a generator limit = 20 # Only want the first 20 results for data in itertools.islice(results, limit): print(data) def gen(): n = 0 while n < 20: n += 1 yield n for part in gen()[:3]: print(part) Traceback (most recent call last): File "gen.py",line 6, in <module> for part in gen()[:3]: TypeError: 'generator' object is not subscriptable import itertools def gen(): n = 0 while n < 20: n += 1 yield n for part in itertools.islice(gen(), 3): print(part) itertools.islice(iterable, 1, 30, 3) Toma una rebanada de un generador Itertools "islice" le permite cortar un generador: Normalmente no se puede cortar un generador: Daré Sin embargo, esto funciona: Tenga en cuenta que al igual que una división normal, también puede usar los argumentos de start , stop y step : groups = itertools.groupby(lst, key=lambda x: x[1]) for key, group in sorted((key, list(group)) for key, group in groups): print(key, list(group)) # 2 [('b', 2, 4), ('a', 2, 5), ('c', 2, 6)] # 5 [('a', 5, 6)]
    • 760. 695 for x in xrange(10): for y in xrange(10): print x, y its = [xrange(10)] * 2 for x,y in itertools.product(*its): print x, y >>> from itertools import product >>> a=[1,2,3,4] >>> b=['a','b','c'] >>> product(a,b) <itertools.product object at 0x0000000002712F78> >>> for i in product(a,b): ... print i ... (1, 'a') (1, 'b') (1, 'c') (2, 'a') (2, 'b') (2, 'c') (3, 'a') (3, 'b') (3, 'c') (4, 'a') (4, 'b') (4, 'c') itertools.product Esta función le permite recorrer el producto cartesiano de una lista de iterables. Por ejemplo, es equivalente a Como todas las funciones de python que aceptan un número variable de argumentos, podemos pasar una lista a itertools.product para desempaquetar, con el operador *. Así, produce los mismos resultados que los dos ejemplos anteriores. itertools.count Introducción: Esta simple función genera infinitas series de números. Por ejemplo... for x, y in itertools.product(xrange(10), xrange(10)): print x, y
    • 761. 696 for number in itertools.count(start=10, step=4): print(number) if number > 20: break 10 14 18 22 def is_even(x): return x % 2 == 0 lst = [0, 2, 4, 12, 18, 13, 14, 22, 23, 44] result = list(itertools.takewhile(is_even, lst)) print(result) Tenga en cuenta que hay que romper o se imprime para siempre! Salida: Argumentos: count() toma dos argumentos, start y step : Salida: itertools.takewhile itertools.takewhile le permite tomar elementos de una secuencia hasta que una condición se convierte en False . Esto produce [0, 2, 4, 12, 18] . 0 1 2 3 4 5 6 7 8 9 10 for number in itertools.count(): if number > 20: break print(number)
    • 762. 697 def takewhile(predicate, iterable): for x in iterable: if predicate(x): yield x else: break def is_even(x): return x % 2 == 0 lst = [0, 2, 4, 12, 18, 13, 14, 22, 23, 44] result = list(itertools.dropwhile(is_even, lst)) print(result) def dropwhile(predicate, iterable): iterable = iter(iterable) for x in iterable: if not predicate(x): yield x break for x in iterable: yield x Tengaencuentaque, el primer número que violael predicado (es decir,la funciónque devuelve un valor booleano) is_even is, 13 . Una vez que takewhile encuentra un valor que produce False para el predicado dado, se rompe. La salida producida por takewhile es similar a la salida generada a partir del código siguiente. Nota: La concatenación de los resultados producidos por takewhile y dropwhile produce el iterable original. result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst)) itertools.dropwhile itertools.dropwhile le permite tomar elementos de una secuencia después de que una condición se convierte en False . Esto da como resultado [13, 14, 22, 23, 44] . ( Este ejemplo es el mismo que el de takewhile pero usando dropwhile) . Tenga en cuenta que, el primer número que viola el predicado (es decir, la función que devuelve un valor booleano) is_even is, 13 . Todos los elementos antes de eso, se descartan. La salida producida por dropwhile es similar a la salida generada a partir del código a continuación. La concatenación de los resultados producidos por takewhile y dropwhile produce el iterable
    • 763. 698 from itertools import zip_longest a = [i for i in range(5)] # Length is 5 b = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] # Length is 7 for i in zip_longest(a, b): x, y = i # Note that zip longest returns the values as a tuple print(x, y) for i in zip_longest(a, b, fillvalue='Hogwash!'): x, y = i # Note that zip longest returns the values as a tuple print(x, y) a = [1,2,3,4,5] b = list(itertools.combinations(a, 2)) print b a = [1,2,3,4,5] b = list(itertools.combinations(a, 3)) original. result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst)) Zipping dos iteradores hasta que ambos están agotados Similar alafunción incorporada zip() , itertools.zip_longest continuará iterando más allá del final del más corto de los dos iterables. Sepuedepasarunargumentodevalordefillvalue opcional(predeterminadoa'' )dela siguiente manera: En Python 2.6 y 2.7, esta función se llama itertools.izip_longest . Método de combinaciones en el módulo Itertools itertools.combinations devolverá un generador de la secuencia de combinación k de una lista. En otras palabras: devolverá un generador de tuplas de todas las combinaciones posibles de k de la lista de entrada. Por ejemplo: Si tienes una lista: Salida: [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)] Lasalidaanterioresun generador convertido auna lista de tuplas de todas las combinaciones posibles de pares de la lista de entradaa También puedes encontrar todas las 3 combinaciones:
    • 764. 699 from itertools import chain a = (x for x in ['1', '2', '3', '4']) b = (x for x in ['x', 'y', 'z']) ' '.join(chain(a, b)) '1 2 3 4 x y z' ' '.join(chain.from_iterable([a,b]) >>> import itertools >>> for i in itertools.repeat('over-and-over', 3): ... print(i) over-and-over over-and-over over-and-over >>> import itertools as it >>> import operator Salida: [(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (1, 4, 5), (2, 3, 4), (2, 3, 5), (2, 4, 5), (3, 4, 5)] Encadenando múltiples iteradores juntos Use itertools.chain para crear un solo generador que produzca los valores de varios generadores en secuencia. Resultados en: Como constructor alternativo, puede usar el método chain.from_iterable que toma como único parámetro un iterable de iterables. Para obtener el mismo resultado que arriba: Mientras que chain puede tomar un número arbitrario de argumentos, chain.from_iterable es la única manera de encadenar un número infinito de iterables. itertools.repeat Repetir algo n veces: Obtener una suma acumulada de números en un iterable Python 3.x 3.2 accumulate rendimientos una suma acumulada (o producto) de números. print b
    • 765. 700 >>> import itertools as it >>> it.cycle('ABCD') A B C D A B C D A B C D ... >>> # Iterate over each element in cycle for a fixed range >>> cycle_iterator = it.cycle('abc123') >>> [next(cycle_iterator) for i in range(0, 10)] ['a', 'b', 'c', '1', '2', '3', 'a', 'b', 'c', '1'] a = [1,2,3] list(itertools.permutations(a)) # [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)] list(itertools.permutations(a, 2)) [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)] a = [1,2,1] list(itertools.permutations(a)) # [(1, 2, 1), (1, 1, 2), (2, 1, 1), (2, 1, 1), (1, 1, 2), (1, 2, 1)] set(itertools.permutations(a)) # {(1, 1, 2), (1, 2, 1), (2, 1, 1)} Recorre los elementos en un iterador cycle es un iterador infinito. Por lo tanto, tenga cuidado de dar límites al usar esto para evitar un bucle infinito. Ejemplo: itertools.permutaciones itertools.permutationsdevuelve ungenerador conpermutaciones sucesivas delongitud rde elementos en el iterable. Silalistaa tieneelementosduplicados,laspermutaciones resultantestendránelementos duplicados, puede usar set para obtener permutacionesúnicas: >>> list(it.accumulate([1,2,3,4,5])) [1, 3, 6, 10, 15] >>> list(it.accumulate([1,2,3,4,5], func=operator.mul)) [1, 2, 6, 24, 120]
    • 766. 701 nulo Ninguna verdadero Falso Verdadero Falso numero (real) flotador número (int) En t cuerda str formación lista objeto dictado JSON Pitón Capítulo 137: Módulo JSON Observaciones Para obtener la documentación completa, incluida la funcionalidad específica de la versión, consulte la documentación oficial . Los tipos Valores predeterminados El módulo json manejará la codificación y decodificación de los siguientes tipos de manera predeterminada: Tipos de serialización: El módulo json también entiende NaN , Infinity e -Infinity como sus valores flotantes correspondientes, que están fuera de la especificación JSON. Tipos de serialización: Pitón JSON dictado objeto lista, tupla formación str cuerda
    • 767. 702 # my_json module import json from functools import partial def serialise_object(obj): # Do something to produce json-serialisable data return dict_obj dump = partial(json.dump, default=serialise_object) dumps = partial(json.dumps, default=serialise_object) # my_json module import json from functools import partial def deserialise_object(dict_obj): # Do something custom return obj def deserialise_float(str_obj): # Do something custom return obj Pitón JSON Enums, float, (int / float) -derived Cierto número cierto Falso falso Ninguna nulo Para no permitir la codificación de NaN , Infinity e -Infinity , debe codificar con allow_nan=False . Esto generará un ValueError si intenta codificar estos valores. Personalización (des) serialización Existen varios enlaces que le permiten manejar datos que deben representarse de manera diferente. El uso de functools.partial permite aplicar parcialmente los parámetros relevantes a estas funciones para su comodidad. Publicación por entregas: Puede proporcionar una función que opere en objetos antes de que se serialicen así: De serialización: Hay varios enlaces que son manejados por las funciones json, como object_hook y parse_float. Para obtener una lista exhaustiva de su versión de python, consulte aquí .
    • 768. 703 # my_json module import json from functools import partial class MyEncoder(json.JSONEncoder): # Do something custom class MyDecoder(json.JSONDecoder): # Do something custom dump = partial(json.dump, cls=MyEncoder) dumps = partial(json.dumps, cls=MyEncoder) load = partial(json.load, cls=MyDecoder) loads = partial(json.loads, cls=MyDecoder) import json d = { 'foo': 'bar', 'alice': 1, 'wonderland': [1, 2, 3] } json.dumps(d) '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}' import json s = '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}' json.loads(s) Mayor (des) serialización personalizada: Elmódulo json también permite la extensión / sustitución de json.JSONEncoder yjson.JSONDecoder para manejar varios tipos.Losganchos documentados anteriormente se pueden agregar como valores predeterminados creando un método de nombre equivalente. Para usarlos, simplemente pase la clase como el parámetro cls a la función relevante. El uso de functools.partial permite aplicar parcialmente el parámetro cls a estas funciones por conveniencia, por ejemplo, Examples Creando JSON desde el dictado de Python El fragmento de código anterior devolverá lo siguiente: Creando el dictado de Python desde JSON El fragmento de código anterior devolverá lo siguiente: load = partial(json.load, object_hook=deserialise_object, parse_float=deserialise_float) loads = partial(json.loads, object_hook=deserialise_object, parse_float=deserialise_float)
    • 769. 704 import json d = { 'foo': 'bar', 'alice': 1, 'wonderland': [1, 2, 3] } with open(filename, 'w') as f: json.dump(d, f) import json with open(filename, 'r') as f: d = json.load(f) import json data = {u"foo": u"bar", u"baz": []} json_string = json.dumps(data) # u'{"foo": "bar", "baz": []}' json.loads(json_string) # {u"foo": u"bar", u"baz": []} import json from io import StringIO Almacenamiento de datos en un archivo El siguiente fragmento de código codifica los datos almacenados en d en JSON y los almacena en un archivo (reemplace el filename con el nombre real del archivo). Recuperando datos de un archivo El siguiente fragmento de código abre un archivo codificado JSON (reemplaza el filename con el nombre real del archivo) y devuelve el objeto que está almacenado en el archivo. `load` vs` loads`, `dump` vs` dumps` El módulo json contiene funciones para leer y escribir en y desde cadenas de Unicode, y para leer y escribir en y desde archivos. Estos se diferencian por una s final en el nombre de la función. En estos ejemplos, usamos un objeto StringIO, pero las mismas funciones se aplicarían a cualquier objeto similar a un archivo. Aquí usamos las funciones basadas en cadenas: Y aquí usamos las funciones basadas en archivos: {u'alice': 1, u'foo': u'bar', u'wonderland': [1, 2, 3]}
    • 770. 705 import json json_file_path = './data.json' data={u"foo": u"bar",u"baz":[]} with open(json_file_path, 'w') as json_file: json.dump(data, json_file) with open(json_file_path) as json_file: json_file_content = json_file.read() # u'{"foo": "bar", "baz": []}' with open(json_file_path) as json_file: json.load(json_file) # {u"foo": u"bar", u"baz": []} # loading from a file data = [json.loads(line) for line in open(file_path).splitlines()] # dumping to a file with open(file_path, 'w') as json_file: for item in data: json.dump(item, json_file) json_file.write('\n') {"foo": {"bar": {"baz": 1}}} Como puede ver, la principal diferencia es que al descargar datos json debe pasar el identificador de archivo a la función, en lugar de capturar el valor de retorno. También vale la pena señalar que debe buscar el inicio del archivo antes de leer o escribir, para evitar la corrupción de datos. Al abrir un archivo, el cursor se coloca en la posición 0 , por lo que lo siguiente también funcionaría: Tenerlas dos formas de tratar conlos datos jsonlepermite trabajar de manera idiomática y eficiente con los formatos que se basan en json, como json-per-line de pyspark : Llamando a `json.tool` desde la línea de comandos a la salida JSON de impresión bonita Dado un archivo JSON "foo.json" como: podemos llamar al módulo directamente desde la línea de comando (pasando el nombre del archivo como un argumento) para imprimirlo en forma bonita: json_file = StringIO() data = {u"foo": u"bar", u"baz": []} json.dump(data, json_file) json_file.seek(0) # Seek back to the start of the file before reading json_file_content = json_file.read() # u'{"foo": "bar", "baz": []}' json_file.seek(0) # Seek back to the start of the file before reading json.load(json_file) # {u"foo": u"bar", u"baz": []}
    • 771. 706 $ cat foo.json | python -m json.tool >>> data = {"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]} >>> print(json.dumps(data)) {"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]} >>> print(json.dumps(data, indent=2)) { "cats": [ { "name": "Tubbs", "color": "white" }, { "name": "Pepper", "color": "black" } ] } El módulo también recibirá información de STDOUT, por lo que (en Bash) también podríamos hacer: Formato de salida JSON Digamos que tenemos los siguientes datos: Simplemente descartando esto como JSON no hace nada especial aquí: Configuración de sangría para obtener una salida más bonita Si queremos una impresión bonita, podemos establecer un tamaño de indent : Ordenando las teclas alfabéticamente para $ python -m json.tool foo.json { "foo": { "bar": { "baz": 1 } } }
    • 772. 707 >>> print(json.dumps(data, sort_keys=True)) {"cats": [{"color": "white", "name": "Tubbs"}, {"color": "black", "name": "Pepper"}]} >>>print(json.dumps(data, separators=(',', ':'))) {"cats":[{"name":"Tubbs","color":"white"},{"name":"Pepper","color":"black"}]} import json from datetime import datetime data = {'datetime': datetime(2016, 9, 26, 4, 44, 0)} print(json.dumps(data)) class DatetimeJSONEncoder(json.JSONEncoder): def default(self, obj): try: return obj.isoformat() except AttributeError: # obj has no isoformat method; let the builtin JSON encoder handle it return super(DatetimeJSONEncoder, self).default(obj) encoder = DatetimeJSONEncoder() print(encoder.encode(data)) # prints {"datetime": "2016-09-26T04:44:00"} obtener un resultado consistente Por defecto, el orden de las teclas en la salida no está definido. Podemos obtenerlos en orden alfabético para asegurarnos de que siempre obtengamos la misma salida: Deshacerse de los espacios en blanco para obtener una salida compacta Podríamosquererdeshacernosdelosespaciosinnecesarios,loquesehaceconfigurando cadenas separadoras diferentes de las predeterminadas ', 'y ': ': JSON que codifica objetos personalizados Si solo intentamos lo siguiente: recibimosunerrorquedicequeTypeError: datetime.datetime(2016, 9,26, 4,44)isnotJSON serializable . Para poder serializar correctamente el objeto de fecha y hora, necesitamos escribir un código personalizado sobre cómo convertirlo: y luego use esta clase de codificador en lugar de json.dumps :
    • 773. 708
    • 774. 709 1 + 1 # Output: 2 from operator import add add(1, 1) # Output: 2 from operator import mul mul('a', 10) # Output: 'aaaaaaaaaa' mul([3], 3) # Output: [3, 3, 3] from operator import methodcaller list(filter(methodcaller('startswith', 'd'), alist)) # Does the same but is faster. # Output: ['duck'] from itertools import groupby from operator import itemgetter adict = {'a': 1, 'b': 5, 'c': 1} Capítulo 138: Módulo operador Examples Operadores como alternativa a un operador infijo. Para cada operador de infijo, por ejemplo, + hay una función de operator ( operator.add para + ): aunque la documentación principal indica que para los operadores aritméticos solo se permite la entrada numérica, es posible: Vea también: asignación de la función de operación a operador en la documentación oficial de Python . Methodcaller En lugar de esta función lambda que llama explícitamente al método: alist = ['wolf', 'sheep', 'duck'] list(filter(lambda x: x.startswith('d'), alist)) # Output: ['duck'] # Keep only elements that start with 'd' uno podría usar una función de operador que hace lo mismo: Itemgetter Agrupando los pares clave-valor de un diccionario por el valor con itemgetter :
    • 775. 710 dict((i, dict(v)) for i, v in groupby(adict.items(), lambda x: x[1])) alist_of_tuples = [(5,2), (1,3), (2,2)] sorted(alist_of_tuples, key=itemgetter(1,0)) # Output: [(2, 2), (5, 2), (1, 3)] que es equivalente (pero más rápido) a una función lambda como esta: O clasificando una lista de tuplas por el segundo elemento primero el primer elemento como secundario: dict((i, dict(v)) for i, v in groupby(adict.items(), itemgetter(1))) # Output: {1: {'a': 1, 'c': 1}, 5: {'b': 5}}
    • 776. 711 pyautogui.displayMousePosition() #gave you the current mouse position but should be done on terminal. #move the cursor relative to your current position. #it will click on the position mention there #it will drag the mouse relative to position moveRel() click(337,46) dragRel() moveTo(200,0,duration=1.5) #move the cursor to (200,0) position with 1.5 second delay #gave you the size of the screen #return current position of mouse size() position() typewrite(['a','b','left','left','X','Y']) pyautogui.KEYBOARD_KEYS #get the list of all the keyboard_keys. pyautogui.hotkey('ctrl','o') #for the combination of keys to enter. typewrite('') #this will type the string on the screen where current window has focused. .screenshot('c:\\path') #get the screenshot. .locateOnScreen('c:\\path') #search that image on screen and get the coordinates for you. locateCenterOnScreen('c:\\path') #get the coordinate for the image on screen. Capítulo 139: módulo pyautogui Introducción pyautogui es un módulo usado para controlar el mouse y el teclado. Este módulo se usa básicamente para automatizar el clic del mouse y las tareas de pulsación del teclado. Para el mouse, las coordenadas de la pantalla (0,0) comienzan desde la esquina superior izquierda. Si está fuera de control, mueva rápidamente el cursor del mouse hacia la parte superior izquierda, tomará el control del mouse y el teclado del Python y se lo devolverá. Examples Funciones del mouse Estas son algunas de las funciones útiles del mouse para controlar el mouse. Funciones del teclado Estas son algunas de las funciones útiles del teclado para automatizar la pulsación de teclas. ScreenShot y reconocimiento de imágenes Esta función te ayudará a tomar la captura de pantalla y también a relacionar la imagen con la parte de la pantalla.
    • 777. 712 import sqlite3 conn = sqlite3.connect('example.db') c = conn.cursor() # Create table c.execute('''CREATETABLE stocks (date text, trans text, symbol text, qty real, price real)''') # Insert a row of data c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") # Save (commit) the changes conn.commit() # We can also close the connection if we are done with it. # Just be sure any changes have been committed or they will be lost. conn.close() print c.fetchone() Capítulo 140: Módulo Sqlite3 Examples Sqlite3 - No requiere proceso de servidor separado. El módulo sqlite3 fue escrito por Gerhard Häring. Para usar el módulo, primero debe crear un objeto de conexión que represente la base de datos. Aquí los datos se almacenarán en el archivo example.db: También puede proporcionar el nombre especial: memoria: para crear una base de datos en la RAM. Una vez que tenga una conexión, puede crear un objeto Cursor y llamar a su método execute () para ejecutar comandos SQL: Obtención de los valores de la base de datos y manejo de errores. Obteniendo los valores de la base de datos SQLite3. Imprimir valores de fila devueltos por consulta de selección Para obtener un solo método fetchone () coincidente import sqlite3 conn = sqlite3.connect('example.db') c = conn.cursor() c.execute("SELECT * from table_name where id=cust_id") for row in c: print row # will be a list
    • 778. 713 a=c.fetchall() #which is similar to list(cursor) method used previously for row in a: print row try: #SQL Code except sqlite3.Error as e: print "An error occurred:", e.args[0] Para filas múltiples use el método fetchall () El manejo de errores se puede hacer usando la función incorporada sqlite3.Error
    • 779. 714 import threading def foo(): print "Hello threading!" my_thread = threading.Thread(target=foo) my_thread.start() # prints 'Hello threading!' import requests from threading import Thread from queue import Queue Capítulo 141: Multihilo Introducción Los subprocesos permiten que los programas de Python manejen múltiples funciones a la vez en lugar de ejecutar una secuencia de comandos individualmente. Este tema explica los principios detrás de los hilos y demuestra su uso. Examples Conceptos básicos de multihilo Usando el módulo de threading , se puede iniciar un nuevo subproceso de ejecución creando un nuevo threading.Thread y asigne una función para ejecutar: El parámetro de target referencia a la función (u objeto llamable) que se ejecutará.El subproceso no comenzará la ejecución hasta que se llame al start en el objeto Thread . Comenzando un hilo Ahora que my_thread ha ejecutado y finalizado, al start nuevo, se producirá un RuntimeError . Si deseaejecutar suhilo comoundemonio,pasar el daemon=True kwarg,oconfigurar my_thread.daemon en True antes de llamar a start(), hace que su Thread ejecute silenciosamente en segundo plano como un demonio. Unirse a un hilo En los casos en que divide un trabajo grande en varios pequeños y desea ejecutarlos simultáneamente, pero debe esperar a que todos terminen antes de continuar, Thread.join() es el método que está buscando. Por ejemplo, supongamos que desea descargar varias páginas de un sitio web y compilarlas en una sola página. Tu harias esto
    • 780. 715 # print 'The main program continuesto run in foreground.' t.join() print("The main program continues to run in the foreground.") t.start() # start method automatic call Thread class run method. from threading import Thread import time class Sleepy(Thread): def run(self): time.sleep(5) print("Hello form Thread") if name == " main ": t = Sleepy() Una mirada más cercana a cómo funciona join() se puede encontrar aquí . Crear una clase de hilo personalizado Usando la clase threading.Thread podemos subclasificar la nueva clase Thread personalizada. debemos anular el método de run en una subclase. Comunicando entre hilos Haymúltipleshilosen sucódigo ynecesita comunicarse de forma seguraentre ellos. Puede utilizar una Queue de la biblioteca de queue . from queue import Queue q = Queue(maxsize=20) def put_page_to_q(page_num): q.put(requests.get('http://some-website.com/page_%s.html' % page_num) def compile(q): # magic function that needs all pages before being able to be executed if not q.full(): raise ValueError else: print("Done compiling!") threads = [] for page_num in range(20): t = Thread(target=requests.get, args=(page_num,)) t.start() threads.append(t) # Next, join all threads to make sure all threads are done running before # we continue. join() is a blocking call (unless specified otherwise using # the kwarg blocking=False when callingjoin) for t in threads: t.join() # Call compile() now, since all threads have completed compile(q)
    • 781. 716 q = Queue() t1 = Thread(target=consumer, args=(q,)) t2 = Thread(target=producer, args=(q,)) t1.start() t2.start() from socket import socket, AF_INET, SOCK_STREAM from threading import Thread from queue import Queue def echo_server(addr, nworkers): print('Echo server running at', addr) # Launch the client workers q = Queue() for n in range(nworkers): t = Thread(target=echo_client, args=(q,)) t.daemon = True t.start() # Run the server sock = socket(AF_INET, SOCK_STREAM) sock.bind(addr) sock.listen(5) while True: client_sock, client_addr = sock.accept() q.put((client_sock, client_addr)) echo_server(('',15000), 128) Creación de subprocesos de productor y consumidor con una cola compartida Creando un grupo de trabajadores Usando threading y queue : Utilizando concurrent.futures.Threadpoolexecutor : from threading import Thread # create a data producer def producer(output_queue): while True: data = data_computation() output_queue.put(data) # create a consumer def consumer(input_queue): while True: # retrieve data (blocking) data = input_queue.get() # do something with the data # indicate data has been consumed input_queue.task_done()
    • 782. 717 def split_line(line, cols): if len(line) > cols: new_line = '' # The actual way to send #!/usr/bin/env python2 import threading import Queue import time import sys import subprocess from backports.shutil_get_terminal_size import get_terminal_size printq = Queue.Queue() interrupt = False lines = [] def main(): ptt = threading.Thread(target=printer) # Turn the printer on ptt.daemon = True ptt.start() #Stupid example ofstuffto print for i in xrange(1,100): printq.put(' '.join([str(x) for x in range(1,i)])) stuff to the printer time.sleep(.5) Python Cookbook, 3ra edición, por David Beazley y Brian K. Jones (O'Reilly). Derechos de autor 2013 David Beazley y Brian Jones, 978-1-449-34037-7. Uso avanzado de multihilos Esta sección contendrá algunos de los ejemplos más avanzados realizados utilizando Multithreading. Impresora avanzada (logger) Un hilo que imprime todo se recibe y modifica la salida de acuerdo con el ancho del terminal. Lo bueno es que también la salida "ya escrita" se modifica cuando cambia el ancho del terminal. from socket import AF_INET, SOCK_STREAM, socket from concurrent.futures import ThreadPoolExecutor def echo_server(addr): print('Echo server running at', addr) pool = ThreadPoolExecutor(128) sock = socket(AF_INET, SOCK_STREAM) sock.bind(addr) sock.listen(5) while True: client_sock, client_addr = sock.accept() pool.submit(echo_client, client_sock, client_addr) echo_server(('',15000))
    • 783. 718 import threading import time class StoppableThread(threading.Thread): """Thread class with a stop() method. The thread itself has to check regularly for the stopped() condition.""" def init (self): super(StoppableThread, self). init () self._stop_event = threading.Event() def stop(self): ww = line.split() i = 0 whilelen(new_line)<=(cols-len(ww[i])-1): new_line += ww[i] + '' i += 1 print len(new_line) if new_line == '': return (line, '') return (new_line, ''.join(ww[i:])) else: return (line, '') def printer(): while True: cols, rows = get_terminal_size() # Get the terminal dimensions msg = '#' + '-' * (cols - 2) + '#\n' # Create the try: new_line = str(printq.get_nowait()) if new_line != '!@#EXIT#@!': # A nice way to turn the printer # thread out gracefully lines.append(new_line) printq.task_done() else: printq.task_done() sys.exit() except Queue.Empty: pass #Build the new message to show and split too long lines for line in lines: res = line # The following is to split lines which are # longer than cols. while len(res) !=0: toprint, res = split_line(res, cols) msg += '\n' + toprint # Clear the shell and print the new output subprocess.check_call('clear') # Keep the shell clean sys.stdout.write(msg) sys.stdout.flush() time.sleep(.5) Hilo que se puede detener con un bucle de tiempo
    • 784. 719 Basado en esta pregunta . self._stop_event.set() def join(self, *args, **kwargs): self.stop() super(StoppableThread,self).join(*args, **kwargs) def run() while not self._stop_event.is_set(): print("Still running!") time.sleep(2) print("stopped!"
    • 785. 720 import multiprocessing import time from random import randint def countUp(): i = 0 while i <= 3: print('Up:\t{}'.format(i)) time.sleep(randint(1, 3)) # sleep 1, 2 or 3 seconds i += 1 def countDown(): i = 3 while i >= 0: print('Down:\t{}'.format(i)) time.sleep(randint(1, 3)) # sleep 1, 2 or 3 seconds i -= 1 if name == ' main ': # Initiate the workers. workerUp = multiprocessing.Process(target=countUp) workerDown = multiprocessing.Process(target=countDown) # Start the workers. workerUp.start() workerDown.start() # Join the workers. This will block in the main (parent) process # until the workers are complete. workerUp.join() workerDown.join() Capítulo 142: Multiprocesamiento Examples Ejecutando dos procesos simples Un ejemplo simple de usar múltiples procesos serían dos procesos (trabajadores) que se ejecutan por separado. En el siguiente ejemplo, se inician dos procesos: • countUp() cuenta 1 arriba, cada segundo. • countDown() cuenta 1 abajo, cadasegundo. La salida es la siguiente: Up: 0 Down: 3 Up: 1 Up: 2 Down: 2 Up: 3 Down: 1 Down: 0
    • 786. 721 from multiprocessing import Pool def cube(x): return x ** 3 if name == " main ": pool = Pool(5) result = pool.map(cube, [0, 1, 2, 3]) Uso de la piscina y el mapa Poolesunaclasequeadministravarios Workers(procesos)detrásdeescenaylepermite al programador usar. Pool(5) crea un nuevo pool con 5 procesos, y pool.map funciona igual que el mapa, pero usa varios procesos (la cantidad definida al crear el pool). Se pueden obtener resultados similares utilizando map_async , apply y apply_async que se pueden encontrar en la documentación .
    • 787. 722 >>> a = 1 >>> id(a) 140128142243264 >>> a += 2 >>> a 3 >>> id(a) 140128142243328 >>> stack = "Overflow" >>> stack 'Overflow' >>> id(stack) 140128123955504 >>> stack += " rocks!" >>> stack 'Overflow rocks!' >>> id(stack) 140128123911472 Capítulo 143: Mutable vs Inmutable (y Hashable) en Python Examples Mutable vs inmutable Hay dos tipos de tipos en Python. Tipos inmutables y tipos mutables. Inmutables Un objeto de un tipo inmutable no puede ser cambiado. Cualquier intento de modificar el objeto dará lugar a que se cree una copia. Esta categoría incluye: enteros, flotadores, complejos, cadenas, bytes, tuplas, rangos y conjuntos de imágenes. Para resaltar esta propiedad, vamos a jugar con el id incorporado. Esta función devuelve el identificador único del objeto pasado como parámetro. Si el id es el mismo, este es el mismo objeto. Si cambia, entonces este es otro objeto. (Algunos dicen que esta es realmente la dirección de memoria del objeto, pero ten cuidado con ellos, son del lado oscuro de la fuerza ...) Está bien, 1 no es 3 ... Noticias de última hora ... Tal vez no. Sin embargo, este comportamiento a menudo se olvida cuando se trata de tipos más complejos, especialmente de cadenas. Jajaja ¿Ver? ¡Podemos modificarlo!
    • 788. 723 >>> stack = "Stack" >>> stackoverflow = stack + "Overflow" >>> id(stack) 140128069348184 >>> id(stackoverflow) 140128123911480 s = "" for i in range(1,1000): s += str(i) s += "," No. Si bien parece que podemos cambiar la cadena nombrada por la stack variables, lo que realmente hacemos es crear un nuevo objeto para contener el resultado de la concatenación. Nos engañan porque en el proceso, el objeto antiguo no va a ninguna parte, por lo que se destruye. En otra situación, eso habría sido más obvio: En este caso, está claro que si queremos conservar la primera cadena, necesitamos una copia. ¿Pero es eso tan obvio para otros tipos? Ejercicio Ahora, sabiendo cómo funcionan los tipos inmutables, ¿qué diría usted con el siguiente código? ¿Es sabio? Mutables Un objeto de un tipo mutable se puede cambiar y se cambia in situ . No se realizan copias implícitas. Estacategoríaincluye:listas,diccionarios,bytearraysysets. Sigamos jugando con nuestra pequeña función de id . (Como nota al margen, uso bytes que contienen datos ASCII para aclarar mi punto, pero recuerde que los bytes no están diseñados para contener datos textuales. Que la fuerza me perdone). ¿Que tenemos? Creamos un bytearray, lo modificamos y usando el id , podemos asegurarnos de >>> b = bytearray(b'Stack') >>> b bytearray(b'Stack') >>> b = bytearray(b'Stack') >>> id(b) 140128030688288 >>> b += b'Overflow' >>> b bytearray(b'StackOverflow') >>> id(b) 140128030688288
    • 789. 724 >>> c = b >>> c += b' rocks!' >>> c bytearray(b'StackOverflow rocks!') >>> b bytearray(b'StackOverflow rocks!') >>> id(c) == id(b) True >>> ll = [ [] ]*4 # Create a list of 4 lists to contain our results >>> ll [[], [], [], []] >>> ll[0].append(23) # Add result 23 to first list >>> ll [[23], [23], [23], [23]] >>> # Oops... >>> def list_add3(lin): lin += [3] return lin >>> a = [1, 2, 3] >>> b = list_add3(a) que este es el mismo objeto, modificado. No es una copia de eso. Por supuesto, si un objeto se va a modificar con frecuencia, un tipo mutable hace un trabajo mucho mejor que un tipo inmutable. Desafortunadamente, la realidad de esta propiedad a menudo se olvida cuando más duele. Bueno... Waiiit un segundo ... En efecto. c no es una copia de b . c es b . Ejercicio Ahora que entiendes mejor qué efecto secundario implica un tipo mutable, ¿puedes explicar qué está mal en este ejemplo? Mutables e inmutables como argumentos Uno de los principales casos de uso cuando un desarrollador necesita tener en cuenta la mutabilidad es cuando pasa argumentos a una función. Esto es muy importante, ya que esto determinará la capacidad de la función para modificar objetos que no pertenecen a su alcance, o en otras palabras, si la función tiene efectos secundarios. Esto también es importante para comprender dónde debe estar disponible el resultado de una función.
    • 790. 725 >>> def tuple_add3(tin): tin += (3,) return tin >>> a = (1, 2, 3) >>> b = tuple_add3(a) >>> b (1, 2, 3, 3) >>> a (1, 2, 3) >>> def yoda(prologue, sentence): sentence.reverse() prologue += " ".join(sentence) return prologue >>> focused = ["You must", "stay focused"] >>> saying = "Yoda said: " >>> yoda_sentence = yoda(saying, focused) Aquí,elerrorespensarquelin ,comoparámetrodelafunción,puedemodificarselocalmente. Ensulugar,linya referenciadelmismoobjeto.Comoesteobjetoesmutable,lamodificaciónse realizainsitu,loquesignificaqueelobjetoal quehacenreferenciatantolin comoasemodifica. Noesnecesariodevolverlin ,porqueya tenemosunareferenciaaesteobjetoen formadea . ay b terminan haciendo referencia al mismoobjeto. Esto no es lo mismo para las tuplas. Al comienzo de la función, tin y a referencia del mismo objeto.Pero este es un objeto inmutable. Así que cuando la función intenta modificarla, tin recibir un nuevo objeto con la modificación, mientras que a mantiene una referencia al objeto original. En este caso, devolver tin es obligatorio, o el nuevo objeto se perdería. Ejercicio Nota: el reverse opera en el lugar. ¿Qué opinas de esta función? ¿Tiene efectos secundarios? ¿Es necesaria la devolución? Después de la llamada, ¿cuál es el valor de saying ? De focused ? ¿Qué sucede si se vuelve a llamar a la función con los mismos parámetros? >>> b [1, 2, 3, 3] >>> a [1, 2, 3, 3]
    • 791. 726 from py2neo import authenticate, Graph, Node, Relationship authenticate("localhost:7474", "neo4j", "<pass>") graph = Graph() results = News.objects.todays_news() for r in results: article = graph.merge_one("NewsArticle", "news_id", r) article.properties["title"] = results[r]['news_title'] article.properties["timestamp"] = results[r]['news_timestamp'] article.push() [...] results = News.objects.todays_news() for r in results: article = graph.merge_one("NewsArticle", "news_id", r) if 'LOCATION' in results[r].keys(): for loc in results[r]['LOCATION']: loc = graph.merge_one("Location", "name", loc) try: rel = graph.create_unique(Relationship(article, "about_place", loc)) except Exception, e: print e Capítulo 144: Neo4j y Cypher usando Py2Neo Examples Importación y Autenticación Debe asegurarse de que su base de datos Neo4j existe en localhost: 7474 con las credenciales apropiadas. El objeto graph es su interfaz con la instancia de neo4j en el resto de su código de Python. Más bien, gracias a hacer de esto una variable global, debes mantenerla en el método init una clase. Añadiendo nodos a Neo4j Graph Agregar nodos a la gráfica es bastante simple, graph.merge_one es importante ya que evita elementos duplicados.(Si ejecuta el script dosveces,la segunda vez se actualizará el títuloy no se crearán nuevos nodos para los mismosartículos) timestamp debe ser un número entero ynouna cadena defecha, ya queneo4jrealmente notiene untipode datos de fecha.Esto causaproblemas de clasificación cuando almacena la fechacomo '05 -06-1989 ' article.push() es una llamada que realmente realiza la operación en neo4j. No olvides este paso. Agregando relaciones a Neo4j Graph
    • 792. 727 def get_autocomplete(text): query = """ start n = node(*) where n.name =~ '(?i)%s.*' return n.name,labels(n) limit 10; """ query = query % (text) obj = [] for res in graph.cypher.execute(query): # print res[0],res[1] obj.append({'name':res[0],'entity_type':res[1]}) return res def search_news_by_entity(location,timestamp): query = """ MATCH (n)-[]->(l) where l.name='%s' and n.timestamp='%s' RETURN n.news_id limit 10 """ query = query % (location,timestamp) news_ids = [] for res in graph.cypher.execute(query): news_ids.append(str(res[0])) return news_ids MATCH (n)-[]->(l) where l.name='Donald Trump' RETURN n.date,count(*) order by n.date MATCH (n:NewsArticle)-[]->(l) create_unique es importante para evitar duplicados. Pero por lo demás es una operación bastante sencilla.El nombre de larelación también es importante, ya quelousaríaen casosavanzados. Consulta 1: Autocompletar en títulos de noticias Esta es una consulta de ejemplo para obtenertodos los nodos con el name la propiedad que comienza con el text argumento. Consulta 2: obtener artículos de noticias por ubicación en una fecha en particular Puede usar esta consulta para encontrar todos los artículos de noticias (n) conectados a una ubicación (l) por unarelación. Cypher Query Samples Contar artículos conectados a una persona en particular a lo largo del tiempo. Busque otras personas / ubicaciones conectadas a los mismos artículos de noticias que Trump con al menos 5 nodos de relaciones totales.
    • 793. 728 where l.name='Donald Trump' MATCH (n:NewsArticle)-[]->(m) with m,count(n) as num where num>5 return labels(m)[0],(m.name), num order by num desc limit 10
    • 794. 729 #! /usr/bin/env python class Node: definit (self, cargo=None, next=None): self.car = cargo self.cdr = next def str (self): return str(self.car) def display(lst): if lst: w("%s " % lst) display(lst.cdr) else: w("nil\n") Capítulo 145: Nodo de lista enlazada Examples Escribe un nodo de lista enlazada simple en python Una lista enlazada es: • la lista vacía, representada por Ninguna, o • un nodo que contiene un objeto de carga y una referencia a una lista enlazada.
    • 795. 730 class Foo(object): def init (self): self. bar = None @property def bar(self): if self. bar is None: self. bar = some_expensive_lookup_operation() return self. bar >>> from foobar import Foo >>> foo = Foo() >>> print(foo.bar) # This will take some time since bar is None after initialization 42 >>> print(foo.bar) # This is much faster since bar has a value now 42 class Cash(object): def init (self, value): self.value = value @property def formatted(self): return '${:.2f}'.format(self.value) @formatted.setter Capítulo 146: Objetos de propiedad Observaciones Nota : en Python 2, asegúrese de que su clase herede del objeto (lo que lo convierte en una clase de nuevo estilo) para que todas las características de las propiedades estén disponibles. Examples Usando el decorador @property El decorador de @property se puede utilizar para definir métodos en una clase que actúan como atributos. Un ejemplo en el que esto puede ser útil es cuando se expone información que puede requerir una búsqueda inicial (costosa) y una recuperación sencilla a partir de entonces. Dado algún módulo de foobar.py : Entonces Usando el decorador de propiedad para las propiedades de lectura-escritura Si desea usar @property para implementar un comportamiento personalizado para configurar y obtener, use este patrón:
    • 796. 731 >>> wallet = Cash(2.50) >>> print(wallet.formatted) $2.50 >>> print(wallet.value) 2.5 >>> wallet.formatted = '$123.45' >>> print(wallet.formatted) $123.45 >>> print(wallet.value) 123.45 class BaseClass(object): @property def foo(self): return some_calculated_value() @foo.setter def foo(self, value): do_something_with_value(value) class DerivedClass(BaseClass): @BaseClass.foo.setter def foo(self, value): do_something_different_with_value(value) class A: p = 1234 def getX (self): return self._x def setX (self, value): self._x = value Para usar esto: Anulando solo un captador, configurador o un eliminador de un objeto de propiedad Cuando se hereda de una clase con una propiedad, puede proporcionar una nueva aplicación para una o más de las propiedades getter , setter o deleter funciones, haciendo referencia a la propiedad objeto de la clase padre: También puede agregar un definidor o un eliminador donde antes no había uno en la clase base. Usando propiedades sin decoradores Si bien el uso de la sintaxis decorativa (con la @) es conveniente, también es un poco oculto. Puede utilizar propiedades directamente, sin decoradores. El siguiente ejemplo de Python 3.x muestra esto: def formatted(self, new): self.value = float(new[1:])
    • 797. 732 def getY (self): return self._y def setY (self, value): self._y = 1000 + value # Weird but possible def getY2 (self): return self._y def setY2 (self, value): self._y = value defgetT (self): return self._t def setT (self, value): self._t = value def getU (self): return self._u + 10000 def setU (self, value): self._u = value -5000 x, y, y2 = property (getX, setX), property (getY, setY), property (getY2, setY2) t = property (getT, setT) u = property (getU, setU) A.q = 5678 class B: def getZ (self): return self.z_ def setZ (self, value): self.z_ = value z = property (getZ, setZ) class C: def init (self): self.offset = 1234 def getW (self): return self.w_ + self.offset def setW (self, value): self.w_ = value - self.offset w = property (getW, setW) a1 = A () a2 = A () a1.y2 = 1000 a2.y2 = 2000 a1.x = 5 a1.y = 6
    • 798. 733 a2.x = 7 a2.y = 8 a1.t = 77 a1.u = 88 print (a1.x, a1.y, a1.y2) print (a2.x, a2.y, a2.y2) print (a1.p, a2.p, a1.q, a2.q) print (a1.t, a1.u) b = B () c = C () b.z = 100100 c.z = 200200 c.w = 300300 print (a1.x, b.z, c.z, c.w) print (a1.x, b.z, c.z, c.w) c.w = 400400 c.z = 500500 b.z = 600600
    • 799. 734 x = True y = True z = x and y # z = True x = True y = False z = x and y # z = False x = False y = True z = x and y # z = False x = False y = False z = x and y # z = False x = 1 y = 1 z = x and y # z = y, so z = 1, see `and` and `or` are not guaranteed to be a boolean x = 0 y = 1 z = x and y # z = x, so z = 0 (see above) x = 1 y = 0 z = x and y # z = y, so z = 0 (see above) x = 0 y = 0 z = x and y # z = x, so z = 0 (see above) x = True y = True z = x or y # z = True Capítulo 147: Operadores booleanos Examples y Evalúa el segundo argumento si y solo si ambos argumentos son veraces. De lo contrario se evalúa al primer argumento falsey. Los 1 en el ejemplo anterior se pueden cambiar a cualquier valor verdadero, y los 0 se pueden cambiar a cualquier valor falso. o Evalúa el primer argumento de verdad si alguno de los argumentos es verdadero. Si ambos argumentos son falsey, evalúa el segundo argumento.
    • 800. 735 x = True y = not x # y = False x = False y = not x # y = True >>> def true_func(): ... print("true_func()") ... return True ... >>> def false_func(): ... print("false_func()") ... return False ... >>> true_func() or false_func() true_func() True Los 1 en el ejemplo anterior se pueden cambiar a cualquier valor verdadero, y los 0 se pueden cambiar a cualquier valor falso. no Devuelve lo contrario de la siguiente declaración: Evaluación de cortocircuito Python evalúa mínimamente las expresiones booleanas. x = True y = False z = x or y # z = True x = False y = True z = x or y # z = True x = False y = False z = x or y # z = False x = 1 y = 1 z = x or y # z = x, so z = 1, see `and` and `or` are not guaranteed to be a boolean x = 1 y = 0 z = x or y # z = x, so z = 1 (see above) x = 0 y = 1 z = x or y # z = y, so z = 1 (see above) x = 0 y = 0 z = x or y # z = y, so z = 0 (see above)
    • 801. 736 def or_(a, b): if a: return a else: return b def and_(a, b): if not a: return a else: return b if 3.14 < x < 3.142: print("x is near pi") `and` y` or` no están garantizados para devolver un valor booleano Cuando usa or , devolverá el primer valor en laexpresión si es verdadero, de lo contrario, devolverá ciegamente el segundo valor. Es decir or es equivalente a: Para and , devolverá su primer valor si es falso, de lo contrario, devolverá el último valor: Un simple ejemplo En Python puedes comparar un solo elemento utilizando dos operadores binarios, uno en cada lado: Enmuchos (¿la mayoría?)Lenguajes de programación, estose evaluaría de formacontrariaalas matemáticas regulares: (3.14 < x) < 3.142 , pero en Python se trata como 3.14 < x and x < 3.142 , como la mayoría de los no programadores Esperaría. >>> false_func() or true_func() false_func() true_func() True >>> true_func() and false_func() true_func() false_func() False >>> false_func() and false_func() false_func() False
    • 802. 737 # 60 = 0b111100 # 30 = 0b011110 60 & 30 # Out: 28 # 28 = 0b11100 bin(60 & 30) # Out: 0b11100 Capítulo 148: Operadores de Bitwise Introducción Las operaciones bitwise alteran cadenas binarias en el nivel de bit. Estas operaciones son increíblemente básicas y están directamente soportadas por el procesador. Estas pocas operaciones son necesarias para trabajar con controladores de dispositivo, gráficos de bajo nivel, criptografía y comunicaciones de red. Esta sección proporciona conocimientos útiles y ejemplos de operadores bitwise de Python. Sintaxis • x << y # Bitwise Left Shift • x >> y # Bitwise Right Shift • x & y # Bitwise Y • x | y # Bitwise OR • ~ x # Bitwise NO • x ^ y # Bitwise XOR Examples Y a nivel de bit El operador & realizará un AND binario, donde se copia un bit si existe en ambos operandos. Eso significa: # 0 & 0 = 0 # 0 & 1 = 0 # 1 & 0 = 0 # 1 & 1 = 1 Bitwise o El |eloperadorrealizará un binario "o", donde se copia un bit si existe en cualquiera delos
    • 803. 738 #60=0b111100 #30=0b011110 60 | 30 # Out: 62 # 62 = 0b111110 bin(60 | 30) # Out: 0b111110 # 60 = 0b111100 # 30 = 0b011110 60 ^ 30 # Out: 34 # 34 = 0b100010 bin(60 ^ 30) # Out: 0b100010 # 2 = 0b10 2 << 2 # Out: 8 # 8 = 0b1000 bin(2 << 2) # Out: 0b1000 7 << 1 # Out: 14 operandos. Eso significa: # 0 | 0 = 0 # 0 | 1 = 1 # 1 | 0 = 1 # 1 | 1 = 1 XOR de bitwise (OR exclusivo) El operador ^ realizará un XOR binario en el que se copia un binario 1 si y solo si es el valor de exactamente un operando. Otra forma de afirmar esto es que el resultado es 1 solo si los operandos son diferentes. Ejemplos incluyen: # 0 ^ 0 = 0 # 0 ^ 1 = 1 # 1 ^ 0 = 1 # 1 ^ 1 = 0 Desplazamiento a la izquierda en modo de bits El operador << realizará un "desplazamiento a la izquierda" a nivel de bits, donde el valor del operando izquierdo se mueve a la izquierda por el número de bits dado por el operando derecho. Realizar un cambio de bit a la izquierda de 1 es equivalente a la multiplicación por 2 :
    • 804. 739 3 << 4 # Out: 48 # 8 = 0b1000 8 >> 2 # Out: 2 # 2 = 0b10 bin(8 >> 2) # Out: 0b10 36 >> 1 # Out: 18 15 >> 1 # Out: 7 48 >> 4 # Out: 3 59 >> 3 # Out: 7 Realizar un cambio de bit a la izquierda de n es equivalente a la multiplicación por 2**n : Cambio a la derecha en el modo de bits El operador >> realizará un "desplazamiento a la derecha" a nivel de bits, donde el valor del operando izquierdo se mueve a la derecha por el número de bits dado por el operando derecho. Realizar un cambio de bit a la derecha de 1 es equivalente a la división entera por 2 : Realizar un cambio de bit a la derecha de n es equivalente a la división entera por 2**n : Bitwise NO El operador ~ volteará todos los bits en el número. Dado que las computadoras usan representaciones de números firmados , especialmente la notación de complemento de los dos para codificar números binarios negativos donde los números negativos se escriben con un (1) inicial en lugar de un cero (0). Esto significa que si estuviera usando 8 bits para representar los números del complemento a dos, trataría los patrones de 0000 0000 a 0111 1111 para representar números de 0 a 127 y reservaría 1xxx xxxx para representar números negativos. Números de ocho bits de complemento a dos Bits Valor sin firmar Valor del complemento a dos 0000 0000 0 0
    • 805. 740 # 0 = 0b0000 0000 ~0 # Out: -1 # -1 = 0b1111 1111 # 1 = 0b0000 0001 ~1 # Out: -2 # -2 = 1111 1110 # 2 = 0b0000 0010 ~2 # Out: -3 # -3 = 0b1111 1101 # 123 = 0b0111 1011 ~123 # Out: -124 # -124 = 0b1000 0100 Bits Valor sin firmar Valor del complemento a dos 0000 0001 1 1 0000 0010 2 2 0111 1110 126 126 0111 1111 127 127 1000 0000 128 -128 1000 0001 129 -127 1000 0010 130 -126 1111 1110 254 -2 1111 1111 255 -1 Enesencia,estosignificaquemientras1010 0110tieneunvalor sinsignode166(seobtieneal agregar (128 * 1) + (64 * 0) + (32 * 1) + (16 * 0) + (8 * 0) + (4 * 1) + (2 * 1) + (1 * 0) ), tiene un valor de complemento a dos de -90 (se obtiene al agregar (128 * 1)- (64 * 0)- (32 * 1) - (16 * 0) - (8 * 0) - (4 * 1) - (2 * 1) - (1 * 0) , y complementando el valor). De esta manera, los números negativos varían hasta -128 ( 1000 0000 ). Cero (0) se representa como 0000 0000 , y menos uno (-1) como 1111 1111 . En general, sin embargo, esto significa ~n = -n - 1 . Tenga en cuenta que el efecto general de esta operación cuando se aplica a números positivos se puede resumir: ~n -> -|n+1|
    • 806. 741 # -0 = 0b0000 0000 ~-0 # Out: -1 # -1 = 0b1111 1111 # 0 is the obvious exception to this rule, as -0 == 0 always # -1 = 0b1000 0001 ~-1 # Out: 0 # 0 = 0b0000 0000 # -2 = 0b1111 1110 ~-2 # Out: 1 # 1 = 0b0000 0001 # -123 = 0b1111 1011 ~-123 # Out: 122 # 122 = 0b0111 1010 a = 0b001 a &= 0b010 # a = 0b000 a = 0b001 a |= 0b010 # a = 0b011 a = 0b001 a <<= 2 # a = 0b100 a = 0b100 a >>= 2 # a = 0b001 a = 0b101 a ^= 0b011 # a = 0b110 Y luego, cuando se aplica a números negativos, el efecto correspondiente es: ~-n -> |n-1| Los siguientes ejemplos ilustran esta última regla ... Operaciones in situ Todos los operadores de Bitwise (excepto ~ ) tienen sus propias versiones in situ
    • 807. 742 import operator # contains 2 argument arithmetic functions for the examples a, b = 1, 2 # Using the "+" operator: a + b # = 3 # Using the "in-place" "+=" operator to add and assign: a += b # a = 3 (equivalent to a = a + b) Capítulo 149: Operadores matemáticos simples Introducción Python hace operadores matemáticos comunes por sí mismo, incluyendo división de números enteros y flotantes, multiplicación, exponenciación, suma y resta. El módulo matemático (incluido en todas las versiones estándar de Python) ofrece funciones ampliadas como funciones trigonométricas, operaciones de raíz, logaritmos y muchos más. Observaciones Tipos numéricos y sus metaclases. El módulo de numbers contiene las metaclases abstractas para los tipos numéricos: subclases números.número Números.Integral números.Racional numeros.Real bool ✓ ✓ ✓ ✓ En t ✓ ✓ ✓ ✓ fracciones.Fracción ✓ - ✓ ✓ flotador ✓ - - ✓ complejo ✓ - - - decimal.decimal ✓ - - - - Examples Adición
    • 808. 743 [1, 2, 3] + [4, 5,6] # = [1, 2, 3, 4, 5, 6] "first string " + "second string" # = 'first string second string' # contains 2 argument arithmetic functions # = 1 import operator operator.sub(b, a) a, b = 1, 2 # Using the "-" operator: b - a # = 1 # = 6 import operator operator.mul(a, b) # = 6 a, b = 2, 3 a * b Posibles combinaciones (tipos incorporados): • int e int (da un int) • int y float (da un float) • int y complex (da un complex). • float y float (da un float) • float y complex (da un complex ). • complex y complex (da un complex ). Nota: el operador + también se utiliza para concatenar cadenas, listas y tuplas: Sustracción Posibles combinaciones (tipos incorporados): • int e int (da un int) • int y float (da un float) • int y complex (da un complex). • float y float (da un float) • float y complex (da un complex ). • complex y complex (da un complex ). Multiplicación a = operator.iadd(a, b) # a = 5 since a is set to 3 right before this line # The "+=" operator is equivalent to: operator.add(a, b) # = 5 since a is set to 3 right before this line
    • 809. 744 3 * 'ab' # = 'ababab' 3 * ('a', 'b') # = ('a', 'b', 'a', 'b', 'a', 'b') a, b, c, d, e = 3, 2, 2.0, -3, 10 d / e # = -1 b / a # = 0 d / b # = -2 a / c # = 1.5 a / b # = 1 Posibles combinaciones (tipos incorporados): • int e int (da un int) • int y float (da un float) • int y complex (da un complex). • float y float (da un float) • float y complex (da un complex ). • complex y complex (da un complex ). Nota: el operador * también se utiliza para la concatenación repetida de cadenas, listas y tuplas: División Python hace división de enteros cuando ambos operandos son enteros. El comportamiento de los operadores de división de Python ha cambiado de Python 2.xy 3.x (ver también División de enteros ). Python 2.x 2.7 En Python 2, el resultado del operador '/' depende del tipo de numerador y denominador. Tenga en cuenta que debido a que a y b son int s, el resultado es un int . El resultado siempre se redondea hacia abajo (floored). Debidoaquecesunflotador,elresultadodea / cesunfloat. También puede utilizar el módulo operador: Python 2.x 2.2 import operator # the operator module provides 2-argument arithmetic functions operator.div(a, b) # = 1 operator. div (a, b) # = 1
    • 810. 745 from operator import truediv truediv(a, b) # = 1.5 # = 1.5 # = 1.5 float(a) / b a / float(b) # = 1 # = 1.0 a // b a // c ¿Qué tal si quieres división flotante? Recomendado: De acuerdo (si no desea aplicar a todo el módulo): a / (b * 1.0) # = 1.5 1.0 * a / b # = 1.5 a / b * 1.0 # = 1.0 (careful with order of operations) No recomendado (puede generar TypeError, por ejemplo, si el argumento es complejo): Python 2.x 2.2 El operador '//' en Python 2 fuerza la división de pisos independientemente del tipo. Python 3.x 3.0 EnPython 3, el operador/realizauna división "verdadera"independientemente delos tipos.El operador // realiza la división del piso y mantiene el tipo. a / b e / b a // b a // c # = 1.5 # = 5.0 # = 1 # = 1.0 import operator operator.truediv(a, b) operator.floordiv(a, b) operator.floordiv(a, c) # the operator module provides 2-argument arithmetic functions # = 1.5 # = 1 # = 1.0 Posibles combinaciones (tipos incorporados): • int e int (da un int en Python 2 y un float en Python 3) • int y float (da un float) • int y complex (da un complex). • float y float (da un float) • float y complex (da un complex ). from future import division # applies Python 3 style division to the entire module a / b # = 1.5 a // b # = 1
    • 811. 746 # does so more efficiently # 0, calculates (2 ** 3) % 2, but as per Python docs, a, b, c = 2, 3, 2 pow(2, 3, 2) import math x = 8 math.pow(x, 1/3) # evaluates to 2.0 x**(1/3) # evaluates to 2.0 math.exp(0) # 1.0 math.exp(1) # 2.718281828459045 (e) • complex y complex (da un complex ). Ver PEP 238 para más información. Exponer a, b = 2, 3 (a ** b) # = 8 pow(a, b) # = 8 import math math.pow(a, b) # = 8.0 (always float; does not allow complex results) import operator operator.pow(a, b) # = 8 Otra diferencia entre el pow math.pow y math.pow es que el pow incorporado puede aceptar tres argumentos: Funciones especiales La función math.sqrt(x) calcula la raíz cuadrada de x . import math import cmath c = 4 math.sqrt(c) cmath.sqrt(c) # = 2.0 (always float; does not allow complex results) # = (2+0j) (always complex) Para calcular otras raíces, como una raíz cúbica, aumente el número al recíproco del grado de la raíz. Esto se podría hacer con cualquiera de las funciones exponenciales u operador. La función math.exp(x) calcula e ** x . Lafunciónmath.expm1(x)calculae ** x - 1.Cuandoxespequeño,estoproporcionauna precisión significativamente mejor que math.exp(x) - 1 .
    • 812. 747 # optional base argument. Default is math.e math.log(5, math.e) # = 1.6094379124341003 cmath.log(5) # = (1.6094379124341003+0j) math.log(1000, 10) # 3.0 (always returns float) cmath.log(1000, 10) # (3+0j) # = 1.6094379124341003 import math import cmath math.log(5) # Logarithm base 10 math.log10(100) # = 2.0 cmath.log10(100) # = (2+0j) # = 3.0 # Logarithm base 2 math.log2(8) # Logarithm base e - 1 (higher precision for low values) math.log1p(5) # = 1.791759469228055 a = a + 1 a = a * 2 a += 1 # and a *= 2 Logaritmos De forma predeterminada, la función math.log calcula el logaritmo de un número, base e. Opcionalmente puede especificar una base como segundo argumento. Existen variaciones especiales de la función math.log para diferentes bases. Operaciones in situ Es común que dentro de las aplicaciones se necesite tener un código como este: o Existe un atajo efectivo para estas operaciones in situ: Se puede usar cualquier operador matemático antes del carácter '=' para realizar una operación in situ: math.exp(1e-6) - 1 # 1.0000004999621837e-06 math.expm1(1e-6) # 1.0000005000001665e-06 # exact result # 1.000000500000166666708333341666... math.expm1(0) # 0.0
    • 813. 748 a, b = 1, 2 import math math.sin(a) # returns the sine of 'a' in radians # Out: 0.8414709848078965 math.cosh(b) # returns the inverse hyperbolic cosine of 'b' in radians # Out: 3.7621956910836314 math.atan(math.pi) # returns the arc tangent of 'pi' in radians # Out: 1.2626272556789115 math.hypot(a, b) # returns the Euclidean norm, same as math.sqrt(a*a + b*b) # Out: 2.23606797749979 math.hypot(x2-x1, y2-y1) math.degrees(a) # Out: 57.29577951308232 math.radians(57.29577951308232) # Out: 1.0 • -= disminuir la variable en su lugar • += incrementar la variable en su lugar • *= multiplica la variable en su lugar • /= dividir la variable en su lugar • //= piso divide la variable en su lugar # Python 3 • %= devolver el módulo de la variable en su lugar • **= elevar a una potencia en su lugar Existen otros operadores in situ para los operadores bitwise ( ^ , |etc) Funciones trigonométricas Tengaencuentaquemath.hypot(x, y) tambiéneslalongituddelvector(odistancia euclidiana) desde el origen (0, 0) hasta el punto (x, y) . Para calcular la distancia euclidiana entre dos puntos (x1, y1) y (x2, y2) puede usar math.hypot siguiente manera Para convertir de radianes -> grados y grados -> radianes respectivamente use math.degrees y math.radians Módulo Como en muchos otros idiomas, Python usa el operador % para calcular el módulo. 3 % 4 # 3 10 % 2 # 0 6 % 4 # 2
    • 814. 749 quotient, remainder = divmod(9, 4) # quotient = 2, remainder = 1 as 4 * 2 + 1 == 9 O utilizando el módulo operator : import operator operator.mod(3 , 4) # 3 operator.mod(10 , 2) # 0 operator.mod(6 , 4) # 2 También puedes usar números negativos. -9 % 7 # 5 9 % -7 # -5 -9 % -7 # -2 Si necesita encontrar el resultado de la división y el módulo de enteros, puede usar la función divmod como acceso directo:
    • 815. 750 import cProfile def f(x): return "42!" cProfile.run('f(12)') import cProfile, pstats, StringIO Capítulo 150: Optimización del rendimiento Observaciones Cuando intente mejorar el rendimiento de un script de Python, en primer lugar debería poder encontrar el cuello de botella de su script y tener en cuenta que ninguna optimización puede compensar una mala elección en las estructuras de datos o una falla en el diseño de su algoritmo. La identificación de los cuellos de botella de rendimiento se puede hacer mediante la creación de perfiles de su script. En segundo lugar, no intente optimizar demasiado pronto su proceso de codificación a expensas de la legibilidad / diseño / calidad. Donald Knuth hizo la siguiente declaración sobre la optimización: "Debemos olvidarnos de las pequeñas eficiencias, digamos que aproximadamente el 97% de las veces: la optimización prematura es la raíz de todo mal. Sin embargo, no debemos dejar pasar nuestras oportunidades en ese 3% crítico ". Examples Código de perfil En primer lugar, debe poder encontrar el cuello de botella de su script y tener en cuenta que ninguna optimización puede compensar una mala elección en la estructura de datos o una falla en el diseño de su algoritmo. En segundo lugar, no intente optimizar demasiado pronto su proceso de codificación a expensas de la legibilidad / diseño / calidad. Donald Knuth hizo la siguiente declaración sobre la optimización: "Debemos olvidarnos de las pequeñas eficiencias, digamos que aproximadamente el 97% de las veces: la optimización prematura es la raíz de todo mal. Sin embargo, no debemos dejar pasar nuestras oportunidades en ese 3% crítico". Paraperfilarsucódigotienevariasherramientas:cProfile (oelprofilemáslento)delabiblioteca estándar, line_profiler y timeit . Cada uno de ellos tiene un propósito diferente. cProfile es un generador de perfiles determinístico: se controlan los eventos de llamada de función, retorno de función y excepción, y se realizan intervalos precisos para los intervalos entre estos eventos (hasta 0.001s). La documentación de la biblioteca ([ https://docs.python.org/2/library/profile.html◆◆1]) nos proporciona un caso de uso simple O si prefiere envolver partes de su código existente:
    • 816. 751 3 function calls in 0.000 seconds Ordered by: standard name $ kernprof -l script_to_profile.py @profile def slow_function(a, b, c): ... $ python -m line_profiler script_to_profile.py.lprof Esto creará resultados que se parecen a la tabla a continuación, donde puede ver rápidamente dónde pasa su programa la mayor parte de su tiempo e identificar las funciones para optimizar. ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.000 0.000 <stdin>:1(f) 1 0.000 0.000 0.000 0.000 <string>:1(<module>) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} El módulo line_profiler ([ https://github.com/rkern/line_profilerI [ ]] es útil para tener un análisis línea por línea de su código. Obviamente, esto no es manejable para scripts largos, pero está dirigido a fragmentos. Consulte la documentación para más detalles. La forma más fácil de comenzar es usar el script kernprof tal como se explica en la página del paquete, tenga en cuenta que deberá especificar manualmente la función (es) que desea perfilar. kernprof creará una instancia de LineProfiler y la insertará en el espacio de nombres builtins con el perfil de nombre. Se ha escrito para ser utilizado como decorador, por lo que en su script, decora las funciones que desea perfilar con @profile . El comportamiento predeterminado de kernprof es colocar los resultados en un archivo binario script_to_profile.py.lprof . Puede decirle a kernprof que vea inmediatamente los resultados formateados en el terminal con la opción [-v / - ver]. De lo contrario, puede ver los resultados más tarde así: Finalmente,timeitproporcionaunaformasencilladeprobarunforroounapequeñaexpresión tanto desde la línea de comandos como desde el shell de python. Este módulo responderá preguntas como,¿es másrápidohaceruna listadecomprensiónousarlalist()integradalist() al transformar un conjunto en una lista? Busque la palabra clave de setup o la opción -s para agregar el código deconfiguración. pr = cProfile.Profile() pr.enable() # ... do something ... # ... long ... pr.disable() sortby = 'cumulative' ps = pstats.Stats(pr, stream=s).sort_stats(sortby) ps.print_stats() print s.getvalue()
    • 817. 752 $ python -m timeit '"-".join(str(n) for n in range(100))' 10000 loops, best of 3: 40.3 usec per loop desde una terminal >>> import timeit >>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000) 0.8187260627746582
    • 818. 753 import os os.path.join('a', 'b', 'c') >>> os.path.join('a', 'b', 'c') 'a\b\c' >>> os.path.join('a', 'b', 'c') 'a/b/c' Capítulo 151: os.path Introducción Este módulo implementa algunas funciones útiles en las rutas de acceso. Los parámetros de ruta se pueden pasar como cadenas o bytes. Se recomienda que las aplicaciones representen los nombres de archivo como cadenas de caracteres (Unicode). Sintaxis • os.path.join (a, * p) • os.path.basename (p) • os.path.dirname (p) • os.path.split (p) • os.path.splitext (p) Examples Unir caminos Para unir dos o más componentes de ruta, primero importe el módulo OS de Python y luego use lo siguiente: La ventaja de usar os.path es que permite que el código permanezca compatible en todos los sistemas operativos, ya que utiliza el separador apropiado para la plataforma en la que se está ejecutando. Por ejemplo, el resultado de este comando en Windows será: En un sistema operativo Unix: Camino Absoluto desde el Camino Relativo Utilice os.path.abspath :
    • 819. 754 >>> p = os.path.join(os.getcwd(), 'foo.txt') >>> p '/Users/csaftoiu/tmp/foo.txt' >>> os.path.dirname(p) '/Users/csaftoiu/tmp' >>> os.path.basename(p) 'foo.txt' >>> os.path.split(os.getcwd()) ('/Users/csaftoiu/tmp', 'foo.txt') >>> os.path.splitext(os.path.basename(p)) ('foo', '.txt') os.path.abspath(os.path.join(PATH_TO_GET_THE_PARENT, os.pardir)) path = '/home/john/temp' os.path.exists(path) #this returns false if path doesn't exist or if the path is a broken symbolic link dirname = '/home/john/python' os.path.isdir(dirname) filename = dirname + 'main.py' os.path.isfile(filename) Manipulación de componentes del camino Para separar un componente de la ruta: Obtener el directorio padre Si el camino dado existe. para comprobar si existe el camino dado compruebe si la ruta dada es un directorio, archivo, enlace simbólico, punto de montaje, etc. para comprobar si la ruta dada es un directorio para comprobar si la ruta dada es un archivo >>> os.getcwd() '/Users/csaftoiu/tmp' >>> os.path.abspath('foo') '/Users/csaftoiu/tmp/foo' >>> os.path.abspath('../foo') '/Users/csaftoiu/foo' >>> os.path.abspath('/foo') '/foo'
    • 820. 755 symlink = dirname + 'some_sym_link' os.path.islink(symlink) mount_path = '/home' os.path.ismount(mount_path) para comprobar si el camino dado es enlace simbólico para comprobar si la ruta dada es un punto de montaje
    • 821. 756 orders_df = pd.DataFrame() orders_df['customer_id'] = [1,1,1,1,1,2,2,3,3,3,3,3] orders_df['order_id'] = [1,1,1,2,2,3,3,4,5,6,6,6] orders_df['item'] = ['apples', 'chocolate', 'chocolate', 'coffee', 'coffee', 'apples', 'bananas', 'coffee', 'milkshake', 'chocolate', 'strawberry', 'strawberry'] # And this is how the dataframe looks like: print(orders_df) # First, we define the function that will be applied per customer_id count_number_of_orders = lambda x: len(x.unique()) # And now, we can tranform each group using the logic defined above orders_df['number_of_orders_per_cient'] = ( # Put the results into a new column Capítulo 152: Pandas Transform: Preforma operaciones en grupos y concatena los resultados. Examples Transformada simple Primero, vamos a crear un marco de datos ficticio Suponemos que un cliente puede tener n pedidos, un pedido puede tener m artículos y los artículos se pueden pedir más veces # customer_id order_id item # 0 1 1 apples # 1 1 1 chocolate # 2 1 1 chocolate # 3 1 2 coffee # 4 1 2 coffee # 5 2 3 apples # 6 2 3 bananas # 7 3 4 coffee # 8 3 5 milkshake # 9 3 6 chocolate # 10 3 6 strawberry # 11 3 6 strawberry . . Ahora, usaremos la función de transform pandas para contar el número de pedidos por cliente
    • 822. 757 that is called 'number_of_orders_per_cient' orders_df # Take the original dataframe .groupby(['customer_id'])['order_id'] # Create a seperate group for each customer_id & select the order_id .transform(count_number_of_orders)) # Apply the function to each group seperatly #Inspecting the results... print(orders_df) .transform(multiple_items_per_order)) # Apply the defined function to # Put the results into a new # Take the orders dataframe # Create a seperate group for # Then, we transform each group according to the defined function orders_df['item_duplicated_per_order'] = ( column orders_df .groupby(['order_id'])['item'] each order_id & select the item # Let's try to see if the items were ordered more than once in each orders # First, we define a fuction that will be applied per group def multiple_items_per_order(_items): # Apply .duplicated, which will return True is the item occurs more than once. multiple_item_bool = _items.duplicated(keep=False) return(multiple_item_bool) # Create a dummy dataframe orders_df = pd.DataFrame() orders_df['customer_id'] = [1,1,1,1,1,2,2,3,3,3,3,3] orders_df['order_id'] = [1,1,1,2,2,3,3,4,5,6,6,6] orders_df['item'] = ['apples', 'chocolate', 'chocolate', 'coffee', 'coffee', 'apples', 'bananas', 'coffee', 'milkshake', 'chocolate', 'strawberry', 'strawberry'] # customer_id order_id item number_of_orders_per_cient # 0 1 1 apples 2 # 1 1 1 chocolate 2 # 2 1 1 chocolate 2 # 3 1 2 coffee 2 # 4 1 2 coffee 2 # 5 2 3 apples 1 # 6 2 3 bananas 1 # 7 3 4 coffee 3 # 8 3 5 milkshake 3 # 9 3 6 chocolate 3 # 10 3 6 strawberry 3 # 11 3 6 strawberry 3 Múltiples resultados por grupo Usando funciones de transform que devuelven sub-cálculos por grupo. En el ejemplo anterior, tuvimos un resultado por cliente. Sin embargo, también se pueden aplicar funciones que devuelven valores diferentes para el grupo.
    • 823. 758 each group separately #Inspecting the results... print(orders_df) # customer_id order_id item item_duplicated_per_order # 0 1 1 apples False # 1 1 1 chocolate True # 2 1 1 chocolate True # 3 1 2 coffee True # 4 1 2 coffee True # 5 2 3 apples False # 6 2 3 bananas False # 7 3 4 coffee False # 8 3 5 milkshake False # 9 3 6 chocolate False # 10 3 6 strawberry True # 11 3 6 strawberry True
    • 824. 759 from types import MethodType class Animal(object): def init (self, *args, **kwargs): self.name = kwargs.pop('name', None) or 'Animal' if kwargs.get('walk', None): self.walk = MethodType(kwargs.pop('walk'), self) def walk(self): """ Cause animal instance to walk Walking funcionallity is a strategy, and is intended to be implemented separately by different types of animals. """ message = '{} shouldimplement a walkmethod'.format( self. class . name ) raise NotImplementedError(message) # Here are some different walking algorithms that can be used with Animal def snake_walk(self): print('I am slithering side to side because I am a {}.'.format(self.name)) def four_legged_animal_walk(self): print('I am using all four of my legs to walk because I am a(n) {}.'.format( self.name)) def two_legged_animal_walk(self): print('I am standing up on my two legs to walk because I am a {}.'.format( self.name)) Capítulo 153: Patrones de diseño Introducción Un patrón de diseño es una solución general a un problema común en el desarrollo de software. Este tema de documentación está dirigido específicamente a proporcionar ejemplos de patrones de diseño comunes en Python. Examples Patrón de estrategia Este patrón de diseño se llama patrón de estrategia. Se utiliza para definir una familia de algoritmos, encapsula cada uno de ellos y los hace intercambiables. El patrón de diseño de estrategia permite que un algoritmo varíe independientemente de los clientes que lo utilizan. Por ejemplo, los animales pueden "caminar" de muchas maneras diferentes. Caminar podría considerarse una estrategia que es implementada por diferentes tipos de animales:
    • 825. 760 generic_animal = Animal() king_cobra = Animal(name='King Cobra', walk=snake_walk) elephant = Animal(name='Elephant', walk=four_legged_animal_walk) kangaroo = Animal(name='Kangaroo', walk=two_legged_animal_walk) kangaroo.walk() elephant.walk() king_cobra.walk() # This one will Raise a NotImplementedError to let the programmer # know that the walk method is intended to be used as a strategy. generic_animal.walk() # OUTPUT: # # I am standing up on my two legs to walk because I am a Kangaroo. # I am using all four of my legs to walk because I am a(n) Elephant. # I am slithering side to side because I am a King Cobra. # Traceback (most recent call last): # File "./strategy.py", line 56, in <module> # generic_animal.walk() # File "./strategy.py", line 30, in walk # raise NotImplementedError(message) # NotImplementedError: Animal should implement a walk method Ejecutar este ejemplo produciría el siguiente resultado: Tenga en cuenta que en lenguajes como C ++ o Java, este patrón se implementa utilizando una clase abstracta o una interfaz para definir una estrategia. En Python tiene más sentido simplemente definir algunas funciones externamente que pueden agregarse dinámicamente a una clase usando types.MethodType . Introducción a los patrones de diseño y patrón Singleton. Los patrones de diseño proporcionan soluciones a los commonly occurring problems en el diseño de software. Los patrones de diseño fueron introducidos por primera vez por GoF(Gang of Four) donde describían los patrones comunes como problemas queocurren una y otra vez y soluciones aesos problemas. Los patrones de diseño tienen cuatro elementos esenciales: 1. The pattern name es un identificador que podemos usar para describir un problema de diseño, sus soluciones y consecuencias en una o dos palabras. 2. The problem describe cuándo aplicar el patrón. 3. The solution describe los elementos que conforman el diseño, sus relaciones, responsabilidades y colaboraciones. 4. The consequences son los resultados y las compensaciones de aplicar el patrón. Ventajas de los patrones de diseño: 1. Son reutilizables en múltiples proyectos. 2. El nivel arquitectónico de problemas puede ser resuelto. 3. Han sido probados y probados con el tiempo, lo cual es la experiencia de desarrolladores y arquitectos.
    • 826. 761 class Singleton(object): def new (cls): # hasattr methodchecksif the class object an instanceproperty or not. if not hasattr(cls, 'instance'): cls.instance = super(Singleton, cls). new(cls) return cls.instance s = Singleton() print ("Object created", s) s1 = Singleton() print ("Object2 created", s1) ('Object created', < main .Singleton object at 0x10a7cc310>) ('Object2 created', < main .Singleton object at 0x10a7cc310>) 4. Tienen confiabilidad y dependencia. Los patrones de diseño se pueden clasificar en tres categorías: 1. Patrón creacional 2. Patrón estructural 3. Patrón de comportamiento Creational Pattern : se ocupan de cómo se puede crear el objeto y aíslan los detalles de la creación del objeto. Structural Pattern :diseñanlaestructuradeclasesyobjetosparaquepuedancomponersepara lograr resultados más grandes. Behavioral Pattern : se ocupan de la interacción entre los objetos y la responsabilidad de los objetos. Patrón Singleton : Esuntipodecreational patternqueproporcionaunmecanismoparatenersolounoyunobjeto de un tipo dado y proporciona un punto de acceso global. Por ejemplo, Singleton se puede usar en operaciones de base de datos, donde queremos que el objeto de la base de datos mantenga la consistencia de los datos. Implementación Podemos implementar Singleton Pattern en Python creando solo una instancia de la clase Singleton y sirviendo nuevamente el mismo objeto. Salida: Tenga en cuenta que en lenguajes como C ++ o Java, este patrón se implementa haciendo que el constructor sea privado y creando un método estático que realice la inicialización del objeto. De esta manera, un objeto se crea en la primera llamada y la clase devuelve el mismo objeto a partir de entonces. Pero en Python, no tenemos forma de crear constructores privados.
    • 827. 762 from abc import ABCMeta, abstractmethod class Music(): metaclass = ABCMeta @abstractmethod def do_play(self): pass class Mp3(Music): def do_play(self): print ("Playing .mp3 music!") class Ogg(Music): def do_play(self): print ("Playing .ogg music!") class MusicFactory(object): def play_sound(self, object_type): return eval(object_type)().do_play() if name == " main ":mf = MusicFactory() music = input("Which music you want to play Mp3 or Ogg") mf.play_sound(music) Which music you want to play Mp3 or Ogg"Ogg" Playing .ogg music! from datetime import date from operator import attrgetter Patrón de fábrica El patrón de fábrica es también un Creational pattern . El término factory significa que una clase es responsable de crear objetos de otros tipos.Hay una claseque actúa como una fábrica que tiene objetos y métodos asociados con ella. El cliente crea un objeto llamando a los métodos con ciertos parámetros y la fábrica crea el objeto del tipo deseado y lo devuelve al cliente. Salida: MusicFactory es la clase de fábrica aquí que crea un objeto de tipo Mp3 o Ogg según la elección que proporciona el usuario. Apoderado El objeto proxy se usa a menudo para garantizar el acceso protegido a otro objeto, cuya lógica empresarial interna no queremos contaminar con los requisitos de seguridad. Supongamos que queremos garantizar que solo los usuarios con permisos específicos puedan acceder a los recursos. Definición de proxy: (garantiza que solo los usuarios que realmente puedan ver las reservas puedan reservar el servicio al consumidor)
    • 828. 763 class Proxy: def init (self, current_user, reservation_service): self.current_user = current_user self.reservation_service = reservation_service def highest_total_price_reservations(self, date_from, date_to, reservations_count): if self.current_user.can_see_reservations: return self.reservation_service.highest_total_price_reservations( date_from, date_to, reservations_count ) else: return [] #Models and ReservationService: class Reservation: def init (self, date, total_price): self.date = date self.total_price = total_price class ReservationService: def highest_total_price_reservations(self, date_from, date_to, reservations_count): # normally it would be read from database/external service reservations = [ Reservation(date(2014, 5, 15), 100), Reservation(date(2017, 5, 15), 10), Reservation(date(2017, 1, 15), 50) ] filtered_reservations = [r for r in reservations if (date_from <= r.date <= date_to)] sorted_reservations = sorted(filtered_reservations, key=attrgetter('total_price'), reverse=True) return sorted_reservations[0:reservations_count] class User: def init (self, can_see_reservations, name): self.can_see_reservations = can_see_reservations self.name = name #Consumer service: class StatsService: def init (self, reservation_service): self.reservation_service = reservation_service def year_top_100_reservations_average_total_price(self, year): reservations = self.reservation_service.highest_total_price_reservations( date(year, 1, 1), date(year, 12, 31), 1 ) if len(reservations) > 0: total = sum(r.total_price for r in reservations)
    • 829. 764 BENEFICIOS • estamos evitando cualquier cambio en ReservationService cuando se cambianlas restricciones de acceso. • no estamos mezclando datos relacionados con la empresa ( date_from , date_to , reservations_count ) con conceptos de dominio no relacionados (permisos de usuario) en servicio. • El consumidor ( StatsService ) también está libre de la lógica relacionada con los permisos CUEVAS • La interfaz de proxy es siempre exactamente la misma que el objeto que oculta, por lo que el usuario que consume el servicio envuelto por el proxy ni siquiera estaba al tanto de la presencia del proxy. return total / len(reservations) else: return 0 #Test: def test(user, year): reservations_service = Proxy(user, ReservationService()) stats_service = StatsService(reservations_service) average_price = stats_service.year_top_100_reservations_average_total_price(year) print("{0} will see: {1}".format(user.name, average_price)) test(User(True, "John the Admin"), 2017) test(User(False, "Guest"), 2017)
    • 830. 765 In [1]: import string In [2]: %%timeit s=""; long_list=list(string.ascii_letters)*50 ....: for substring in long_list: ....: s+=substring ....: 1000 loops, best of 3: 570 us per loop In [3]: %%timeit long_list=list(string.ascii_letters)*50 ....: s="".join(long_list) ....: 100000 loops, best of 3: 16.1 us per loop In [4]: %timeit for i in range(100000):pass 100 loops, best of 3: 2.82 ms per loop In [5]: %timeit for i in list(range(100000)):pass 100 loops, best of 3: 3.95 ms per loop >>> import timeit >>> timeit.timeit('list(itertools.repeat("a", 100))', 'import itertools', number = 10000000) 10.997665435877963 >>> timeit.timeit('["a"]*100', number = 10000000) 7.118789926862576 python -m timeit "'-'.join(str(n) for n in range(100))" 10000 loops, best of 3: 29.2 usec per loop python -m timeit "'-'.join(map(str,range(100)))" 100000 loops, best of 3: 19.4 usec per loop Capítulo 154: Perfilado Examples %% timeit y% timeit en IPython Concatanación de cadenas de perfiles: Perfilado de bucles sobre iterables y listas: función timeit () Repetición de perfiles de elementos en una matriz. línea de comandos de timeit Perfil de concatanación de números.
    • 831. 766 $ kernprof -lv so6.py Wrote profile results to so6.py.lprof Timer unit: 4.27654e-07 s Total time: 22.6427 s File: so6.py Function: slow_func at line 4 Line # Hits Time Per Hit % Time Line Contents ============================================================== html=s.get("https://en.wikipedia.org/").text 8 list(html)]) 50 5306958 106139.2 10.0 sum([pow(ord(x),3.1) for x in import requests @profile def slow_func(): s = requests.session() html=s.get("https://en.wikipedia.org/").text sum([pow(ord(x),3.1) for x in list(html)]) for i in range(50): slow_func() line_profiler en linea de comando El código fuente con la directiva @profile antes de la función que queremos perfilar: Usando el comando kernprof para calcular el perfil línea por línea 4 @profile 5 def slow_func(): 6 50 20729 414.6 0.0 s = requests.session() 7 50 47618627 952372.5 89.9 La solicitud de página es casi siempre más lenta que cualquier cálculo basado en la información de la página. Usando cProfile (Perfilador preferido) Python incluye un generador de perfiles llamado cProfile. Esto es generalmente preferido sobre el uso de timeit. Desglosa su script completo y para cada método en su script le dice: • ncalls:elnúmerodevecesquesellamóaunmétodo • tottime : tiempo total empleado en la función dada (excluyendo el tiempo realizado en llamadas a subfunciones) • percall : Tiempo empleado porllamada. O el cociente de tottime dividido por ncalls • cumtime : el tiempo acumulado empleado en esta y todas las subfunciones (desde la invocación hasta la salida). Esta cifra es precisa incluso para funciones recursivas. • percall : es el cociente de cumtime dividido por llamadas primitivas
    • 832. 767 $ python -m cProfile -s time main.py • filename:lineno(function) : proporciona los datos respectivos de cada función El cProfiler se puede llamarfácilmente en la línea de comandos usando: Para ordenar la lista devuelta de métodos perfilados por el tiempo empleado en el método: $ python -m cProfile main.py
    • 833. 768 data={'a':'some_value', 'b':[9,4,7], 'c':['some_str','another_str','spam','ham'], 'd':{'key':'nested_dictionary'}, } import pickle file=open('filename','wb') #file object in binary write mode pickle.dump(data,file) #dump the data in the file object file.close() #close the file to write into the file Capítulo 155: Persistencia Python Sintaxis • pickle.dump (obj, file, protocol = None, *, fix_imports = True) • pickle.load (archivo, *, fix_imports = True, encoding = "ASCII", errores = "strict") Parámetros Parámetro Detalles obj Representación encurtida de obj al archivo de objeto de archivo abierto protocolo un entero, le dice al pickler que use el protocolo dado, 0 -ASCII, 1 - formato binario antiguo expediente El argumento del archivo debe tener un método write () wb para el método dump y para cargar el método rb read () Examples Persistencia Python Los objetos como números, listas, diccionarios, estructuras anidadas y objetos de instancia de clase viven en la memoria de su computadora y se pierden tan pronto como termina el script. pickle almacena los datos de forma persistente en un archivo separado. La representación de un objeto encurtido es siempre un objeto de bytes en todos los casos, por lo que uno debe abrir archivos en wb para almacenar datos y rb para cargar datos desde pickle. Los datos pueden estar fuera de cualquier tipo, por ejemplo, Almacenamiento de datos
    • 834. 769 import pickle file=open('filename','rb') #file object in binary read mode data=pickle.load(file) #load the data back file.close() >>>data {'b': [9, 4, 7], 'a': 'some_value', 'd': {'key': 'nested_dictionary'}, 'c': ['some_str', 'another_str', 'spam', 'ham']} import pickle def save(filename,object): file=open(filename,'wb') pickle.dump(object,file) file.close() def load(filename): file=open(filename,'rb') object=pickle.load(file) file.close() return object >>>list_object=[1,1,2,3,5,8,'a','e','i','o','u'] >>>save(list_file,list_object) >>>new_list=load(list_file) >>>new_list [1, 1, 2, 3, 5, 8, 'a', 'e', 'i', 'o', 'u' Cargar datos Los siguientes tipos pueden ser decapados 1. Ninguno, verdadero y falso 2. enteros, números de punto flotante, números complejos 3. cuerdas, bytes, bytearrays 4. Tuplas, listas, conjuntos y diccionarios que contienen solo objetos extraíbles 5. Funciones definidas en el nivel superior de un módulo (usando def, no lambda) 6. Funciones incorporadas definidas en el nivel superior de un módulo 7. Clases que se definen en el nivel superior de un módulo. 8. instancias de dichas clases cuyo dict o el resultado de llamar a getstate () Función de utilidad para guardar y cargar. Guardar datos en y desde archivo
    • 835. 770 Capítulo 156: pip: PyPI Package Manager Introducción pip es el gestor de paquetes más utilizado para el Índice de paquetes de Python, instalado de forma predeterminada con las versiones recientes de Python. Sintaxis • pip <comando> [opciones] donde <comando> es uno de los siguientes: ○ instalar ○ Instalar paquetes ○ desinstalar ○ Desinstalar paquetes ○ congelar ○ ○ lista ○ Salida de paquetes instalados en formato de requerimientos. Listar paquetes instalados ○ espectáculo ○ Mostrar información sobre los paquetes instalados ○ buscar ○ Buscar PyPI para paquetes ○ rueda ○ Construye ruedas a partir de tus requerimientos. ○ cremallera ○ Zip paquetes individuales (obsoletos) ○ abrir la cremallera ○ ○ haz ○ Descomprimir paquetes individuales (obsoletos) Crear pybundles (en desuso) ○ ayuda ○ Mostrar ayuda para comandos Observaciones A veces, pip realizará una compilación manual de código nativo. En Linux, Python elegirá automáticamente un compilador de C disponible en su sistema. Consulte la tabla a continuación para obtener la versión requerida de Visual Studio / Visual C ++ en Windows (las versiones más recientes no funcionarán). Versión Python Versión de Visual Studio Versión Visual C ++ 2.6 - 3.2 Visual Studio 2008 Visual C ++ 9.0
    • 836. 771 $ pip install SomePackage $ pip install SomePackage==1.0.4 $ pip install SomePackage>=1.0.4 $ pip install -r requirements.txt $ pip freeze $ pip uninstall SomePackage Versión Python Versión de Visual Studio Versión Visual C ++ 3.3 - 3.4 Visual Studio 2010 Visual C ++ 10.0 3.5 Visual Studio 2015 Visual C ++ 14.0 Fuente: wiki.python.org Examples Instalar paquetes Para instalar la última versión de un paquete llamado SomePackage : Para instalar una versión específica de un paquete: Para especificar una versión mínima para instalar para un paquete: Si los comandos muestran un error de denegación de permiso en Linux / Unix, use sudo con los comandos Instalar desde archivos de requisitos Cada línea del archivo de requisitos indica algo para instalar, y al igual que los argumentos para instalar, los detalles sobre el formato de los archivos están aquí: Formato del archivo de requisitos . Después de instalar el paquete, puede verificarlo usando el comando de freeze : Desinstalar paquetes Para desinstalar un paquete:
    • 837. 772 $ pip list # example output docutils (0.9.1) Jinja2 (2.6) Pygments (1.5) Sphinx (1.1.2) $ pip list --outdated # example output docutils (Current: 0.9.1 Latest: 0.10) Sphinx (Current: 1.1.2 Latest: 1.1.3) $ pip install --upgrade SomePackage $ pip install --upgrade pip $ python -m pip install --upgrade pip pip list --outdated --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U Para listar todos los paquetes instalados usando `pip` Para listar los paquetes instalados: Para listar paquetes obsoletos y mostrar la última versión disponible: Paquetes de actualización Corriendo actualizará el paquete SomePackage y todas sus dependencias. Además, pip elimina automáticamente la versión anterior del paquete antes de la actualización. Para actualizar pip en sí, haz en Unix o en las máquinas de Windows. Actualizando todos los paquetes desactualizados en Linux pip no contiene actualmente una bandera que permita a un usuario actualizar todos los paquetes desactualizados de una sola vez. Sin embargo, esto puede lograrse uniendo los comandos en un entorno Linux: Este comando toma todos los paquetes en el virtualenv local y comprueba si están desactualizados. De esa lista, obtiene el nombre del paquete y luego lo canaliza a un comando pip install -U . Al final de este proceso, todos los paquetes locales deben actualizarse.
    • 838. 773 for /F "delims= " %i in ('pip list --outdated --local') do pip install -U %i pip freeze > requirements.txt pip freeze --local > requirements.txt pip install [package] pip2 install [package] Actualizando todos los paquetes desactualizados en Windows pip no contiene actualmente una bandera que permita a un usuario actualizar todos los paquetes desactualizados de una sola vez. Sin embargo, esto puede lograrse uniendo los comandos en un entorno Windows: Este comando toma todos los paquetes en el virtualenv local y comprueba si están desactualizados. De esa lista, obtiene el nombre del paquete y luego lo canaliza a un comando pip install -U . Al final de este proceso, todos los paquetes locales deben actualizarse. Cree un archivo Requirements.txt de todos los paquetes en el sistema pip ayuda en la creación de los requirements.txt archivos .txt al proporcionar la opción de freeze . Esto guardará una lista de todos los paquetes y su versióninstalada en el sistema en un archivo llamado requirements.txt en la carpeta actual. Cree un archivo Requirements.txt de paquetes solo en el virtualenv actual pip ayuda en la creación de los requirements.txt archivos .txt al proporcionar la opción de freeze . El parámetro --local solo generará una lista de paquetes y versiones que se instalan localmente en un virtualenv. Los paquetes globales no serán listados. Usando una determinada versión de Python con pip Si tiene tanto Python 3 como Python 2 instalados, puede especificar qué versión de Python le gustaría que usara pip. Esto es útil cuando los paquetes solo admiten Python 2 o 3 o cuando desea probar con ambos. Si desea instalar paquetes para Python 2, ejecute: o: Si desea instalar paquetes para Python 3, haga:
    • 839. 774 \path\to\that\python.exe -m pip install some_package # on Windows OR /usr/bin/python25 -m pip install some_package # on OS-X/Linux py -3 -m pip install -U some_package # Install/Upgrade some_package to the latest python 3 py -3.3 -m pip install -U some_package # Install/Upgrade some_package to python 3.3 if present py -2 -m pip install -U some_package # Install/Upgrade some_package to the latest python 2 - 64 bit if present py -2.7-32 -m pip install -U some_package # Install/Upgrade some_package to python 2.7 - 32 bit if present También puede invocar la instalación de un paquete a una instalación específica de Python con: En las plataformas OS-X / Linux / Unix, es importante tener en cuenta la distinción entre la versión del sistema de python (la actualización hace que el sistema deje de funcionar) y las versiones de usuario de python. Usted puede , dependiendo de lo que está intentando actualizar , necesita prefijar estos comandos con sudo e ingresar una contraseña. Delmismomodo,enWindows,algunasinstalacionesdePython,especialmenteaquellasqueson partedeotropaquete,puedenterminarinstaladasenlosdirectoriosdelsistema(aquellasque tendrá que actualizar desde una ventana de comandos que se ejecuta en el modo de administración) si le parece que necesita Para ello, es una muy buena idea comprobar qué instalación de Python está intentando actualizar con un comando como python -c"import sys;print(sys.path);" o py -3.5 -c"import sys;print(sys.path);" También puede comprobar qué pip está intentando ejecutar con pip --version En Windows, si tienes ambos python 2 y python 3 instalados, y en tu ruta y tu python 3 es mayor que 3.4, entonces probablemente también tengas python launcher py en la ruta de tu sistema. A continuación, puede hacer trucos como: Siestáejecutandoymanteniendo variasversionesdepython,lerecomendaríaencarecidamente leer sobre los entornos virtualenv python virtualenv o venv que le permiten aislar tanto la versión de python como los paquetes que estánpresentes. Instalación de paquetes aún no en pip como ruedas Muchos paquetes de python puro aún no están disponibles en el Índice de Paquetes de Python como ruedas, pero aún así se instalan bien. Sin embargo, algunos paquetes en Windows le dan el error vcvarsall.bat no encontrado. El problema es que el paquete que está intentando instalar contiene una extensión C o C ++ y no está disponible actualmente como una rueda precompilada del índice del paquete python, pypi , y en las ventanas no tiene la cadena de herramientas necesaria para compilar tales artículos La respuesta más simple es ir al excelente sitio de Christoph Gohlke y localizar la versión adecuada de las bibliotecas que necesita. Por apropiado en el paquete nombrar -cp NN - tiene que coincidir con la versión de Python, es decir, si está utilizando Windows 32 bits pitón incluso en Win64 el nombre debe incluir -win32- y si el uso de la pitón de 64 bits que debe incluir - pip3 install [package]
    • 840. 775 win_amd64 - y luego la versión de Python debe coincidir, es decir, para Python 34, el nombre del archivo debe incluir -cp 34- , etc. Esta es básicamente la magia que el pip hace por ti en el sitio pypi. Alternativamente, necesita obtener el kit de desarrollo de Windows apropiado para la versión de python que está utilizando, los encabezados de cualquier biblioteca en la que el paquete está intentando crear interfaces, posiblemente los encabezados de python para la versión de python, etc. Python 2.7 usó Visual Studio 2008, Python 3.3 y 3.4 usó Visual Studio 2010, y Python 3.5+ usa Visual Studio 2015. • Instale " Visual C ++ Compiler Package for Python 2.7 ", que está disponible en el sitio web de Microsoft o • Instale " Windows SDK para Windows 7 y .NET Framework 4 " (v7.1), que está disponible en el sitio web de Microsoft o • Instale Visual Studio 2015 Community Edition , (o cualquier versión posterior, cuando se publiquen) , asegurándose de que selecciona las opciones para instalar el soporte de C & C ++ que ya no tiene el valor predeterminado . Me han dicho que la descarga y la instalación pueden demorar hasta 8 horas. así que asegúrese de que esas opciones estén configuradas en el primer intento. Entonces es posible que deba ubicar los archivos de encabezado, en la revisión correspondiente de las bibliotecas a las que se vincula su paquete deseado y descargarlos en las ubicaciones correspondientes. Finalmente , puede dejar que pip haga su compilación; por supuesto, si el paquete tiene dependencias que aún no tiene, es posible que también necesite encontrar los archivos de encabezado para ellos. Alternativas: también vale la pena mirar hacia fuera, tanto en pypi como en el sitio de Christop , para cualquier versión ligeramente anterior del paquete que está buscando, ya sea python puro o pre-construido para su plataforma y versión de python y posiblemente usarlos, si encontrado, hasta que su paquete esté disponible. Del mismo modo, si está utilizando la última versión de python, es posible que los mantenedores de paquetes necesiten un poco de tiempo para ponerse al día, por lo que, para los proyectos que realmente necesitan un paquete específico, es posible que deba usar una python un poco más antigua por el momento. También puede consultar el sitio de origen de los paquetes para ver si hay una versión bifurcada que esté disponible preconstruida o como puro python y buscar paquetes alternativos que proporcionen la funcionalidad que necesita pero está disponible. Un ejemplo que viene a la mente es el siguiente. Almohada , mantenida activamente , reemplazo de PIL actualmente no actualizado en 6 años y no disponible para python 3 . Después , recomendaría a cualquier persona que tenga este problema que vaya al rastreador de errores del paquete y añada o aumente, si no hay uno ya, un boleto que solicite educadamente que los mantenedores del paquete proporcionen una rueda en pypi para su específico combinación de plataforma y python, si esto se hace, normalmente las cosas mejorarán con el tiempo, algunos mantenedores de paquetes no se dan cuenta de que se han perdido una
    • 841. 776 > py -3.5-32 -m venv demo-pip > demo-pip\Scripts\activate.bat > python -m pip install -U pip Collecting pip Using cached pip-9.0.1-py2.py3-none-any.whl Installing collected packages: pip Found existing installation: pip 8.1.1 Uninstalling pip-8.1.1: Successfully uninstalled pip-8.1.1 Successfully installed pip-9.0.1 > pip install git+https://github.com/sphinx-doc/sphinx/ Collecting git+https://github.com/sphinx-doc/sphinx/ Cloning https://github.com/sphinx-doc/sphinx/ to c:\users\steve- ~1\appdata\local\temp\pip-04yn9hpp-build Collecting six>=1.5 (from Sphinx==1.7.dev20170506) Using cached six-1.10.0-py2.py3-none-any.whl Collecting Jinja2>=2.3 (from Sphinx==1.7.dev20170506) combinación determinada que las personas pueden estar usando. Nota sobre la instalación de versiones preliminares Pipsiguelas reglas del control de versiones semántico y, de forma predeterminada, prefierelos paquetespublicados antes que los lanzamientos previos.Porlo tanto, si un paquete dado seha liberado como V0.98 y también hay una versión candidata V1.0-rc1 el comportamiento predeterminado depip install seráinstalar V0.98 : si deseainstalarlaversióncandidata, le recomendamosparaprobarprimeroenunentornovirtual,puedehabilitarlocon--pip install-- pre package-name o --pip install --pre --upgrade package-name . En muchos casos, los prelanzamientosolanzamientosdecandidatospuedennotenerruedas creadas para todas las combinaciones de plataformas y versiones, porlo que es más probable que encuentre los problemas anteriores. Nota sobre la instalación de versiones de desarrollo También puede usar pip para instalar versiones de desarrollo de paquetes desde github y otras ubicaciones, ya que dicho código está en flujo, es muy poco probable que se le construyan ruedas, por lo que cualquier paquete impuro requerirá la presencia de las herramientas de construcción, y es posible que se puede romper en cualquier momento, por lo que se recomienda encarecidamente al usuario que solo instale dichos paquetes en un entorno virtual. Existen tres opciones para tales instalaciones: 1. Descargue una instantánea comprimida, la mayoría de los sistemas de control deversiones en línea tienen la opción de descargar una instantánea comprimida del código. Esto puede descargarse manualmente y luego instalarse con la ruta de pip install / to / download / file. Tenga en cuenta que, para la mayoría de los formatos de compresión, pip manejará el desempaquetado en un área de caché, etc. 2. Permita que pip maneje la descarga e instale por usted con: pip installURL /of/ package / repository - también puede necesitar usar las --trusted-host , --client-cert y / o --proxy paraqueestofuncionecorrectamente,especialmenteenunentornocorporativo.p.ej:
    • 842. 777 Using cached Jinja2-2.9.6-py2.py3-none-any.whl Collecting Pygments>=2.0 (from Sphinx==1.7.dev20170506) Using cached Pygments-2.2.0-py2.py3-none-any.whl Collecting docutils>=0.11 (from Sphinx==1.7.dev20170506) Using cached docutils-0.13.1-py3-none-any.whl Collecting snowballstemmer>=1.1 (from Sphinx==1.7.dev20170506) Using cached snowballstemmer-1.2.1-py2.py3-none-any.whl Collecting babel!=2.0,>=1.3 (from Sphinx==1.7.dev20170506) Using cached Babel-2.4.0-py2.py3-none-any.whl Collecting alabaster<0.8,>=0.7 (fromSphinx==1.7.dev20170506) Using cached alabaster-0.7.10-py2.py3-none-any.whl Collecting imagesize (from Sphinx==1.7.dev20170506) Using cached imagesize-0.7.1-py2.py3-none-any.whl Collecting requests>=2.0.0 (from Sphinx==1.7.dev20170506) Using cached requests-2.13.0-py2.py3-none-any.whl Collecting typing (from Sphinx==1.7.dev20170506) Using cached typing-3.6.1.tar.gz Requirement already satisfied: setuptools in f:\toolbuild\temp\demo-pip\lib\site-packages (from Sphinx==1.7.dev20170506) Collecting sphinxcontrib-websupport (from Sphinx==1.7.dev20170506) Downloading sphinxcontrib_websupport-1.0.0-py2.py3-none-any.whl Collecting colorama>=0.3.5 (from Sphinx==1.7.dev20170506) Using cached colorama-0.3.9-py2.py3-none-any.whl Collecting MarkupSafe>=0.23 (from Jinja2>=2.3->Sphinx==1.7.dev20170506) Using cached MarkupSafe-1.0.tar.gz Collecting pytz>=0a (frombabel!=2.0,>=1.3->Sphinx==1.7.dev20170506) Using cached pytz-2017.2-py2.py3-none-any.whl Collecting sqlalchemy>=0.9 (from sphinxcontrib-websupport->Sphinx==1.7.dev20170506) Downloading SQLAlchemy-1.1.9.tar.gz (5.2MB) 100% |################################| 5.2MB 220kB/s Collecting whoosh>=2.0 (from sphinxcontrib-websupport->Sphinx==1.7.dev20170506) Downloading Whoosh-2.7.4-py2.py3-none-any.whl (468kB) 100% |################################| 471kB 1.1MB/s Installing collected packages: six, MarkupSafe, Jinja2, Pygments, docutils, snowballstemmer, pytz, babel, alabaster, imagesize, requests, typing, sqlalchemy, whoosh, sphinxcontrib-websupport, colorama, Sphinx Running setup.py install for MarkupSafe ... done Running setup.py install for typing ... done Running setup.py install for sqlalchemy ... done Running setup.py install for Sphinx ... done Successfully installed Jinja2-2.9.6 MarkupSafe-1.0 Pygments-2.2.0 Sphinx-1.7.dev20170506 alabaster-0.7.10 babel-2.4.0 colorama-0.3.9 docutils-0.13.1 imagesize-0.7.1 pytz-2017.2 requests2.13.0 six-1.10.0 snowballstemmer-1.2.1 sphinxcontrib-websupport-1.0.0 sqlalchemy1.1.9 typing-3.6.1 whoosh-2.7.4 Tenga en cuenta el prefijo git+ a la URL. 3. Clonarelrepositoriousandogit,mercurialherramientaaceptableuotro,preferentemente una herramienta DVCS, y el uso pip installruta / a / clonada /repo - esto tanto el proceso como cualquier archivo requires.text y llevar a cabo los pasos de generación y configuración,sepuedecambiarmanualmentedirectorioa surepositorioclonadoyejecute pip install -r requires.txt python setup.py install yluegopython setup.py install para obtener el mismo efecto.Lasgrandes ventajasde este enfoque esque, si bienlaoperación de clonación inicial puede llevar más tiempo que la descarga de instantáneas, puede actualizar a la última versión con, en el caso de git: git pull origin master y si la versión actual contiene errores, puede usar la pip uninstall nombre-paquete, luego use los comandos de git checkout para retroceder a través del historial del repositorio a las
    • 843. 778 versiones anteriores y volver a intentarlo.
    • 844. 779 from string import Template data = dict(item = "candy", price = 8, qty = 2) # define the template t = Template("Simon bought $qty $item for $price dollar") print(t.substitute(data)) Simon bought 2 candy for 8 dollar from string import Template class MyOtherTemplate(Template): delimiter = "#" data = dict(id = 1, name = "Ricardo") t=MyOtherTemplate("My name is #name andI havetheid: #id") print(t.substitute(data)) Capítulo 157: Plantillas en python Examples Programa de salida de datos simple usando plantilla Salida: Las plantillas admiten sustituciones basadas en $ en lugar de sustituciones basadas en%. Substitute (mapeo, palabras clave) realiza la sustitución de plantillas, devolviendo una nueva cadena. La asignación es cualquier objeto similar a un diccionario con claves que coinciden con los marcadores de posición de la plantilla. En este ejemplo, el precio y la cantidad son marcadores de posición. Los argumentos de palabras clave también se pueden utilizar como marcadores de posición. Los marcadores de posición de las palabras clave tienen prioridad si ambos están presentes. Cambiando delimitador Puede cambiar el delimitador "$" a cualquier otro. El siguiente ejemplo: Puedes leer los documentos aquí.
    • 845. 780 class Shape: """ This is a parent class that is intended to be inherited by other classes """ def calculate_area(self): """ This method is intended to be overridden in subclasses. If a subclass doesn't implement it but it is called, NotImplemented will be raised. """ raise NotImplemented class Square(Shape): """ This is a subclass of the Shape class, and represents a square """ side_length = 2 # in this example, the sides are 2 units long def calculate_area(self): """ This method overrides Shape.calculate_area(). When an object of type Square has its calculate_area() method called, this is the method that will be called, rather than the parent class' version. It performsthe calculation necessary for this shape, a square, and returns the result. """ return self.side_length * 2 class Triangle(Shape): """ Thisis also a subclass ofthe Shape class, and it represents a triangle """ base_length = 4 height = 3 def calculate_area(self): """ This method also overrides Shape.calculate_area() and performs the area Capítulo 158: Polimorfismo Examples Polimorfismo basico El polimorfismo es la capacidad de realizar una acción en un objeto independientemente de su tipo. Esto generalmente se implementa creando una clase base y teniendo dos o más subclases que implementan todos los métodos con la misma firma. Cualquier otra función o método que manipule estos objetos puede llamar a los mismos métodos independientemente del tipo de objeto en el que esté operando, sin necesidad de realizar una verificación de tipo primero. En la terminología orientada a objetos, cuando la clase X extiende la clase Y, entonces Y se llama súper clase o clase base y X se llama subclase o clase derivada.
    • 846. 781 class Square: side_length = 2 def calculate_square_area(self): return self.side_length ** 2 class Triangle: base_length = 4 height = 3 def calculate_triangle_area(self): return (0.5 * self.base_length) * self.height def get_area(input_obj): # Notice the type checks that are now necessary here. These type checks # could get very complicated for a more complex example, resulting in # duplicate and difficult to maintain code. Deberíamos ver esta salida: Ninguna 4 6.0 ¿Qué pasa sin el polimorfismo? Sin polimorfismo, puede requerirse una verificación de tipo antes de realizar una acción en un objetoparadeterminarel métodocorrectoparallamar.Elsiguienteejemplodecontadorrealiza lamismatareaqueel códigoanterior,perosinelusodepolimorfismo,lafunciónget_area()tiene que hacer más trabajo. calculation for a triangle, returning the result. """ return 0.5 * self.base_length * self.height def get_area(input_obj): """ This function accepts an input object, and will call that object's calculate_area() method. Note that the object type is not specified. It could be a Square, Triangle, or Shape object. """ print(input_obj.calculate_area()) # Create one object of each class shape_obj = Shape() square_obj = Square() triangle_obj = Triangle() # Now pass each object, one at a time, to the get_area() function and see the # result. get_area(shape_obj) get_area(square_obj) get_area(triangle_obj)
    • 847. 782 class Duck: def quack(self): print("Quaaaaaack!") def feathers(self): print("The duck has white and gray feathers.") class Person: def quack(self): print("The person imitates a duck.") def feathers(self): print("The person takes a feather from the ground and shows it.") def name(self): print("John Smith") def in_the_forest(obj): obj.quack() obj.feathers() Deberíamos ver esta salida: 4 6.0 Nota IMPORTANTE Tenga en cuenta que las clases utilizadas en el ejemplo de contador son clases de "nuevo estilo" y se heredan implícitamente de la clase de objeto si se está utilizando Python 3. El polimorfismo funcionará tanto en Python 2.xy 3.x, pero el código de contraejemplo del polimorfismo generará una excepción si se ejecuta en un intérprete de Python 2.x porque escribe (input_obj). el nombre devolverá "instancia" en lugar del nombre de la clase si no se heredan explícitamente del objeto, lo que da como resultado que nunca se asigne un área. Escribiendo pato Polimorfismo sin herencia en forma de escritura de pato disponible en Python debido a su sistema de escritura dinámico. Esto significa que siempre que las clases contengan los mismos métodos, el intérprete de Python no distingue entre ellos, ya que la única comprobación de las llamadas se realiza en tiempo de ejecución. if type(input_obj). name == "Square": area = input_obj.calculate_square_area() elif type(input_obj). name == "Triangle": area = input_obj.calculate_triangle_area() print(area) # Create one object of each class square_obj = Square() triangle_obj = Triangle() # Now pass each object, one at a time, to the get_area() function and see the # result. get_area(square_obj) get_area(triangle_obj)
    • 848. 783 La salida es: Quaaaaaack! El pato tiene plumas blancas y grises. La persona imita a un pato. La persona toma una pluma del suelo y la muestra. donald = Duck() john = Person() in_the_forest(donald) in_the_forest(john)
    • 849. 784 import psycopg2 # Establish a connection to the existing database 'my_database' using # the user 'my_user' with password 'my_password' con = psycopg2.connect("host=localhost dbname=my_database user=my_user password=my_password") # Create a cursor cur = con.cursor() # Insert a record into 'my_table' cur.execute("INSERT INTO my_table(id, first_name, last_name) VALUES (2, 'Jane', 'Doe');") # Commit the current transaction con.commit() # Retrieve all records from 'my_table' cur.execute("SELECT * FROM my_table;") results = cur.fetchall() # Close the database connection con.close() # Print the results print(results) Capítulo 159: PostgreSQL Examples Empezando PostgreSQLesunabasededatosdecódigoabiertodesarrolladaactivamenteymadura.Usando el módulo psycopg2 , podemos ejecutar consultas en la base dedatos. Instalación utilizando pip pip install psycopg2 Uso básico Supongamos quetenemos una tabla my_tableen la base dedatos my_database definida de la siguiente manera. carné de identidad nombre de pila apellido 1 Juan Gama Podemos usar el módulo psycopg2 para ejecutar consultas en la base de datos de la siguiente manera.
    • 850. 785 # OUTPUT: [(1, 'John', 'Doe'), (2, 'Jane', 'Doe')]
    • 851. 786 Capítulo 160: Precedencia del operador Introducción Los operadores de Python tienen un orden de prioridad establecido , que determina qué operadores se evalúan primero en una expresión potencialmente ambigua. Por ejemplo, en la expresión 3 * 2 + 7, primero se multiplica 3 por 2, y luego el resultado se agrega a 7, obteniendo 13. La expresión no se evalúa al revés, porque * tiene una precedencia más alta que +. A continuación hay una lista de operadores por precedencia y una breve descripción de lo que hacen (generalmente). Observaciones De la documentación de Python: La siguiente tabla resume las precedencias del operador en Python, desde la precedencia más baja (menos vinculante) hasta la precedencia más alta (más vinculante). Los operadores en la misma caja tienen la misma prioridad. A menos que la sintaxis esté explícitamente dada, los operadores son binarios. Los operadores en el mismo grupo agrupan de izquierda a derecha (excepto las comparaciones, incluidas las pruebas, que tienen la misma prioridad y cadena de izquierda a derecha y exponenciación, que agrupa de derecha a izquierda). Operador Descripción lambda Expresión lambda si Expresión condicional o Booleano o y Booleano y no x Booleano no en, no en, es, no es, <, <=,>,> =, <>,! =, == Comparaciones, incluyendo pruebas de membresía y pruebas de identidad | Bitwise o ^ Bitwise XOR Y Y a nivel de bit <<, >> Turnos
    • 852. 787 >>> a, b, c, d = 2, 3, 5, 7 >>> a ** (b + c) # parentheses 256 >>> a * b ** c # exponent: same as `a * (b ** c)` 7776 >>> a + b * c / d # multiplication / division: same as `a + (b * c / d)` 4.142857142857142 >>> 300 / 300 * 200 200.0 >>> 300 * 200 / 300 200.0 >>> 1e300 / 1e300 * 1e200 1e+200 >>> 1e300 * 1e200 / 1e300 inf Operador Descripción +, - Adición y sustracción *, /, //,% Multiplicación, división, resto [8] + x, -x, ~ x Positivo, negativo, a nivel de bit NO ** Exposiciónción [9] x [índice], x [índice: índice], x (argumentos ...), x.attribute Suscripción, corte, llamada, atributo de referencia. (expresiones ...), [expresiones ...], {clave: valor ...}, expresiones ... Encuadernación o visualización de tupla, visualización de lista, visualización de diccionario, conversión de cadena Examples Ejemplos simples de precedencia de operadores en python. Python sigue la regla de PEMDAS. PEMDAS significa paréntesis, exponentes, multiplicación y división, y suma y resta. Ejemplo: Extras: las reglas matemáticas se mantienen, pero no siempre :
    • 853. 788 import threading import time def process(): time.sleep(2) start = time.time() process() print("One run took %.2fs" % (time.time() - start)) start = time.time() threads = [threading.Thread(target=process) for _ in range(4)] for t in threads: t.start() for t in threads: t.join() print("Four runs took %.2fs" % (time.time() - start)) # Out: One run took 2.00s # Out: Four runs took 2.00s Capítulo 161: Procesos e hilos Introducción La mayoría de los programas se ejecutan línea por línea, ejecutando solo un proceso a la vez. Los hilos permiten que múltiples procesos fluyan independientemente unos de otros. El subprocesamiento con múltiples procesadores permite que los programas ejecuten múltiples procesos simultáneamente. Este tema documenta la implementación y el uso de subprocesos en Python. Examples Bloqueo de intérprete global El rendimiento de subprocesos múltiples de Python a menudo puede verse afectado por el bloqueo global de intérprete . En resumen, aunque puede tener varios subprocesos en un programa de Python, solo una instrucción de bytecode puede ejecutarse en paralelo al mismo tiempo, independientemente del número de CPU. Como tal, el multihilo en casos en los que las operaciones están bloqueadas por eventos externos, como el acceso a la red, puede ser bastante efectivo: Tenga en cuenta que aunque cada process tardó 2 segundos en ejecutarse, los cuatro procesos juntos pudieron ejecutarse de manera efectiva en paralelo, tomando un total de 2 segundos. Sin embargo, los subprocesos múltiples en los casos en los que se realizan cálculos intensivos en
    • 854. 789 import threading import time def somefunc(i): return i * i def otherfunc(m, i): return m + i def process(): for j inrange(100): result = 0 for i in range(100000): result = otherfunc(result, somefunc(i)) start = time.time() process() print("One run took %.2fs" % (time.time() - start)) start = time.time() threads = [threading.Thread(target=process) for _ in range(4)] for t in threads: t.start() for t in threads: t.join() print("Four runs took %.2fs" % (time.time() - start)) # Out: One run took 2.05s # Out: Four runs took 14.42s import multiprocessing import time def somefunc(i): return i * i def otherfunc(m, i): return m + i def process(): for j inrange(100): result = 0 for i in range(100000): result = otherfunc(result, somefunc(i)) start = time.time() process() print("One run took %.2fs" % (time.time() - start)) el código de Python, como muchos cálculos, no producen una gran mejora e incluso pueden ser más lentos que ejecutarse en paralelo: En este último caso, el multiprocesamiento puede ser efectivo, ya que los procesos múltiples pueden, por supuesto, ejecutar múltiples instrucciones simultáneamente:
    • 855. 790 import threading import os def process(): print("Pid is %s, thread id is %s" % (os.getpid(), threading.current_thread().name)) threads = [threading.Thread(target=process) for _ in range(4)] for t in threads: t.start() for t in threads: t.join() # Out: Pid is 11240, thread id is Thread-1 # Out: Pid is 11240, thread id is Thread-2 # Out: Pid is 11240, thread id is Thread-3 # Out: Pid is 11240, thread id is Thread-4 import multiprocessing import os def process(): print("Pid is %s" % (os.getpid(),)) processes = [multiprocessing.Process(target=process) for _ in range(4)] for p in processes: p.start() for p in processes: p.join() # Out: Pid is 11206 # Out: Pid is 11207 # Out: Pid is 11208 # Out: Pid is 11209 Corriendo en múltiples hilos Use threading.Thread para ejecutar una función en otrohilo. Ejecutando en múltiples procesos Use multiprocessing.Process para ejecutar una función en otro proceso. La interfaz es similar a threading.Thread : start = time.time() processes = [multiprocessing.Process(target=process) for _ in range(4)] for p in processes: p.start() for p in processes: p.join() print("Four runs took %.2fs" % (time.time() - start)) # Out: One run took 2.07s # Out: Four runs took 2.30s
    • 856. 791 import threading obj = {} obj_lock = threading.Lock() def objify(key, val): print("Obj has %d values" % len(obj)) with obj_lock: obj[key] = val print("Obj now has %d values" % len(obj)) ts =[threading.Thread(target=objify, args=(str(n),n))fornin range(4)] for t in ts: t.start() for t in ts: t.join() print("Obj final result:") import pprint; pprint.pprint(obj) # Out: Obj has 0 values # Out: Obj has 0 values # Out: Obj now has 1 values # Out: Obj now has 2 valuesObj has 2 values # Out: Obj now has 3 values # Out: # Out: Obj has 3 values # Out: Obj now has 4values # Out: Obj final result: # Out: {'0': 0, '1': 1, '2': 2, '3': 3} import multiprocessing plain_num = 0 shared_num = multiprocessing.Value('d', 0) lock = multiprocessing.Lock() def increment(): global plain_num with lock: # ordinary variable modifications are not visible across processes plain_num += 1 # multiprocessing.Value modifications are Compartir el estado entre hilos Como todos los subprocesos se ejecutan en el mismo proceso, todos los subprocesos tienen acceso a los mismos datos. Sin embargo, el acceso simultáneo a los datos compartidos debe protegerse con un bloqueo para evitar problemas de sincronización. Estado de intercambio entre procesos El códigoqueseejecutaendiferentesprocesosnocomparte, de formapredeterminada,los mismos datos. Sin embargo, el módulo de multiprocessing contiene primitivas para ayudar a compartir valores a través de múltiplesprocesos.
    • 857. 792 shared_num.value += 1 ps = [multiprocessing.Process(target=increment) for n in range(4)] for p in ps: p.start() for p in ps: p.join() print("plain_num is %d, shared_num is %d" % (plain_num, shared_num.value)) # Out: plain_num is 0, shared_num is 4
    • 858. 793 s=lambda x:x*x s(2) =>4 name_lengths = map(len, ["Mary", "Isla", "Sam"]) print(name_lengths) =>[4, 4, 3] total = reduce(lambda a, x: a + x, [0, 1, 2, 3, 4]) print(total) =>10 Capítulo 162: Programación Funcional en Python Introducción La programación funcional descompone un problema en un conjunto de funciones. Lo ideal es que las funciones solo tomen entradas y produzcan salidas, y no tengan ningún estado interno que afecte la salida producida para una entrada dada. A continuación, se encuentran las técnicas funcionales comunes a muchos idiomas: como lambda, map, reduce. Examples Función lambda Una función anónima, en línea definida con lambda. Los parámetros de la lambda se definen a la izquierda de los dos puntos. El cuerpo de la función se define a la derecha de los dos puntos. El resultado de ejecutar el cuerpo de la función se devuelve (implícitamente). Función de mapa Mapa toma una función y una colección de elementos. Hace una nueva colección vacía, ejecuta la función en cada elemento de la colección original e inserta cada valor de retorno en la nueva colección. Devuelve la nueva colección. Este es un mapa simple que toma una lista de nombres y devuelve una lista de las longitudes de esos nombres: Función de reducción Reducir toma una función y una colección de elementos. Devuelve un valor que se crea combinando los elementos. Este es un simple reducir. Devuelve la suma de todos los elementos de la colección. Función de filtro
    • 859. 794 # outputs[5,6] arr=[1,2,3,4,5,6] [ifori infilter(lambda x:x>4,arr)] Filtro toma una función y una colección. Devuelve una colección de cada elemento para el que la función devolvió True.
    • 860. 795 Capítulo 163: Programación IoT con Python y Raspberry PI Examples Ejemplo - sensor de temperatura Interfaz de DS18B20 con Raspberry pi Conexión de DS18B20 con Raspberry pi Se puede ver que hay tres terminales. 1. Vcc 2. Gnd 3. Datos (protocolo de un cable)
    • 861. 796 R1 es una resistencia de 4.7k ohmios para elevar el nivel de voltaje 1. Vcc debe conectarse a cualquiera de los pines 5v o 3.3v de la Raspberry pi (PIN: 01, 02, 04, 17). 2. Gnd debe estar conectado a cualquiera de los pines Gnd de Raspberry pi (PIN: 06, 09, 14, 20, 25). 3. Los datos deben estar conectados a (PIN: 07) Habilitando la interfaz de un cable desde el lado RPi 4. Inicie sesión en Raspberry pi utilizando putty o cualquier otro terminal linux / unix. 5. Después de iniciar sesión, abra el archivo /boot/config.txt en su navegador favorito. nano /boot/config.txt 6. Ahora agregue esta línea dtoverlay=w1–gpio al final delarchivo. 7. Ahora reinicie el Raspberry pi sudo reboot . 8. Inicia sesión en Raspberry pi y ejecuta sudo modprobe g1-gpio 9. Luego ejecute sudo modprobe w1-therm 10. Ahora vaya al directorio / sys / bus / w1 / devices cd /sys/bus/w1/devices 11. Ahora descubrirá un directorio virtual creado con su sensor de temperatura a partir de 28 -
    • 862. 797 import glob import time RATE = 30 sensor_dirs = glob.glob("/sys/bus/w1/devices/28*") if len(sensor_dirs) != 0: while True: time.sleep(RATE) for directories in sensor_dirs: temperature_file = open(directories + "/w1_slave") # Reading the files text = temperature_file.read() temperature_file.close() # Split the text with new lines (\n) and select the second line. second_line = text.split("\n")[1] # Split the line into words, and select the 10th word temperature_data = second_line.split(" ")[9] # We will read after ignoring first two character. temperature = float(temperature_data[2:]) #Nownormalisethetemperaturebydividing1000. temperature = temperature / 1000 print'Address:'+str(directories.split('/')[-1])+',Temperature: '+str(temperature) ********. 12. Ir a este directorio cd 28-******** 13. Ahora hay un nombre de archivow1-slave ,este archivocontiene la temperatura yotra información como CRC. cat w1-slave . Ahora escribe un módulo en python para leer la temperatura Sobre el módulo de python se imprimirá la temperatura frente a la dirección durante un tiempo infinito. El parámetro RATE se define para cambiar o ajustar la frecuencia de la consulta de temperatura del sensor. Diagrama de pin GPIO 1. [ https://www.element14.com/community/servlet/JiveServlet/previewBody/73950-102-11- 339300/pi3_gpio.png◆[3]
    • 863. 798 pip install pytest # projectroot/module/code.py def add(a, b): return a + b # projectroot/tests/test_code.py from module import code def test_add(): assert code.add(1, 2) == 3 # ensure we have the modules $ touch tests/ init .py $ touch module/ init .py $ py.test ================================================== test session starts =================================================== platform darwin -- Python 2.7.10, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 rootdir: /projectroot, inifile: collected 1 items tests/test_code.py . Capítulo 164: py.test Examples Configurando py.test py.test esunadevariasbibliotecasdepruebasdetercerosqueestándisponiblesparaPython. Se puede instalar utilizando pip con El código a probar Digamos que estamos probando una función de adición en projectroot/module/code.py : El código de prueba Creamos un archivo de prueba en projectroot/tests/test_code.py . El archivo debe comenzar con test_ para que se reconozca como un archivo de prueba. Corriendo la prueba Desde projectroot simplemente ejecutamos py.test :
    • 864. 799 # projectroot/tests/test_code.py from module import code def test_add failing(): assert code.add(10, 11) == 33 tests/test_code.py:5: AssertionError ================================================ 1 failed in 0.01 seconds ================================================ + where <function add at 0x105d4d6e0> = code.add def test_add failing(): assert code.add(10, 11) == 33 assert 21 == 33 + where 21 = <function add at 0x105d4d6e0>(10, 11) > E E E $ py.test ================================================== test session starts =================================================== platform darwin -- Python 2.7.10, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 rootdir: /projectroot, inifile: collected 1 items tests/test_code.py F ======================================================== FAILURES ======================================================== test_add failing # projectroot/module/stuff.py class Stuff(object): def prep(self): self.foo = 1 Pruebas de falla Una prueba fallida proporcionará resultados útiles en cuanto a lo que salió mal: Resultados: Introducción a los accesorios de prueba Las pruebas más complicadas a veces necesitan tener las cosas configuradas antes de ejecutar el código que desea probar. Es posible hacer esto en la función de prueba en sí, pero luego terminas con funciones de prueba grandes que hacen tanto que es difícil decir dónde se detiene la configuración y comienza la prueba. También puede obtener una gran cantidad de códigos de configuración duplicados entre sus diversas funciones de prueba. Nuestro archivo de código: ================================================ 1 passed in 0.01 seconds ================================================
    • 865. 800 # projectroot/tests/test_stuff.py import pytest from module import stuff def test_foo_updates(): my_stuff = stuff.Stuff() my_stuff.prep() assert 1 == my_stuff.foo my_stuff.foo = 30000 assert my_stuff.foo == 30000 def test_bar_updates(): my_stuff = stuff.Stuff() my_stuff.prep() assert 2 == my_stuff.bar my_stuff.bar = 42 assert 42 == my_stuff.bar # projectroot/tests/test_stuff.py import pytest from module import stuff def get_prepped_stuff(): my_stuff = stuff.Stuff() my_stuff.prep() return my_stuff def test_foo_updates(): my_stuff = get_prepped_stuff() assert 1 == my_stuff.foo my_stuff.foo = 30000 assert my_stuff.foo == 30000 def test_bar_updates(): my_stuff = get_prepped_stuff() assert 2 == my_stuff.bar my_stuff.bar = 42 assert 42 == my_stuff.bar Nuestro archivo de prueba: Estos son ejemplos bastante simples, pero si nuestro objeto Stuff necesitara mucha más configuración, se volvería difícil de manejar. Vemos que hay un código duplicado entre nuestros casos de prueba, así que vamos a reformular eso en una función separada primero. Esto se ve mejor, pero todavía tenemos la my_stuff = get_prepped_stuff() nuestras funciones de prueba. Py.test accesorios para el rescate! self.bar = 2
    • 866. 801 @pytest.fixture def prepped_stuff(): my_stuff = stuff.Stuff() my_stuff.prep() return my_stuff def test_foo_updates(prepped_stuff): my_stuff = prepped_stuff assert 1 == my_stuff.foo my_stuff.foo = 30000 assert my_stuff.foo == 30000 def test_bar_updates(prepped_stuff): my_stuff = prepped_stuff assert 2 == my_stuff.bar my_stuff.bar = 42 assert 42 == my_stuff.bar def test_foo_updates(prepped_stuff): assert 1 == prepped_stuff.foo prepped_stuff.foo = 30000 assert prepped_stuff.foo == 30000 def test_bar_updates(prepped_stuff): assert 2 == prepped_stuff.bar prepped_stuff.bar = 42 assert 42 == prepped_stuff.bar Los accesorios son versiones mucho más potentes y flexibles de las funciones de configuración de prueba. Pueden hacer mucho más de lo que estamos aprovechando aquí, pero lo haremos paso a paso. Primero cambiamos get_prepped_stuff a un dispositivo llamado prepped_stuff . Desea nombrar sus aparatos con sustantivos en lugar de verbos debido ala forma en que los aparatos se utilizarán en las funciones de prueba más adelante. El @pytest.fixture indica que esta función específica debe manejarse como un accesorio en lugar de una función regular. Ahora debemos actualizar las funciones de prueba para que usen el aparato. Esto se hace agregando un parámetro a su definición que coincida exactamente con el nombre del dispositivo. Cuando se ejecuta py.test, ejecutará el dispositivo antes de ejecutar la prueba, luego pasará el valor de retorno del dispositivo a la función de prueba a través de ese parámetro. (Tenga en cuenta que los dispositivos no necesitan devolver un valor; en su lugar, pueden hacer otras tareas de configuración, como llamar a un recurso externo, organizar las cosas en el sistema de archivos, poner valores en una base de datos, independientemente de las pruebas necesarias para la configuración) Ahora puedes ver por qué lo nombramos con un sustantivo. pero la línea my_stuff = prepped_stuff es bastante inútil, así que simplemente utilicemos prepped_stuff directamente. Ahora estamos usando accesorios! Podemos ir más lejos cambiando el alcance del dispositivo
    • 867. 802 # projectroot/module/stuff.py class Stuff(object): def prep(self): self.foo = 1 self.bar = 2 def finish(self): self.foo = 0 self.bar = 0 @pytest.fixture def prepped_stuff(request): # we need to pass in the request to use finalizers my_stuff = stuff.Stuff() my_stuff.prep() def fin(): # finalizer function # do all the cleanup here my_stuff.finish() request.addfinalizer(fin) # register fin() as a finalizer # you can do more setup here if you really want to return my_stuff @pytest.yield_fixture (de modo que solo se ejecute una vez por módulo de prueba o sesión de ejecución del conjunto de pruebas en lugar de una vez por función de prueba), construyendo dispositivos que utilicen otros dispositivos, parametrizando el dispositivo (para que el dispositivo y todo las pruebas que usan ese dispositivo se ejecutan varias veces, una vez para cada parámetro dado al dispositivo), dispositivos que leen los valores del módulo que los llama ... como se mencionó anteriormente, los dispositivos tienen mucha más potencia y flexibilidad que una función de configuración normal. Limpieza después de las pruebas. Digamos que nuestro código ha crecido y nuestro objeto Stuff ahora necesita una limpieza especial. Podríamos agregar algún código para llamar a la limpieza al final de cada función de prueba, pero los dispositivos proporcionan una mejor manera de hacerlo. Si agrega una función al dispositivo y lo registra como finalizador , se llamará al código en la función de finalizador después de que se realice la prueba con el dispositivo. Si el alcance del dispositivo es mayor que una sola función (como módulo o sesión), el finalizador se ejecutará una vez que se hayan completado todas las pruebas en el alcance, por lo que una vez que el módulo haya terminado de ejecutarse o al final de toda la sesión de ejecución de prueba . Usar la función de finalizador dentro de una función puede ser un poco difícil de entender a primera vista, especialmente cuando tienes dispositivos más complicados.En su lugar, puede utilizarundispositivo de rendimiento para hacerlo mismoconun flujode ejecuciónlegiblemás humano. La única diferencia real es que, en lugar de utilizar la return , usamos un yield en la parte del dispositivo donde se realiza la configuración y el control debeir a una función de prueba, luego se agrega todo el código de limpieza después del yield . También lo decoramos como un yield_fixture para que py.test sepa cómo manejarlo.
    • 868. 803 ¡Y eso concluye la Introducción a los Aparatos de Prueba! Para obtener más información, consulte la documentación oficial de la prueba py.test y la documentación oficial de la unidad de rendimiento. def prepped_stuff(): # it doesn't need request now! # do setup my_stuff = stuff.Stuff() my_stuff.prep() # setup is done, pass control to the test functions yield my_stuff # do cleanup my_stuff.finish()
    • 869. 804 """PyAudio Example: Play a wave file (callback version).""" import pyaudio import wave import time import sys if len(sys.argv) < 2: print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0]) sys.exit(-1) wf = wave.open(sys.argv[1], 'rb') # instantiate PyAudio (1) p = pyaudio.PyAudio() # define callback (2) def callback(in_data, frame_count, time_info, status): data = wf.readframes(frame_count) return (data, pyaudio.paContinue) Capítulo 165: pyaudio Introducción PyAudio proporciona enlaces de Python para PortAudio, la biblioteca de E / S de audio multiplataforma. Con PyAudio, puede usar Python fácilmente para reproducir y grabar audio en una variedad de plataformas. PyAudio está inspirado en: 1.pyPortAudio / fastaudio: enlaces de Python para la API de PortAudio v18. 2.tkSnack: kit de herramientas de sonido multiplataforma para Tcl / Tk y Python. Observaciones Nota: se llama a stream_callback en un hilo separado (del hilo principal). Las excepciones que se producen en el stream_callback: 1. Imprima un rastreo de error estándar para ayudar a la depuración, 2 .queue la excepción que se lanzará (en algún momento) en el hilo principal, y 3. Devuelva paAbort a PortAudio para detener la transmisión. Nota: No llame a Stream.read () ni a Stream.write () si usa una operación sin bloqueo. Ver: firma de devolución de llamada de PortAudio para detalles adicionales: http://portaudio.com/docs/v19- doxydocs/portaudio_8h.html#a8a60fb2a5ec9cbade3f54a9c978e2710 Examples Modo de devolución de llamada de audio I / O
    • 870. 805 import pyaudio import wave import sys CHUNK = 1024 if len(sys.argv) < 2: print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0]) sys.exit(-1) wf = wave.open(sys.argv[1], 'rb') # instantiate PyAudio (1) p = pyaudio.PyAudio() Enel modo de devolución de llamada,PyAudio llamará a una función de devolución dellamada especificada(2) siempreque necesitenuevosdatos deaudio(para reproducir) y /ocuandohaya nuevos datos de audio (grabados)disponibles.Tenga en cuenta quePyAudiollama a la función de devolución de llamada en un hilo separado. La función tiene la siguiente callback(<input_data>, <frame_count>, <time_info>, <status_flag>) firma callback(<input_data>, <frame_count>, <time_info>, <status_flag>) y debe devolver una tupla que contiene fotogramas frame_count de datos de audio y una bandera que indica si hay más frames para reproducir / grabar. Comience a procesar la transmisión de audio utilizando pyaudio.Stream.start_stream () (4), que llamará repetidamente a la función de devolución de llamada hasta que esa función devuelva pyaudio.paComplete . Para mantener el flujo activo, el hilo principal no debe terminar, por ejemplo, durmiendo (5). Modo de bloqueo de E / S de audio "" "Ejemplo de PyAudio: reproducir un archivo wave." "" # open stream using callback (3) stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), channels=wf.getnchannels(), rate=wf.getframerate(), output=True, stream_callback=callback) # start the stream (4) stream.start_stream() # wait for stream to finish (5) while stream.is_active(): time.sleep(0.1) # stop stream (6) stream.stop_stream() stream.close() wf.close() # close PyAudio (7) p.terminate()
    • 871. 806 Para usar PyAudio, primero cree una instancia de PyAudio usando pyaudio.PyAudio () (1), que configura el sistema portaudio. Para grabar o reproducir audio, abra una transmisión en el dispositivo deseado con los parámetros de audio deseados utilizando pyaudio.PyAudio.open () (2). Esto configura un pyaudio.Stream para reproducir o grabar audio. Reproduce el audio escribiendo datos de audio en la transmisión usando pyaudio.Stream.write () , o lee los datos de audio de la transmisión usando pyaudio.Stream.read () . (3) Tenga en cuenta que en el " modo de bloqueo ", cada pyaudio.Stream.write () o pyaudio.Stream.read () se bloquea hasta que todos los cuadros dados / solicitados se hayan reproducido / grabado. Alternativamente, para generar datos de audio sobre la marcha o procesar inmediatamente los datos de audio grabados, use el "modo de devolución de llamada" ( consulte el ejemplo en el modo de devolución de llamada ) Use pyaudio.Stream.stop_stream () para pausar la reproducción / grabación, y pyaudio.Stream.close () para terminar la transmisión. (4) Finalmente, finalice la sesión de portaudio utilizando pyaudio.PyAudio.terminate () (5) # open stream (2) stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), channels=wf.getnchannels(), rate=wf.getframerate(), output=True) # read data data = wf.readframes(CHUNK) # play stream (3) while len(data) > 0: stream.write(data) data = wf.readframes(CHUNK) # stop stream (4) stream.stop_stream() stream.close() # close PyAudio (5) p.terminate()
    • 872. 807 pip install pygame Capítulo 166: pygame Introducción Pygame es la biblioteca de acceso para hacer aplicaciones multimedia, especialmente juegos, en Python. El sitio web oficial es http://www.pygame.org/ . Sintaxis • pygame.mixer.init (frecuencia = 22050, tamaño = -16, canales = 2, búfer = 4096) • pygame.mixer.pre_init (frecuencia, tamaño, canales, búfer) • pygame.mixer.quit () • pygame.mixer.get_init () • pygame.mixer.stop () • pygame.mixer.pause () • pygame.mixer.unpause () • pygame.mixer.fadeout (tiempo) • pygame.mixer.set_num_channels (count) • pygame.mixer.get_num_channels () • pygame.mixer.set_reserved (cuenta) • pygame.mixer.find_channel (force) • pygame.mixer.get_busy () Parámetros Parámetro Detalles contar Un entero positivo que representa algo así como la cantidad de canales necesarios para ser reservados. fuerza Un valor booleano ( False o True ) que determina si find_channel() tiene que devolver un canal (inactivo o no) con True o no (si no hay canales inactivos) con False Examples Instalando pygame Con pip Con conda :
    • 873. 808 pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=4096) Descarga directa desde el sitio web: http://www.pygame.org/download.shtml Puede encontrar los instaladores adecuados para Windows y otros sistemas operativos. Los proyectos también se pueden encontrar en http://www.pygame.org/ Modulo mezclador de pygame El módulo pygame.mixer ayuda a controlar la música utilizada en los programas de pygame . A partir de ahora, hay 15 funciones diferentes para el módulo mixer. Inicializando De manera similar a cómo tienes que inicializar pygame con pygame.init() , también debes inicializar pygame.mixer . Al usar la primera opción, inicializamos el módulo usando los valores predeterminados. Puede, sin embargo, anular estas opciones predeterminadas. Al usar la segunda opción, podemos inicializar el módulo usando los valores que manualmente ingresamos en nosotros mismos. Valores estándar: Para verificar si lo hemos inicializado o no, podemos usar pygame.mixer.get_init() , que devuelve True si es y False si no lo es. Para salir / deshacer la inicialización, simplemente use pygame.mixer.quit() .Si desea continuar reproduciendo sonidos con el módulo, es posible que deba reinicializar el módulo. Posibles acciones Mientras se reproduce su sonido, puede pausarlo temporalmente con pygame.mixer.pause() . Para reanudar la reproducción de sus sonidos, simplemente use pygame.mixer.unpause() . También puedes desvanecer el final del sonido utilizando pygame.mixer.fadeout() . Se necesita un argumento, que es la cantidad de milisegundos que se tarda en terminar de desvanecerse la música. Los canales Puede reproducir tantas canciones como sea necesario siempre que haya suficientes canales abiertos para admitirlas. Por defecto, hay 8 canales. Para cambiar la cantidad de canales que hay, use pygame.mixer.set_num_channels() . El argumento es un entero no negativo. Si la cantidad de canales disminuye, cualquier sonido que se reproduzca en los canales eliminados se detendrá conda install -c tlatorre pygame=1.9.2
    • 874. 809 de inmediato. Para saber cuántos canales se están utilizando actualmente, llame a pygame.mixer.get_channels(count) . La salida es el número de canales que no están abiertos actualmente. También puede reservar canales para los sonidos que deben reproducirse utilizando pygame.mixer.set_reserved(count) . El argumento también es un entero no negativo. Cualquier sonido que se reproduzca en los canales recién reservados no se detendrá. También puede averiguar qué canal no se está utilizando mediante el uso de pygame.mixer.find_channel(force) . Su argumento es un bool: verdadero o falso. Si no hay canales que estén inactivos y la force sea Falso, devolverá None . Si la force es verdadera, devolverá el canal que ha estado tocando durante más tiempo.
    • 875. 810 import pyglet window = pyglet.window.Window() label = pyglet.text.Label('Hello, world', font_name='Times New Roman', font_size=36, x=window.width//2, y=window.height//2, anchor_x='center', anchor_y='center') @window.event def on_draw(): window.clear() label.draw() pyglet.app.run() pip3 install pyglet sound = pyglet.media.load(sound.wav) sound.play() import pyglet from pyglet.gl import * Capítulo 167: Pyglet Introducción Pyglet es un módulo de Python utilizado para efectos visuales y de sonido. No tiene dependencias en otros módulos. Ver [pyglet.org] [1] para la información oficial. [1]: http://pyglet.org Examples Hola Mundo en Pyglet Instalación de Pyglet Instala Python, entra en la línea de comandos y escribe: Python 2: Python 3: Reproducción de sonido en Pyglet Usando Pyglet para OpenGL pip install pyglet
    • 876. 811 import pyglet from pyglet.gl import * win = pyglet.window.Window() glClear(GL_COLOR_BUFFER_BIT) @win.event def on_draw(): glBegin(GL_POINTS) glVertex2f(x, y) #x is desired distance from left side of window, y is desired distance from bottom of window #make as many vertexes as you want glEnd Dibujar puntos usando Pyglet y OpenGL Para conectar los puntos, reemplace GL_POINTS con GL_LINE_LOOP . win = pyglet.window.Window() @win.event() def on_draw(): #OpenGL goes here. Use OpenGL as normal. pyglet.app.run()
    • 877. 812 pip install pyinstaller Capítulo 168: PyInstaller - Distribuir código de Python Sintaxis • pyinstaller [opciones] script [script ...] | archivo de especificaciones Observaciones PyInstaller es un módulo utilizado para agrupar aplicaciones de Python en un solo paquete junto con todas las dependencias. El usuario puede ejecutar la aplicación del paquete sin un intérprete de Python o cualquier módulo. Combina correctamente muchos paquetes importantes como numpy, Django, OpenCv y otros. Algunos puntos importantes para recordar: • Pyinstaller es compatible con Python 2.7 y Python 3.3+ • Pyinstaller ha sido probado contra Windows, Linux y Mac OS X. • NO es un compilador cruzado. (Una aplicación de Windows no se puede empaquetar en Linux. Debe ejecutar PyInstaller en Windows para agrupar una aplicación para Windows) Página de inicio documentos oficiales Examples Instalación y configuración Pyinstaller es un paquete normal de Python. Se puede instalar utilizando pip: Instalación en Windows Para Windows, pywin32 o pypiwin32 es un requisito previo. Este último se instala automáticamente cuando se instala pyinstaller usando pip. Instalación en Mac OS X PyInstaller funciona con el Python 2.7 predeterminado que se proporciona con el Mac OS X actual. Si se van a usar versiones posteriores de Python o si se deben usar paquetes importantes como PyQT, Numpy, Matplotlib y similares, se recomienda instalarlos usando ya sea MacPorts o Homebrew . Instalación desde el archivo Si pip no está disponible, descargue el archivo comprimido desde PyPI . Para probar la versión de desarrollo, descargue el archivo comprimido desde la rama de
    • 878. 813 desarrollo de la página de descargas de PyInstaller . Expandaelarchivoyencuentreel scriptsetup.py .Ejecutepython setup.py install conprivilegio de administrador para instalar o actualizar PyInstaller. Verificando la instalación El comando pyinstaller debería existir en la ruta del sistema para todas las plataformas después de una instalación exitosa. pyinstaller --version escribiendo pyinstaller --version en la línea de comando. Esto imprimirá la versión actual de pyinstaller. Usando Pyinstaller En el caso de uso más simple, simplemente navegue hasta el directorio en el que se encuentra su archivo y escriba: pyinstaller myfile.py Pyinstaller analiza el archivo y crea: • Un archivo myfile.spec en el mismo directorio que myfile.py • Una carpeta de compilación en el mismo directorio que myfile.py • Una carpeta dist en el mismo directorio que myfile.py • Archivos de registro en la carpeta de compilación La aplicación incluida se puede encontrar en la carpeta dist Opciones Hay varias opciones que se pueden usar con pyinstaller. Una lista completa de las opciones se puede encontrar aquí . Una vez que su aplicación se puede empaquetar, abra 'dist \ myfile \ myfile.exe'. Agrupar en una carpeta Cuando se usa PyInstaller sin ninguna opción para agrupar myscript.py , la salida predeterminada es una única carpeta (denominada myscript ) que contiene un ejecutable llamado myscript ( myscript.exe en Windows) junto con todas las dependencias necesarias. La aplicación se puede distribuir comprimiendo la carpeta en un archivo zip. El mododeunacarpetasepuedeconfigurar explícitamente con la opción-D o--onedir pyinstaller myscript.py -D Ventajas: Una de las principales ventajas de agrupar en una sola carpeta es que es más fácil depurar problemas. Si alguno de los módulos no se puede importar, puede verificarse inspeccionando la
    • 879. 814 carpeta. Otra ventaja se siente durante las actualizaciones. Si hay algunos cambios en el código pero las dependencias utilizadas son exactamente las mismas, los distribuidores pueden enviar el archivo ejecutable (que generalmente es más pequeño que la carpeta completa). Desventajas La única desventaja de este método es que los usuarios tienen que buscar el ejecutable entre una gran cantidad de archivos. Además, los usuarios pueden eliminar / modificar otros archivos, lo que puede hacer que la aplicación no funcione correctamente. Agrupar en un solo archivo pyinstaller myscript.py -F Lasopciones paragenerar unsoloarchivo son-F o--onefile .Estomyscript.exe el programaen un solo archivo myscript.exe . Un solo archivo ejecutable es más lento que el paquete de una carpeta. También son más difíciles de depurar.
    • 880. 815 from ply import lex import ply.yacc as yacc tokens = ( 'PLUS', 'MINUS', 'TIMES', 'DIV', 'LPAREN', 'RPAREN', Capítulo 169: Python Lex-Yacc Introducción PLY es una implementación pura de Python de las populares herramientas de construcción de compiladores lex y yacc. Observaciones Enlaces adicionales: 1. Documentos oficiales 2. Github Examples Empezando con PLY Para instalar PLY en su máquina para python2 / 3, siga los pasos descritos a continuación: 1. Descarga el código fuente desde aquí . 2. Descomprima el archivo zip descargado. 3. Navegue en la carpeta ply-3.10 descomprimida 4. Ejecute el siguiente comando en su terminal: python setup.py install Sicompletó todolo anterior, ahoradeberíapoderusarel móduloPLY.Puedeprobarloabriendo un intérprete de python y escribiendo import ply.lex. Nota: No utilice pip para instalar PLY, se instalará una distribución rota en su máquina. El "¡Hola mundo!" de PLY - Una calculadora simple Demostremos el poder de PLY con un ejemplo simple: este programa tomará una expresión aritmética como una entrada de cadena e intentará resolverla. Abre tu editor favorito y copia el siguiente código:
    • 881. 816 'NUMBER', ) t_ignore = ' \t' t_PLUS = r'\+' t_MINUS = r'-' t_TIMES = r'\*' t_DIV = r'/' t_LPAREN = r'\(' t_RPAREN = r'\)' deft_NUMBER(t): r'[0-9]+' t.value = int( t.value ) return t def t_newline( t): r'\n+' t.lexer.lineno += len( t.value ) def t_error( t ): print("Invalid Token:",t.value[0]) t.lexer.skip( 1 ) lexer = lex.lex() precedence = ( ( 'left', 'PLUS', 'MINUS' ), ( 'left', 'TIMES', 'DIV' ), ( 'nonassoc', 'UMINUS' ) ) def p_add( p ) : 'expr : expr PLUS expr' p[0] = p[1] + p[3] def p_sub( p ) : 'expr : expr MINUS expr' p[0] = p[1] - p[3] def p_expr2uminus( p ) : 'expr: MINUS expr %prec UMINUS' p[0] = - p[2] def p_mult_div( p ) : '''expr : expr TIMES expr | expr DIV expr''' if p[2] == '*' : p[0] = p[1] * p[3] else : if p[3] == 0 : print("Can't divide by 0") raise ZeroDivisionError('integer division by 0') p[0] = p[1] / p[3] defp_expr2NUM(p): 'expr: NUMBER' p[0] = p[1]
    • 882. 817 import ply.lex as lex # List of token names. This is always required tokens = [ 'NUMBER', 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'LPAREN', 'RPAREN', ] # Regular expression rules for simple tokens # A regular expression rule with some action code def t_NUMBER(t): r'\d+' t.value = int(t.value) return t Guarde este archivo como calc.py y ejecútelo. Salida: ¿Cuál es la respuesta correcta para -4 * - (3 - 5) ? Parte 1: Tokenizing entrada con Lex Hay dos pasos que llevó a cabo el código del ejemplo 1: uno fue tokenizar la entrada, lo que significa que buscó los símbolos que constituyen la expresión aritmética, y el segundo paso fue analizar , lo que implica analizar los tokens extraídos y evaluar el resultado. Esta sección proporciona un ejemplo simple de cómo tokenizar la entrada del usuario, y luego la divide línea por línea. t_PLUS = r'\+' t_MINUS = r'-' t_TIMES = r'\*' t_DIVIDE = r'/' t_LPAREN = r'\(' t_RPAREN = r'\)' -8 def p_parens( p ) : 'expr : LPAREN expr RPAREN' p[0] = p[2] def p_error( p ): print("Syntax error in input!") parser = yacc.yacc() res = parser.parse("-4*-(3-5)") # the input print(res)
    • 883. 818 tokens = [ 'NUMBER', 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'LPAREN', 'RPAREN', ] Guarde este archivo como calclex.py . Usaremos esto cuando construyamos nuestro analizador de Yacc. Descompostura 1. Importe el módulo usando import ply.lex 2. Todos los lexers deben proporcionar una lista llamada tokens que define todos los posibles nombres de token que puede producir el lexer. Esta lista siempre es obligatoria. tokens también podrían ser una tupla de cadenas (en lugar de una cadena), donde cada cadena denota un token como antes. 3. La regla de expresiones regulares para cada cadena puede definirse como una cadena o como una función. En cualquier caso, el nombre de la variable debe tener el prefijo t_ para denotar que es una regla para hacer coincidir tokens. # Define a rule so we can track line numbers def t_newline(t): r'\n+' t.lexer.lineno += len(t.value) #Astringcontainingignoredcharacters(spacesandtabs) t_ignore = ' \t' # Error handling rule def t_error(t): print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1) # Build the lexer lexer = lex.lex() # Give the lexer some input lexer.input(data) # Tokenize while True: tok = lexer.token() if not tok: break # No more input print(tok)
    • 884. 819 def t_NUMBER(t): r'\d+' t.value = int(t.value) return t def t_newline(t): r'\n+' t.lexer.lineno += len(t.value) def t_COMMENT(t): r'\#.*' pass # No return value. Token discarded • Para tokens simples, la expresión regular se puede especificar como cadenas: t_PLUS = r'\+' • Si es necesario realizar algún tipo de acción, se puede especificar una regla de token como una función. Tenga en cuenta que la regla se especifica como una cadena de documentación dentro de la función. La función acepta un argumento que es una instancia de LexToken , realiza alguna acción y luego devuelve el argumento. Si desea usar una cadena externa como regla de expresión regular para la función en lugar de especificar una cadena de documentación, considere el siguiente ejemplo: @TOKEN(identifier) def t_ID(t): ... #actions # identifier is a string holding the regex • Unainstanciadeobjeto LexToken(llamemosaesteobjetot)tienelossiguientes atributos: 1. t.typeque es el tipo de token (como una cadena) (por ejemplo: 'NUMBER' , 'PLUS' , etc.). Por defecto, t.type se establece en el nombre que sigue al prefijo t_ . 2. t.value que es el lexema (el texto real t.value ) 3. t.lineno que es el número de línea actual (esto no se actualiza automáticamente, ya que el lexer no sabe nada de los números de línea). Actualiza lineno usando una función llamada t_newline . 4. t.lexpos que es la posición del token en relación con el comienzo del texto de entrada. • Si no se devuelve nada de una función de regla de expresiones regulares, el token se descarta. Si desea descartar un token, alternativamente puede agregar el prefijo t_ignore_ a una variable de regla de expresiones regulares en lugar de definir una función para la misma regla. ...Es lo mismo que:
    • 885. 820 t_ignore_COMMENT = r'\#.*' t_ignore = ' \t' # ignores spaces andtabs literals = [ '+', '-', '*', '/' ] literals = "+-*/" literals = [ '{', '}' ] def t_lbrace(t): r'\{' t.type = '{' #Set token type to the expected literal (ABSOLUTEMUST if this is a literal) return t # Error handling rule def t_error(t): print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1) # skip the illegal token (don't process it) Por supuesto, esto no es válido si está realizando alguna acción cuando ve un comentario. En cuyo caso, use una función para definir la regla de expresiones regulares. Si no ha definido un token para algunos caracteres pero aún quiere ignorarlo, use t_ignore = "<characters to ignore>" (estos prefijos son necesarios): • Al crear la expresión regular maestra, lex agregará las expresiones regulares especificadas en el archivo de la siguiente manera: 1. Las fichas definidas por funciones se agregan en el mismo orden en que aparecen en el archivo. 2. Los tokens definidos por cadenas se agregan en orden decreciente de la longitud de la cadena que define la expresión regular para ese token. Si coincide == y = en el mismo archivo, aproveche estas reglas. • Los literales son tokens que se devuelven como son. Tanto t.type como t.valuese establecerán en el propio carácter. Defina una lista de literales como tales: o, Es posible escribir funciones de token que realizan acciones adicionales cuando se combinan literales. Sin embargo, deberás configurar el tipo de token de forma adecuada. Por ejemplo: • Manejar errores con la función t_error. t_ignore_COMMENT = r'\#.*'
    • 886. 821 # Build the lexer # m = MyLexer() m.build() m.test("3 + 4") # Build the lexer def build(self, **kwargs): self.lexer = lex.lex(module=self, **kwargs) def test(self, data): self.lexer.input(data) for token in self.lexer.token(): print(token) # Build the lexer and try it out usual ... # everything relating to token rules and error handling comes here as import ply.lex as lex class MyLexer(object): for i in lexer: print(i) # Yacc example import ply.yacc as yacc # Get the token map from the lexer. This is required. from calclex import tokens def p_expression_plus(p): 'expression : expression PLUS term' p[0] = p[1] + p[3] En general, t.lexer.skip(n) omite n caracteres en la cadena de entrada. 4. Preparativos finales Construya el lexer usando lexer = lex.lex() . También puede colocar todo dentro de una clase y llamar a la instancia de uso de la clase para definir el lexer. P.ej: Proporcione entrada utilizando lexer.input(data) donde los datos son una cadena Para obtener los tokens, use lexer.token() que devuelve tokens coincidentes. Puede iterar sobre lexer en un bucle como en: Parte 2: Análisis de entrada Tokenized con Yacc Esta sección explica cómo se procesa la entrada tokenizada de la Parte 1: se realiza utilizando las gramáticas libres de contexto (CFG). Se debe especificar la gramática y los tokens se procesan de acuerdo con la gramática. Bajo el capó, el analizador utiliza un analizador LALR.
    • 887. 822 def p_expression_plus(p): 'expression : expression PLUS term' def p_expression_minus(p): 'expression : expression MINUS term' p[0] = p[1] - p[3] def p_expression_term(p): 'expression : term' p[0] = p[1] def p_term_times(p): 'term:termTIMESfactor' p[0] = p[1] *p[3] def p_term_div(p): 'term:termDIVIDEfactor' p[0] = p[1] / p[3] def p_term_factor(p): 'term : factor' p[0] = p[1] def p_factor_num(p): 'factor: NUMBER' p[0] = p[1] def p_factor_expr(p): 'factor : LPAREN expression RPAREN' p[0] = p[2] # Error rule for syntax errors def p_error(p): print("Syntax error in input!") # Build the parser parser = yacc.yacc() while True: try: s = raw_input('calc > ') except EOFError: break if not s: continue result = parser.parse(s) print(result) Descompostura • Cada regla gramatical está definida por una función donde la cadena de documentación de esa función contiene la especificación gramatical libre de contexto apropiada. Las declaraciones que conforman el cuerpo de la función implementan las acciones semánticas de la regla. Cada función acepta un solo argumento p que es una secuencia que contiene los valores de cada símbolo gramatical en la regla correspondiente. Los valores de p[i] se asignan a símbolos gramaticales como se muestra aquí:
    • 888. 823 p[0] = p[1] + p[3] def p_binary_operators(p): '''expression : expression PLUS term | expression MINUS term term : term TIMES factor | termDIVIDEfactor''' if p[2] == '+': p[0] = p[1] + p[3] elif p[2] == '-': p[0] = p[1] - p[3] elif p[2] == '*': p[0] = p[1] * p[3] elif p[2] == '/': p[0] = p[1] / p[3] def p_binary_operators(p): '''expression : expression '+' term |expression'-'term term : term '*' factor | term '/' factor''' if p[2] == '+': p[0] = p[1] + p[3] elif p[2] == '-': p[0] = p[1] - p[3] elif p[2] == '*': p[0] = p[1] * p[3] elif p[2] == '/': p[0] = p[1] / p[3] # ^ ^ ^ ^ # p[0] p[1] p[2] p[3] • Para los tokens, el "valor" de la p[i] es el mismo que el atributo p.value asignado en el módulo lexer. Por lo tanto, PLUS tendrá el valor + . • Para no terminales, el valor se determina por lo que se coloque en p[0] . Si no se coloca nada, el valor es Ninguno. Además, p[-1] no es lo mismo que p[3] , ya que p no es una lista simple ( p[-1] puede especificar acciones incrustadas (no se trata aquí)). Tenga en cuenta que la función puede tener cualquier nombre, siempre que esté precedida por p_ . • La p_error(p) se define para detectar errores de sintaxis (igual que yyerror en yacc / bison). • Se pueden combinar varias reglas gramaticales en una sola función, lo que es una buena idea si las producciones tienen una estructura similar. • Se pueden usar caracteres literales en lugar de fichas. Por supuesto, los literales deben especificarse en el módulo lexer. • Lasproduccionesvacíastienenlaforma'''symbol:'''
    • 889. 824 precedence = ( ('nonassoc', 'LESSTHAN', 'GREATERTHAN'), # Nonassociative operators ('left', 'PLUS', 'MINUS'), ('left', 'TIMES', 'DIVIDE'), ('right', 'UMINUS'), # Unary minus operator ) • Paraestablecerexplícitamenteelsímbolodeinicio,usestart = 'foo',dondefooesalgo que no es terminal. • La configuración de la precedencia y la asociatividad se puede hacer utilizando la variable de precedencia. Los tokens se ordenan de menor a mayor precedencia. nonassoc significa que esos tokens no se asocian. Esto significa que algo como a < b < c es ilegal mientras que a < b todavía es legal. • parser.outesunarchivodedepuraciónquesecreacuandoseejecutaelprogramayaccpor primeravez.Cadavezqueseproduceunconflictodedesplazamiento/reducción,el analizador siempre cambia.
    • 890. 825 from requests import post foo = post('http://httpbin.org/post', data = {'key':'value'}) print(foo.headers) {'Content-Length':'439','X-Processed-Time':'0.000802993774414','X-Powered-By':'Flask', 'Server': 'meinheld/0.6.1', 'Connection': 'keep-alive', 'Via': '1.1 vegur', 'Access-ControlAllow-Credentials':'true','Date':'Sun,21May201720:56:05GMT','Access-Control-AllowOrigin': '*', 'Content-Type': 'application/json'} headers = {'Cache-Control':'max-age=0', 'Upgrade-Insecure-Requests':'1', 'User-Agent':'Mozilla/5.0 (WindowsNT10.0;Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36', 'Content-Type':'application/x-www-form-urlencoded', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Referer':'https://www.groupon.com/signup', 'Accept-Encoding':'gzip, deflate, br', 'Accept-Language':'es-ES,es;q=0.8' } foo = post('http://httpbin.org/post', headers=headers, data = {'key':'value'}) Capítulo 170: Python Requests Post Introducción Documentación para el módulo de solicitudes de Python en el contexto del método HTTP POST y su función de solicitudes correspondiente Examples Post simple Realizará una simple operación HTTP POST. Los datos publicados pueden ser en la mayoría de los formatos, sin embargo, los pares de valores clave son los más frecuentes. Encabezados Los encabezados pueden ser vistos: Un ejemplo de respuesta: Los encabezados también se pueden preparar antes de la publicación: Codificación La codificación se puede configurar y ver de la misma manera:
    • 891. 826 foo = post('http://httpbin.org/post', data = {'key':'value'}, verify=False) foo = post('http://httpbin.org/post', data = {'key':'value'}, allow_redirects=False) print(foo.url) print(foo.history) from requests import post payload = {'key1' : 'value1', 'key2' : 'value2' } foo = post('http://httpbin.org/post', data=payload) from requests import post payload = {'key1' : 'value1', 'key2' : 'value2'} foo = post('http://httpbin.org/post',json=payload) Verificación SSL Las solicitudes por defecto valida los certificados SSL de los dominios. Esto puede ser anulado: Redireccion Se seguirá cualquier redirección (por ejemplo, http a https), esto también se puede cambiar: Si la operación posterior se ha redirigido, se puede acceder a este valor: Se puede ver un historial completo de redirecciones: Formulario de datos codificados Para pasar datos codificados de forma con la operación posterior, los datos deben estructurarse como diccionario y suministrarse como el parámetro de datos. Si los datos no desean estar codificados en forma, simplemente pase una cadena o un entero al parámetro de datos. Suministre el diccionario al parámetro json para que Solicitudes formateen los datos automáticamente: print(foo.encoding) 'utf-8' foo.encoding = 'ISO-8859-1'
    • 892. 827 from requests import post files = {'file' : open('data.txt', 'rb')} foo = post('http://http.org/post',files=files) files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})} foo = requests.post('http://httpbin.org/post', files=files) multiple_files = [ ('images', ('foo.png', open('foo.png', 'rb'), 'image/png')), ('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))] foo = post('http://httpbin.org/post', files=multiple_files) from requests import post foo = post('http://httpbin.org/post', data={'data' : 'value'}) print(foo.status_code) foo = post('http://httpbin.org/post', data={'data' : 'value'}) print(foo.text) Subir archivo Conel módulodesolicitudes, solo esnecesarioproporcionarunidentificadordearchivoen lugar de los contenidos recuperados con .read() : Nombre de archivo, tipo de contenido y encabezados también se pueden configurar: Lascadenas tambiénsepuedenenviarcomo unarchivo, siemprequeseproporcionencomoel parámetro de files . Múltiples archivos Se pueden suministrar varios archivos de la misma manera que un archivo: Respuestas Los códigos de respuesta se pueden ver desde una operación posterior: Datos devueltos Accediendo a los datos que se devuelven: Respuestas crudas En los casos en que necesite acceder al objeto subyacente urllib3 response.HTTPResponse, esto se puede hacer de la siguiente manera:
    • 893. 828 from requests import post foo = post('http://natas0.natas.labs.overthewire.org', auth=('natas0', 'natas0')) from requests import post from requests.auth import HTTPBasicAuth foo = post('http://natas0.natas.labs.overthewire.org', auth=HTTPBasicAuth('natas0', 'natas0')) from requests import post from requests.auth import HTTPDigestAuth foo = post('http://natas0.natas.labs.overthewire.org', auth=HTTPDigestAuth('natas0', 'natas0')) from requests.auth import AuthBase from requests.auth import _basic_auth_str from requests._internal_utils import to_native_string class CustomAuth(AuthBase): def init (self, secret_header, user_agent , username, password): # setup any auth-related datahere Autenticación Autenticación HTTP simple La autenticación HTTP simple se puede lograr con lo siguiente: Esta es una mano técnicamente corta para lo siguiente: Autentificación HTTP Digest La autenticación HTTP Digest se realiza de una manera muy similar, las solicitudes proporcionan un objeto diferente para esto: Autenticación personalizada En algunos casos, los mecanismos de autenticación integrados pueden no ser suficientes, imagine este ejemplo: Un servidor está configurado para aceptar la autenticación si el remitente tiene la cadena de usuario-agente correcta, un cierto valor de encabezado y proporciona las credenciales correctas a través de la autenticación básica HTTP. Para lograr esto, se debe preparar una clase de autenticación personalizada, subclasificando AuthBase, que es la base para las implementaciones de autenticación de solicitudes: foo = post('http://httpbin.org/post', data={'data' : 'value'}) res = foo.raw print(res.read())
    • 894. 829 foo = get('http://test.com/admin', auth=CustomAuth('SecretHeader', 'CustomUserAgent', 'user', 'password' )) from requests import post proxies = { 'http': 'http://192.168.0.128:3128', 'https': 'http://192.168.0.127:1080', } foo = requests.post('http://httpbin.org/post', proxies=proxies) proxies = {'http': 'http://user:pass@192.168.0.128:312'} foo = requests.post('http://httpbin.org/post', proxies=proxies) proxies = { 'http': 'socks5://user:pass@host:port', 'https': 'socks5://user:pass@host:port' } foo = requests.post('http://httpbin.org/post', proxies=proxies) Esto puede ser utilizado con el siguiente código: Proxies Cada operación POST de solicitud puede configurarse para usar proxies de red Proxies HTTP / S La autenticación básica HTTP se puede proporcionar de esta manera: SOCKS Proxies El uso de proxies de calcetines requiere requests[socks] dependencias de terceros requests[socks] ; una vez instalados, los proxies de calcetines se utilizan de manera muy similar a HTTPBasicAuth: self.secret_header = secret_header self.user_agent = user_agent self.username = username self.password = password def call (self, r): # modify and return the request r.headers['XSecret'] = self.secret_header r.headers['UserAgent'] = self.user_agent r.headers['Authorization'] = _basic_auth_str(self.username, self.password) return r
    • 895. 830 import os, sys from openpyxl import Workbook from datetime import datetime dt = datetime.now() list_values = [["01/01/2016", "05:00:00", 3],\ ["01/02/2016", "06:00:00",4],\ ["01/03/2016", "07:00:00",5],\ ["01/04/2016", "08:00:00",6],\ ["01/05/2016", "09:00:00", 7]] # Create a Workbook on Excel: wb = Workbook() sheet = wb.active sheet.title = 'data' # Print the titles into Excel Workbook: row = 1 sheet['A'+str(row)] = 'Date' sheet['B'+str(row)] = 'Hour' sheet['C'+str(row)] = 'Value' # Populate with data for item in list_values: row += 1 sheet['A'+str(row)] = item[0] sheet['B'+str(row)] = item[1] sheet['C'+str(row)] = item[2] # Save a file by date: filename = 'data_' + dt.strftime("%Y%m%d_%I%M%S") + '.xlsx' wb.save(filename) # Open the file for the user: os.chdir(sys.path[0]) os.system('start excel.exe "%s\\%s"' % (sys.path[0], filename, )) import openpyxl as opx #To change an existing wookbook we located it by referencing its path workbook = opx.load_workbook(workbook_path) Capítulo 171: Python y Excel Examples Ponga los datos de la lista en un archivo de Excel. OpenPyXL OpenPyXL es un módulo para manipular y crear libros de trabajo xlsx/xlsm/xltx/xltm en la memoria. Manipulando y leyendo un libro existente:
    • 896. 831 workbook = opx.load_workbook(workbook_path, read_only=True) first_sheet = workbook.worksheets[0] sheet = workbook.get_sheet_by_name('Sheet Name') for row in sheet.rows: print row[0].value #Calling the Workbook() function creates a new book in memory wb = opx.Workbook() #We can then create a new sheet in the wb ws = wb.create_sheet('Sheet Name', 0) #0 refers to the index of the sheet order in the wb ws.sheet_properties.tabColor = 'FFC0CB' wb.save('filename.xlsx') import xlsxwriter # sample data chart_data = [ {'name': 'Lorem', 'value': 23}, {'name': 'Ipsum', 'value': 48}, {'name': 'Dolor', 'value': 15}, load_workbook() contiene el parámetro read_only , estableciendo esto en True cargará el libro como read_only, esto es útil cuando se leen archivos xlsx más grandes: Una vez que haya cargado el libro en la memoria, puede acceder a las hojas individuales utilizando workbook.sheets Si desea especificar el nombre de una hoja disponible, puede usar workbook.get_sheet_names() . Finalmente, se puede acceder a las filas de la hoja utilizando sheet.rows . Para iterar sobre las filas de una hoja, use: Dado que cada row en rows es una lista de Cell , use Cell.value para obtener el contenido de la Celda. Creando un nuevo libro de ejercicios en la memoria: Se pueden cambiar varias propiedades de la pestaña a través de openpyxl, por ejemplo el tabColor : Para guardar nuestro libro creado terminamos con: Crear gráficos de Excel con xlsxwriter
    • 897. 832 {'name': 'Sit', 'value': 8}, {'name': 'Amet', 'value': 32} ] # excel file path xls_file = 'chart.xlsx' # the workbook workbook = xlsxwriter.Workbook(xls_file) # add worksheet to workbook worksheet = workbook.add_worksheet() row_ = 0 col_ = 0 # write headers worksheet.write(row_, col_, 'NAME') col_ += 1 worksheet.write(row_, col_, 'VALUE') row_ += 1 # write sample data for item in chart_data: col_ = 0 worksheet.write(row_, col_, item['name']) col_ += 1 worksheet.write(row_, col_, item['value']) row_ += 1 # create pie chart pie_chart = workbook.add_chart({'type': 'pie'}) # add series to pie chart pie_chart.add_series({ 'name': 'Series Name', 'categories': '=Sheet1!$A$3:$A$%s' % row_, 'values': '=Sheet1!$B$3:$B$%s' % row_, 'marker': {'type': 'circle'} }) # insert pie chart worksheet.insert_chart('D2', pie_chart) # create column chart column_chart = workbook.add_chart({'type': 'column'}) # add serie to column chart column_chart.add_series({ 'name': 'Series Name', 'categories': '=Sheet1!$A$3:$A$%s' % row_, 'values': '=Sheet1!$B$3:$B$%s' % row_, 'marker': {'type': 'circle'} }) # insert column chart worksheet.insert_chart('D20', column_chart) workbook.close() Resultado:
    • 898. 833 pip install xlrd Lee los datos de excel usando el módulo xlrd La biblioteca xlrd de Python es para extraer datos de los archivos de hoja de cálculo de Microsoft Excel (tm). Instalación:- O puedes usar el archivo setup.py de pypi https://pypi.python.org/pypi/xlrd
    • 899. 834 import xlrd book=xlrd.open_workbook('sample.xlsx') print book.nsheets print book.sheet_names() sheet=book.sheet_by_index(1) cell =sheet.cell(row,col) #where row=rownumber andcol=column number print cell.value #to print the cell contents num_rows=sheet.nrows num_col=sheet.ncols sheets = book.sheet_names() cur_sheet = book.sheet_by_name(sheets[0]) import xlsxwriter # create a new file workbook = xlsxwriter.Workbook('your_file.xlsx') # add some new formats to be used by the workbook percent_format = workbook.add_format({'num_format': '0%'}) percent_with_decimal = workbook.add_format({'num_format': '0.0%'}) bold = workbook.add_format({'bold': True}) red_font = workbook.add_format({'font_color': 'red'}) remove_format = workbook.add_format() # add a new sheet worksheet = workbook.add_worksheet() Leyendo una hoja de Excel: - Importe el módulo xlrd y abra el archivo de Excel usando el método open_workbook (). Consultar número de hojas en el excel. Imprimir los nombres de las hojas Obtener la hoja basada en el índice Leer el contenido de una celda. Obtenga el número de filas y el número de columnas en una hoja de Excel Obtener hoja de excel por nombre Formato de archivos de Excel con xlsxwriter
    • 900. 835 # set the width of column A worksheet.set_column('A:A', 30, ) # set column B to 20 and include the percent format we created earlier worksheet.set_column('B:B', 20, percent_format) # remove formatting from the first row (change in height=None) worksheet.set_row('0:0', None, remove_format) workbook.close()
    • 901. 836 Capítulo 172: Recolección de basura Observaciones Ensunúcleo,elrecolectordebasuradePython(apartirde3.5)esunaimplementaciónde conteodereferenciasimple.Cadavezquehaceunareferenciaaunobjeto(porejemplo,a = myobject)elrecuentodereferenciaeneseobjeto(myobject) seincrementa.Cadavezquese eliminaunareferencia,elrecuentodereferenciasdisminuye,yunavezqueelrecuentode referencias llega a 0 , sabemos que nada tiene una referencia a ese objeto y podemos desasignarlo. Un malentendido común acerca de cómo funciona la administración de memoria de Python es que la palabra clave del delimita la memoria de los objetos. Esto no es verdad. Lo que sucede en realidad es que la palabra clave del Delte simplemente reduce los refcount de los objetos, lo que significa que si lo llama suficientes veces para que el refcount llegue a cero, el objeto puede ser recolectado como basura (incluso si en realidad todavía hay referencias al objeto disponible en otra parte de su código). ). Python crea o limpia agresivamente los objetos la primera vez que los necesita. Si realizo la asignación a = object (), la memoria para el objeto se asigna en ese momento (cpython a veces reutilizará ciertos tipos de objetos, por ejemplo, listas bajo el capó, pero, en su mayoría, no mantiene un grupo de objetos libres y realizará la asignación cuando la necesite. De manera similar, tan pronto como el número de ref se reduce a 0, GC lo limpia. Recolección de basura generacional En la década de 1960, John McCarthy descubrió una falla fatal en el recuento de basura cuando implementó el algoritmo de recuento de cuentas utilizado por Lisp: ¿Qué sucede si dos objetos se refieren entre sí en una referencia cíclica? ¿Cómo puede alguna vez recolectar esos dos objetos de la basura incluso si no hay referencias externas a ellos si siempre se referirán entre ellos? Este problema también se extiende a cualquier estructura de datos cíclica, como los buffers de un anillo o dos entradas consecutivas en una lista con doble enlace. Python intenta solucionar este problema con un giro ligeramente interesante en otro algoritmo de recolección de basura llamado Generational Garbage Collection . En esencia, cada vez que creas un objeto en Python, lo agrega al final de una lista doblemente enlazada. En ocasiones, Python recorre esta lista, comprueba a qué objetos se refieren los objetos de la lista, y si también están en la lista (veremos por qué podrían no estar en un momento), disminuye aún más sus refcounts. En este punto (en realidad, hay algunas heurísticas que determinan cuándo se mueven las cosas, pero supongamos que después de una sola colección para mantener las cosas simples) cualquier cosa que aún tenga un refcount mayor que 0 se promociona a otra lista vinculada llamada "Generación 1" (esta es la razón por la que no todos los objetos están siempre en la lista de la generación 0) que tiene este bucle aplicado con menos frecuencia. Aquí es donde entra en juego la recolección de basura generacional. Hay 3 generaciones de forma predeterminada en Python (tres listas vinculadas de objetos): La primera
    • 902. 837 /* Break reference cycles by clearing the containers involved. This is * tricky business as the lists can be changing and we don't know which * objects may be freed. It is possible I screwed something up here. */ static void delete_garbage(PyGC_Head *collectable, PyGC_Head *old) lista (generación 0) contiene todos los objetos nuevos; si ocurre un ciclo GC y los objetos no se recolectan, se mueven a la segunda lista (generación 1), y si ocurre un ciclo GC en la segunda lista y aún no se recolectan, se mueven a la tercera lista (generación 2 ). La lista de la tercera generación (llamada "generación 2", dado que no tenemos ninguna indexación) es recogida de basura con mucha menos frecuencia que las dos primeras, y la idea es que si su objeto tiene una larga vida útil, no es tan probable que se realice la GCed, y puede que nunca estar en GC durante la vida útil de su aplicación, por lo que no tiene sentido perder el tiempo en cada ejecución del GC. Además, se observa que la mayoría de los objetos se recolectan basura relativamente rápido. De ahora en adelante, llamaremos a estos "buenos objetos" ya que mueren jóvenes. Esto se denomina "hipótesis generacional débil" y también se observó por primera vez en los años 60. Un lado rápido: a diferencia de las dos primeras generaciones, la lista de tercera generación de larga duración no es recogida de basura en un horario regular. Se verifica cuando la proporción de objetos pendientes de larga duración (aquellos que están en la lista de la tercera generación, pero que aún no han tenido un ciclo GC) con el total de objetos de larga duración en la lista es superior al 25%. Esto se debe a que la tercera lista no tiene límites (las cosas nunca se mueven de ella a otra lista, por lo que solo desaparecen cuando en realidad se recolectan basura), lo que significa que para las aplicaciones en las que está creando muchos objetos de larga duración, los ciclos de GC en la tercera lista puede llegar a ser bastante largo. Al utilizar una relación, logramos "rendimiento lineal amortizado en el número total de objetos"; también conocido, cuanto más larga sea la lista, más tiempo lleva GC, pero con menos frecuencia realizamos GC (aquí está la propuesta original de 2008 para esta heurística de Martin von Löwis para mayor lectura). El acto de realizar una recolección de basura en la tercera generación o lista "madura" se denomina "recolección de basura completa". Así que la recolección de basura generacional acelera las cosas tremendamente al no requerir que escaneamos objetos que no es probable que necesiten GC todo el tiempo, pero ¿cómo nos ayuda a romper las referencias cíclicas? Probablemente no muy bien, resulta. La función para realmente romper estos ciclos de referencia comienza así : La razón por la que la recolección de basura generacional ayuda con esto es que podemos mantener la longitud de la lista como un conteo separado; cada vez que agregamos un nuevo objeto a la generación incrementamos este conteo, y cada vez que movemos un objeto a otra generación o lo tratamos, decrementamos el conteo. Teóricamente, al final de un ciclo de GC, este recuento (para las primeras dos generaciones de todos modos) siempre debe ser 0. Si no lo es, cualquier cosa que quede en la lista es alguna forma de referencia circular y podemos dejarla. Sin embargo, hay un problema más aquí: ¿Qué pasa si los objetos sobrantes tienen el método mágico de Python del en ellos? del se llama cada vez que se destruye un objeto de Python. Sin embargo, si dos objetos en una referencia circular tienen métodos del , no podemos estar seguros de que destruir uno no romperá el método del los otros. Para un ejemplo artificial, imagina que escribimos lo siguiente:
    • 903. 838 /* list of uncollectable objects */ static PyObject *garbage = NULL; y establecemos una instancia de A y una instancia de B para que apunten entre sí y luego terminan en el mismo ciclo de recolección de basura? Digamos que elegimos uno al azar y desechamos nuestra instancia de A primero; Se del método del de A, se imprimirá y luego A se liberará. Luego llegamos a B, llamamos a su método del , y ¡ del ! Segfault! A ya no existe. Podríamos arreglar esto llamando primero a del métodos del que del , luego haciendo otra pasada para repartir todo, sin embargo, esto introduce otro problema: ¿Qué pasa si uno de los del método del guarda una referencia del otro objeto que está a punto de ser GCed y ¿Tiene una referencia a nosotros en otro lugar? Todavía tenemos un ciclo de referencia, pero ahora no es posible hacer GC en ninguno de los dos objetos, incluso si ya no están en uso. Tenga en cuenta que incluso si un objeto no es parte de una estructura de datos circular, podría revivir en su propio método del ; Python tiene una verificación de esto y detendrá la GCing si un refcount de objetos ha aumentado después de que se haya llamado a su método del . CPython se ocupa de esto al pegar esos objetos del de GC (cualquier cosa con algún tipo de referencia circular y un método del ) en una lista global de basura no recolectable y luego dejarla ahí por toda la eternidad: Examples Recuento de referencias La gran mayoría de la administración de memoria de Python se maneja con conteo de referencias. Cada vez que se hace referencia a un objeto (por ejemplo, asignado a una variable), su recuento de referencia aumenta automáticamente. Cuando se elimina la referencia (por ejemplo, la variable queda fuera del alcance), su recuento de referencia se reduce automáticamente. Cuando el recuento de referencia llega a cero, el objeto se destruye inmediatamente y la memoria se libera inmediatamente. Por lo tanto, para la mayoría de los casos, el recolector de basura ni siquiera es necesario. class A(object): def init (self, b=None): self.b = b def del (self): print("We're deleting an instance of A containing:", self.b) class B(object): def init (self, a=None): self.a = a def del (self): print("We're deleting an instance of B containing:", self.a)
    • 904. 839 >>> def bar(): return Track() >>> t = bar() Initialized >>> another_t = t # assign another reference >>> print("...") ... >>>t =None # not destructed yet - another_t still refers to it >>> another_t = None # final reference gone, object is destructed Destructed >>> import gc; gc.disable() # disable garbage collector >>> class Track: def init (self): print("Initialized") def del (self): print("Destructed") >>> A = Track() Initialized >>>B = Track() Initialized >>> A.other = B >>> B.other = A >>> del A;del B # objects are not destructed due to reference cycle Para demostrar aún más el concepto de referencias: Recolector de basura para ciclos de referencia La única vez que se necesita el recolector de basura es si tiene un ciclo de referencia . El ejemplo simple de un ciclo de referencia es uno en el que A se refiere a B y B se refiere a A, mientras que nada más se refiere a A o B. No se puede acceder a A ni a B desde cualquier lugar del programa, por lo que se pueden destruir de forma segura. sin embargo, sus recuentos de referencia son 1 y, por lo tanto, no se pueden liberar únicamente con el algoritmo de recuento de referencia. >>> import gc; gc.disable() # disable garbage collector >>> class Track: def init (self): print("Initialized") def del (self): print("Destructed") >>> def foo(): Track() # destructed immediately since no longer has any references print("---") t =Track() # variable is referenced, so it's not destructed yet print("---") # variable is destructed when function exits >>> foo() Initialized Destructed --- Initialized --- Destructed
    • 905. 840 >>> objs = [Track() for _ in range(10)] Initialized Initialized Initialized Initialized Initialized Initialized Initialized Initialized Initialized Initialized >>> for i in range(len(objs)-1): ... objs[i].other = objs[i + 1] ... >>> objs[-1].other = objs[0] # complete the cycle >>> del objs # no one can refer to objs now - still not destructed >>> gc.collect() Destructed Destructed Destructed Destructed Destructed Destructed Destructed Destructed Destructed Destructed 20 >>> import gc >>> gc.disable() # disable garbage collector >>> class Track: def init (self): print("Initialized") def del (self): print("Destructed") >>> def bar(): return Track() >>> t = bar() Initialized Un ciclo de referencia puede ser arbitrario largo. Si A apunta a B apunta a C apunta a ... apunta a Z que apunta a A, entonces no se recolectarán A a Z, hasta la fase de recolección de basura: Efectos del comando del Eliminarunnombredevariabledelámbitousandodel v,oeliminarunobjetodeunacolección usando del v[item] o del[i:j] , o eliminar un atributo usando del v.name , o cualquier otra forma deeliminarreferenciasa un objeto,nodesencadenaningunallamada dedestructorni ninguna memoria liberada en sí misma.Los objetos solose destruyen cuando su cuenta de referencia llega a cero. >>> gc.collect() # trigger collection Destructed Destructed 4
    • 906. 841 >>> import sys >>> sys.getrefcount(1) 797 >>> a = 1 >>> b = 1 >>> sys.getrefcount(1) 799 >>> a = 999999999 >>> sys.getrefcount(999999999) 3 >>> b = 999999999 >>> sys.getrefcount(999999999) 3 >>> import sys >>> a = object() >>> sys.getrefcount(a) 2 >>> b = a >>> sys.getrefcount(a) 3 >>> del b >>> sys.getrefcount(a) 2 >>>another_t =t >>> print("...") ... >>> del t >>> del another_t Destructed # assign another reference # not destructed yet - another_t still refers to it # final reference gone, object is destructed Reutilización de objetos primitivos. Una cosa interesante a tener en cuenta que puede ayudar a optimizar sus aplicaciones es que las primitivas también se vuelven a contar bajo el capó. Echemos un vistazo a los números; para todos los enteros entre -5 y 256, Python siempre reutiliza el mismo objeto: Tenga en cuenta que refcount aumenta, lo que significa que a y b referencia al mismo objeto subyacente cuando se refierena la primitiva 1 .Sinembargo,paranúmeros más grandes,Python en realidad no reutiliza el objeto subyacente: Debido a que el refcount de 999999999 no cambia cuando se asigna a a y b se puede inferir que se refieren a dos objetos subyacentes diferentes,aunque ambos se lesasigna el mismo primitivo. Viendo el refcount de un objeto Forzar la desasignación de objetos. Puede forzar la desasignación de objetos incluso si su refcount no es 0 en Python 2 y 3.
    • 907. 842 import ctypes deallocated = 12345 ctypes.pythonapi._Py_Dealloc(ctypes.py_object(deallocated)) import ctypes, sys deallocated = 12345 (ctypes.c_char * sys.getsizeof(deallocated)).from_address(id(deallocated))[:4] = '\x00' * 4 import gc gc.set_threshold(1000, 100, 10) # Values are just for demonstration purpose Ambas versiones utilizan el módulo ctypes para hacerlo. ADVERTENCIA: haciendo esto dejará su entorno Python inestable y propenso a estrellarse sin un rastreo! El uso de este método también podría introducir problemas de seguridad (bastante improbable). Desasigne solo los objetos que está seguro de que nunca volverá a hacer referencia. Siempre. Python 3.x 3.0 Python 2.x 2.3 Después de ejecutar, cualquier referencia al objeto ahora desasignado hará que Python produzca un comportamiento indefinido o se bloquee, sin un rastreo. Probablemente hubo una razón por la que el recolector de basura no eliminó ese objeto ... Si desasigna None , aparece un mensaje especial: Fatal Python error: deallocating None antesde que se bloquee. Gestionando la recogida de basura. Hay dos enfoques para influir cuando se realiza una limpieza de memoria. Influyen en la frecuencia con la que se realiza el proceso automático y el otro está activando manualmente una limpieza. El recolector de basura se puede manipular ajustando los umbrales de recolección que afectan la frecuencia a la que se ejecuta el recolector. Python utiliza un sistema de gestión de memoria basado en la generación. Los nuevos objetos se guardan en la generación más nueva - generación0 y con cada colección sobrevivida, los objetos se promueven a las generaciones anteriores. Después de llegar a la última generación - generación2 , ya no se promocionan. Los umbrales se pueden cambiar usando el siguiente fragmento de código: El primer argumento representa el umbral para recolectar generation0 . Cada vez que el número de asignaciones supera el número de desasignaciones por 1000, se llamará al recolector de basura. Las generaciones anteriores no se limpian en cada ejecución para optimizar el proceso. El segundo y tercer argumento son opcionales y controlan la frecuencia con la que se limpian las generaciones anteriores. Si la generación0 se procesó 100 veces sin limpiar la generación1 ,
    • 908. 843 import gc gc.collect() >>> f = open("test.txt") >>> del f entonces se procesará la generación1 . De manera similar, los objetos en la generación 2 se procesarán solo cuando los de la generación 1 se hayan limpiado 10 veces sin tocar la generación 2 . Una instancia en la que es beneficioso establecer manualmente los umbrales es cuando el programa asigna una gran cantidad de objetos pequeños sin desasignarlos, lo que hace que el recolector de basura se ejecute con demasiada frecuencia (cada una de las asignaciones de objetos de umbral de generación ). A pesar de que el colector es bastante rápido, cuando se ejecuta en una gran cantidad de objetos plantea un problema de rendimiento. De todos modos, no hay una estrategia única para todos los límites para elegir los umbrales y es confiable en cada caso de uso. La activación manual de una colección se puede hacer como en el siguiente fragmento de código: La recolección de basura se activa automáticamente en función del número de asignaciones y desasignaciones, no en la memoria consumida o disponible. En consecuencia, cuando se trabaja con objetos grandes, la memoria puede agotarse antes de que se active la limpieza automática. Esto es un buen caso de uso para llamar manualmente al recolector de basura. Aunque es posible, no es una práctica recomendada. Evitar las pérdidas de memoria es la mejor opción. De todos modos, en grandes proyectos, detectar la pérdida de memoria puede ser una tarea fácil y activar manualmente una recolección de basura se puede usar como una solución rápida hasta una depuración adicional. Para los programas de larga duración, la recolección de basura puede activarse en una base de tiempo o evento. Un ejemplo para el primero es un servidor web que activa una colección después de un número fijo de solicitudes. Para más adelante, un servidor web que activa una recolección de basura cuando se recibe un cierto tipo de solicitud. No espere a que la recolección de basura se limpie El hecho de que la recolección de basura se limpie no significa que deba esperar a que se limpie el ciclo de recolección de basura. En particular, no debe esperar a que la recolección de basura cierre los manejadores de archivos, las conexiones de base de datos y las conexiones de red abiertas. por ejemplo: En el siguiente código, asume que el archivo se cerrará en el siguiente ciclo de recolección de basura, si f fue la última referencia al archivo. Una forma más explícita de limpiar es llamar a f.close() . Puede hacerlo aún más elegante, es
    • 909. 844 >>> with open("test.txt") as f: ... pass ... # do something with f >>> #now the f object still exists, but it is closed decir, utilizando la instrucción with , también conocida como administrador de contexto : La instrucción with permite sangrar su código debajo del archivo abierto. Esto hace que sea explícito y más fácil ver cuánto tiempo se mantiene abierto un archivo. También siempre cierra un archivo, incluso si se produce una excepción en el bloque while .
    • 910. 845 from PIL import Image import sys import pyocr import pyocr.builders tools = pyocr.get_available_tools() # The tools are returned in the recommended order of usage tool = tools[0] Capítulo 173: Reconocimiento óptico de caracteres Introducción El reconocimiento óptico de caracteres es convertir imágenes de texto en texto real. En estos ejemplos, encuentre formas de usar OCR en python. Examples PyTesseract PyTesseract es un paquete de Python en desarrollo para OCR. Usar PyTesseract es bastante fácil: PyTesseract es de código abierto y se puede encontrar aquí . PyOCR Otro módulo de algún uso es PyOCR , cuyo código fuente está aquí . También es fácil de usar y tiene más funciones que PyTesseract. Para inicializar: try: import Image except ImportError: from PIL import Image import pytesseract #Basic OCR print(pytesseract.image_to_string(Image.open('test.png'))) #In French print(pytesseract.image_to_string(Image.open('test-european.jpg'), lang='fra’))
    • 911. 846 txt = tool.image_to_string( Image.open('test.png'), lang=lang, builder=pyocr.builders.TextBuilder() ) # txt is a Python string word_boxes = tool.image_to_string( Image.open('test.png'), lang="eng", builder=pyocr.builders.WordBoxBuilder() ) # list of box objects. For each box object: # box.content is the word in the box # box.position is its position on the page (in pixels) # # Beware that some OCR tools (Tesseract for instance) # may return empty boxes line_and_word_boxes = tool.image_to_string( Image.open('test.png'), lang="fra", builder=pyocr.builders.LineBoxBuilder() ) # list of line objects. For each line object: # line.word_boxes is a list of word boxes (the individual words in the line) # line.content is the whole text of the line # line.position is the position of the whole line on the page (in pixels) # # Beware that some OCR tools (Tesseract for instance) # may return empty boxes # Digits - Only Tesseract (not 'libtesseract' yet !) digits = tool.image_to_string( Image.open('test-digits.png'), lang=lang, builder=pyocr.tesseract.DigitBuilder() ) # digits is a python string Y algunos ejemplos de uso: langs = tool.get_available_languages() lang = langs[0] # Note that languages are NOT sorted in any way. Please refer # to the system locale settings for the default language # to use.
    • 912. 847 n = 0 for i in range (1, n+1): n += i def recursion(n): if n == 1: return 1 return n + recursion(n - 1) Capítulo 174: Recursion Observaciones La recursión necesita una condición de parada stopCondition para salir de la recursión. La variable original se debe pasar a la función recursiva para que se almacene. Examples Suma de números del 1 al n Siquisiera averiguarlasuma delosnúmerosdel 1al ndonde n es un númeronatural, puedo hacer 1 + 2 + 3 + 4 + ... + (several hours later) + n . Alternativamente, podría escribir un bucle for : O podría usar una técnica conocida como recursión: La recursión tiene ventajas sobre los dos métodos anteriores. La recursión toma menos tiempo que escribir 1 + 2 + 3 para una suma de 1 a 3. Para la recursion(4) , la recursión se puede usar para trabajar hacia atrás: Llamadas a funciones: (4 -> 4 + 3 -> 4 + 3 + 2 -> 4 + 3 + 2 + 1 -> 10) Mientras que el bucle for está trabajando estrictamente hacia adelante: (1 -> 1 + 2 -> 1 + 2 + 3 -> 1 + 2 + 3 + 4 -> 10). A veces, la solución recursiva es más simple que la solución iterativa. Esto es evidente cuando se implementa una reversión de una lista vinculada. El qué, cómo y cuándo de la recursión La recursión se produce cuando una llamada de función hace que esa misma función se vuelva a llamar antes de que finalice la llamada de función original. Por ejemplo, considere la expresión matemática conocida x! (Es decir, la operación factorial). La operación factorial se define para todos los enteros no negativos de la siguiente manera: • Si el número es 0, entonces la respuesta es 1. • De lo contrario, la respuesta es que el número multiplicado por el factorial es uno menos
    • 913. 848 def factorial(n): if n == 0: return 1 else: return n * factorial(n - 1) que ese número. En Python, una implementación ingenua de la operación factorial se puede definir como una función de la siguiente manera: Las funciones de recursión pueden ser difíciles de comprender a veces, así que veamos esto paso a paso. Considera la expresión factorial(3) . Esta y todas las llamadas a funciones crean unnuevoentorno.Un entorno esbásicamenteuna tabla queasignaidentificadores (porejemplo, n , factorial , print , etc.) a sus valores correspondientes. En cualquier momento, puede acceder al entorno actual utilizando locals() . En la primera llamada a la función, la única variable local que se define es n = 3 . Por lo tanto, la impresión de locals() mostraría {'n': 3} . Como n == 3 , el valor de retorno se convierte en n * factorial(n - 1). Enestesiguientepasoes dondelas cosaspueden ser un poco confusas. Mirando nuestra nueva expresión, ya sabemos qué es n . Sin embargo, todavía no sabemos qué factorial(n - 1) es. Primero, n - 1 evalúa a 2 . Entonces, 2 se pasa a factorial como el valor para n . Dado que se tratade unanueva llamadade función, se creaun segundo entorno para almacenar estanueva n . Sea A el primer entorno y B el segundo entorno. A todavía existe y es igual a {'n': 3} , sin embargo,B(que esigual a {'n': 2} ) esel entorno actual.Alobservarel cuerpo delafunción, el valor de retorno es, nuevamente, n * factorial(n - 1) . Sin evaluar esta expresión, vamos a sustituirlaenlaexpresiónderetornooriginal.Alhaceresto,estamosdescartandomentalmenteB , así que recuerde sustituir n consecuencia (es decir, las referencias a B 's n se reemplazan con n - 1 que usa A ' s n ). Ahora, la expresión de retorno original se convierte en n * ((n - 1) * factorial((n - 1) - 1)).Tomeunsegundoparaasegurarsedequeentiendepor quéestoesasí. Ahora,evaluemoslaporciónfactorial((n - 1)- 1))deeso.ComoA'sn == 3,estamospasando 1afactorial.Porlotanto,estamoscreandounnuevoentornoCqueesiguala{'n': 1}.Una vezmás,el valorderetorno es n * factorial(n - 1).Entonces,reemplacemos factorial((n - 1) - 1))delaexpresiónderetorno"original"demanerasimilaracomoajustamoslaexpresiónde retorno original anteriormente. La expresión "original" ahora es n * ((n - 1) * ((n - 2) * factorial((n - 2) - 1))) . Casitermino.Ahora,necesitamosevaluarfactorial((n-2)-1).Estavez,estamospasandoen 0.Porlotanto,estoseevalúaa1.Ahora,vamosarealizarnuestraúltimasustitución.La expresión de retorno "original" ahora es n * ((n - 1) * ((n - 2) * 1)) . Recordando que la expresiónderetornooriginalseevalúaenA,laexpresiónseconvierteen3 * ((3 - 1) * ((3 - 2) * 1)) . Esto, por supuesto, se evalúa a 6. Para confirmar que esta es la respuesta correcta, ¡recuerde que 3! == 3 * 2 * 1 == 6 . Antes de seguir leyendo, asegúrese de comprender completamente el concepto de entornos y cómo se aplican a la recursión. La declaración if n == 0: return 1 se llama un caso base. Esto se debe a que no exhibe recursión.Uncasobaseesabsolutamente necesario.Sinuno,teencontrarás conunarecursión
    • 914. 849 def factorial(n): if n == 0: return 1 elif n == 1: return 1 else: return n * factorial(n - 1) def fib(n): if n == 0 or n == 1: return n else: return fib(n - 2) + fib(n - 1) ( fib((n - 2) - 2) + ( fib(((n - 2) - 1) - 2) + fib(((n - 2) - 1) - 1) ) ) + ( ( fib(((n - 1) - 2) - 2) + fib(((n - 1) - 2) - 1) ) + ( fib(((n - 1) - 1) - 2) + ( fib((((n - 1) - 1) - 1) - 2) + infinita. Dicho esto, siempre que tenga al menos un caso base, puede tener tantos casos como desee. Por ejemplo, podríamos haber escrito un factorial equivalente de la siguiente manera: También puede tener varios casos de recursión, pero no vamos a entrar en eso, ya que es relativamente poco frecuente y, a menudo, es difícil de procesar mentalmente. También puede tener llamadas de función recursiva "paralelas". Por ejemplo, considere la secuencia de Fibonacci que se define de la siguiente manera: • Si el número es 0, entonces la respuesta es 0. • Si el número es 1, entonces la respuesta es 1. • De lo contrario, la respuesta es la suma de los dos números anteriores de Fibonacci. Podemos definir esto como sigue: No recorreré esta función tan a fondo como lo hice con factorial(3) , pero el valor de retorno final de fib(5) es equivalente a la siguiente expresión ( sintácticamente no válida):
    • 915. 850 def factorial(n): product = 1 while n > 1: product *= n n -= 1 return product def fib(n): a, b = 0, 1 while n > 0: a, b = b, a + b n -= 1 return a Esto se convierte en (1 + (0 + 1)) + ((0 + 1) + (1 + (0 + 1))) que, por supuesto, se evalúa en 5 . Ahora, vamos a cubrir algunos términos más de vocabulario: • Unallamadadecolaessimplementeunallamadadefunciónrecursivaqueeslaúltima operación que se realiza antes de devolver un valor. Para ser claros, return foo(n - 1) es una llamada de cola, pero return foo(n - 1) + 1 no (ya que la adición es la última operación). • La optimización de llamadas de cola (TCO) es una forma de reducir automáticamente la recursión en funciones recursivas. • La eliminación de la llamada de cola (TCE) es la reducción de una llamada de la cola a una expresión que se puede evaluar sin recursión. TCE es un tipo de TCO. La optimización de llamadas de cola es útil por varias razones: • El intérprete puede minimizar la cantidad de memoria ocupada por los entornos. Como ninguna computadora tiene memoria ilimitada, las llamadas excesivas a funciones recursivas conducirían a un desbordamiento de pila . • El intérprete puede reducir el número de interruptores de cuadros de pila . Python no tiene una forma de TCO implementada por varias razones . Por lo tanto, se requieren otras técnicas para evitar esta limitación. El método de elección depende del caso de uso. Con algo de intuición, las definiciones de factorial y fib se pueden convertir de manera relativamente fácil a código iterativo de la siguiente manera: Esta suele ser la forma más eficiente de eliminar manualmente la recursión, pero puede ser bastante difícil para funciones más complejas. Otra herramienta útil es el decorador lru_cache de Python, que se puede usar para reducir el número de cálculos redundantes. Ahora tiene una idea de cómo evitar la recursión en Python, pero ¿cuándo debería usar la recursión? La respuesta es "no a menudo". Todas las funciones recursivas pueden ser fib((((n - 1) - 1) - 1) - 1) ) ) )
    • 916. 851 def fib(n): if n <= 1: return (n,0) else: (a, b) = fib(n - 1) return (a + b, a) root - A - AA - AB - B - BA - BB - BBA root = get_root(tree) for node in get_children(root): print(get_name(node)) for child in get_children(node): print(get_name(child)) for grand_child in get_children(child): print(get_name(grand_child)) # prints: A, AA, AB, B, BA, BB, BBA implementadas iterativamente. Es simplemente una cuestión de averiguar cómo hacerlo. Sin embargo, hay casos raros en los que la recursión está bien. La recursión es común en Python cuando las entradas esperadas no causan un número significativo de llamadas a una función recursiva. Si la recursión es un tema que le interesa, le imploro que estudie lenguajes funcionales como Scheme o Haskell. En tales idiomas, la recursión es mucho más útil. Tenga en cuenta que el ejemplo anterior para la secuencia de Fibonacci, aunque es bueno para mostrar cómo aplicar la definición en python y el uso posterior de la caché lru, tiene un tiempo de ejecución ineficiente ya que realiza 2 llamadas recursivas para cada caso no básico. El número de llamadas a la función crece exponencialmente a n . Más bien, de forma no intuitiva, una implementación más eficiente usaría la recursión lineal: Pero ese tiene el problema de devolver un par de números. Esto enfatiza que algunas funciones realmente no ganan mucho con la recursión. Exploración de árboles con recursión Digamos que tenemos el siguiente árbol: Ahora,si deseamos enumerartodoslos nombres deloselementos, podríamos hacer esto conun simple bucle for. Suponemos que hay una función get_name() para devolver una cadena del nombre de un nodo, una función get_children() para devolver una lista de todos los get_children() de un nodo dado en el árbol, y una función get_root() para obtener el nodo raíz Esto funciona bien y rápido, pero ¿qué pasa si los subnodos tienen subnodos propios? Y esos
    • 917. 852 def list_tree_names(node): for child in get_children(node): print(get_name(child)) list_tree_names(node=child) list_tree_names(node=get_root(tree)) # prints: A, AA, AB, B, BA, BB, BBA def list_tree_names(node, lst=[]): for child in get_children(node): lst.append(get_name(child)) list_tree_names(node=child, lst=lst) return lst list_tree_names(node=get_root(tree)) # returns ['A', 'AA', 'AB', 'B', 'BA', 'BB', 'BBA'] RuntimeError: Maximum Recursion Depth Exceeded def cursing(depth): try: cursing(depth + 1) # actually, re-cursing except RuntimeError as RE: print('I recursed {} times!'.format(depth)) cursing(0) # Out: I recursed 1083 times! sys.setrecursionlimit(limit) sys.getrecursionlimit() sys.setrecursionlimit(2000) subnodos podrían tener más subnodos ... ¿Qué pasa si no sabe de antemano cuántos habrá? Un método para resolver esto es el uso de la recursión. Quizás desee no imprimir, pero devuelva una lista plana de todos los nombres de nodo. Esto se puede hacer pasando una lista móvil como parámetro. Incrementando la profundidad máxima de recursión Hay un límite a la profundidad de la posible recursión, que depende de la implementación de Python. Cuando se alcanza el límite, se genera una excepción RuntimeError: Aquí hay una muestra de un programa que causaría este error: Es posible cambiar el límite de profundidad de recursión usando Puede verificar cuáles son los parámetros actuales del límite ejecutando: Ejecutando el mismo método anterior con nuestro nuevo límite obtenemos
    • 918. 853 def countdown(n): if n == 0: print "Blastoff!" else: print n countdown(n-1) def find_max(seq, max_so_far): if not seq: return max_so_far if max_so_far < seq[0]: return find_max(seq[1:], seq[0]) else: return find_max(seq[1:], max_so_far) #!/usr/bin/env python2.4 #Thisprogramshowsoff a python decoratorwhichimplementstail call optimization.It # does this by throwing an exception if it is it's own grandparent, and catching such # exceptions to recall the stack. import sys class TailRecurseException: def init (self, args, kwargs): self.args = args self.kwargs = kwargs Desde Python 3.5, la excepción es un RecursionError, que se deriva de RuntimeError. Recursión de cola - Mala práctica Cuando lo único que se devuelve de una función es una llamada recursiva, se la denomina recursión de cola. Aquí hay un ejemplo de cuenta regresiva escrita usando la recursión de la cola: Cualquier cálculo que se pueda hacer usando la iteración también se puede hacer usando la recursión. Aquí hay una versión de find_max escrita usando la recursión de la cola: La recursión de cola se considera una mala práctica en Python, ya que el compilador de Python no maneja la optimización para las llamadas recursivas de cola. La solución recursiva en casos como este utiliza más recursos del sistema que la solución iterativa equivalente. Optimización de la recursión de cola a través de la introspección de la pila Por defecto, la pila de recursión de Python no puede exceder los 1000 cuadros.Esto se puede cambiar configurando sys.setrecursionlimit(15000) que es más rápido, sin embargo, este método consume másmemoria.Ensulugar, tambiénpodemos resolverel problemaderecursióndecola utilizando la introspección depila. cursing(0) # Out: I recursed 1997 times!
    • 919. 854 @tail_call_optimized def factorial(n, acc=1): "calculate a factorial" if n == 0: return acc return factorial(n-1, n*acc) print factorial(10000) # prints a big, big number, # but doesn't hit the recursion limit. @tail_call_optimized def fib(i, current = 0, next = 1): if i == 0: return current else: return fib(i - 1, next, current + next) print fib(10000) # also prints a big number, # but doesn't hit the recursion limit. Para optimizar las funciones recursivas, podemos usar el decorador @tail_call_optimized para llamara nuestrafunción.Aquíhayalgunosde losejemplos comunesderecursiónqueutilizanel decorador descrito anteriormente: Ejemplo factorial: Ejemplo de Fibonacci: def tail_call_optimized(g): """ This function decorates a function with tail call optimization.It doesthisby throwing anexception if it is it's own grandparent, and catching such exceptions to fake the tail calloptimization. This function fails if the decorated function recurses in a non-tail context. """ def func(*args, **kwargs): f = sys._getframe() if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code: raise TailRecurseException(args, kwargs) else: while 1: try: return g(*args, **kwargs) except TailRecurseException, e: args = e.args kwargs = e.kwargs func. doc = g. doc return func
    • 920. 855 import socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversocket.bind(('localhost', 8089)) serversocket.listen(5) # become a server socket, maximum 5 connections while True: connection, address = serversocket.accept() buf = connection.recv(64) if len(buf) > 0: print(buf) break import socket clientsocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) clientsocket.connect(('localhost', 8089)) clientsocket.send('hello') Capítulo 175: Redes Python Observaciones Ejemplo de socket de cliente Python (muy) básico Examples El ejemplo más simple de cliente / servidor de socket de Python. Lado del servidor: Lado del cliente: Primero ejecute el SocketServer.py, y asegúrese de que el servidor esté listo para escuchar / recibir algo. Luego, el cliente envía la información al servidor; Después de que el servidor recibió algo, termina Creando un servidor HTTP simple Para compartir archivos o alojar sitios web simples (http y javascript) en su red local, puede usar el módulo SimpleHTTPServer integrado de Python. Python debería estar en tu variable Path. Vayaa la carpeta donde están sus archivos y escriba: Para python 2 : Para python 3 : $ python -m SimpleHTTPServer <portnumber>
    • 921. 856 from sockerserver import BaseRequestHandler, TCPServer class EchoHandler(BaseRequestHandler): def handle(self): print('connection from:',self.client_address) while True: msg = self.request.recv(8192) if not msg: break self.request.send(msg) if name == ' main ': server = TCPServer(('', 5000), EchoHandler) server.serve_forever() from socket import socket,AF_INET, SOCK_STREAM sock = socket(AF_INET, SOCK_STREAM) sock.connect(('localhost', 5000)) sock.send(b'Monty Python') sock.recv(8192) # returns b'Monty Python' from socketserver import ThreadingTCPServer ... if name == ' main ': server = ThreadingTCPServer(('', 5000), EchoHandler) server.serve_forever() Si no se da el número de puerto, 8000 es el puerto predeterminado. Así que la salida será: Sirviendo HTTP en el puerto 0.0.0.0 8000 ... Puedeacceder a sus archivos a través de cualquierdispositivo conectado ala redlocal escribiendo http://hostipaddress:8000/ . hostipaddress es su dirección IP local que probablemente comienza con 192.168.xx Para finalizar el módulo simplemente presione ctrl+c. Creando un servidor TCP Puede crear un servidor TCP utilizando la biblioteca socketserver . Aquí hay un servidor de eco simple. Lado del servidor Lado del cliente socketserver hace que sea relativamente fácil crear servidores TCP simples. Sin embargo, debe tener en cuenta que, de formapredeterminada, los servidores son de un solohilo y solo pueden atender a un cliente a la vez. Si desea manejar múltiples clientes, cree una instancia de ThreadingTCPServer lugar. $ python3 -m http.server <portnumber>
    • 922. 857 >>> from socket import socket, AF_INET, SOCK_DGRAM >>> sock = socket(AF_INET, SOCK_DGRAM) >>> sick.sendto(b'', ('localhost', 5000)) 0 >>> sock.recvfrom(8192) (b'Wed Aug 15 20:35:08 2012', ('127.0.0.1', 5000)) from http.server import HTTPServer, CGIHTTPRequestHandler import webbrowser import threading def start_server(path, port=8000): '''Start a simple webserver serving path on port''' os.chdir(path) httpd=HTTPServer(('',port),CGIHTTPRequestHandler) httpd.serve_forever() # Start the server in a new thread port = 8000 daemon = threading.Thread(name='daemon_server', target=start_server, args=('.', port) daemon.setDaemon(True) # Set as a daemon so it will be killed once the main thread is dead. daemon.start() # Open the web browser webbrowser.open('http://localhost:{}'.format(port)) Creando un Servidor UDP Un servidor UDP se crea fácilmente utilizando la biblioteca de socketserver . un servidor de tiempo simple: Pruebas: Inicie Simple HttpServer en un hilo y abra el navegador Útil si tu programa está generando páginas web a lo largo del camino. import time from socketserver import BaseRequestHandler, UDPServer class CtimeHandler(BaseRequestHandler): def handle(self): print('connectionfrom:',self.client_address) # Get message and clientsocket msg, sock = self.request resp = time.ctime() sock.sendto(resp.encode('ascii'), self.client_address) if name == ' main ': server = UDPServer(('', 5000), CtimeHandler) server.serve_forever()
    • 923. 858
    • 924. 859 sum([1,2,3]) # = 6 ''.join(['Hello', ',', ' World']) # = 'Hello,World' # First falsy item: next((i for i in [100, [], 20, 0] if not i)) # = [] # No import needed # No import required... Capítulo 176: Reducir Sintaxis • reducir (función, iterable [, inicializador]) Parámetros Parámetro Detalles función Función que se utiliza para reducir lo iterable (debe tomar dos argumentos). ( solo posicional ) iterable iterable que va a ser reducido. ( solo posicional ) inicializador Valor de inicio de la reducción. ( opcional , solo posicional ) Observaciones reduce podría no ser siempre la función más eficiente. Para algunos tipos hay funciones o métodos equivalentes: • sum() para la suma de una secuencia que contiene elementos sumables (no cadenas): • str.join para la concatenación decuerdas: • next junto con un generador podría ser una variante de cortocircuito en comparación con reduce : Examples Visión general
    • 925. 860 def add(s1, s2): return s1 + s2 asequence = [1, 2, 3] reduce(add, asequence) # equivalent to: add(add(1,2),3) # Out: 6 import operator reduce(operator.add, asequence) # Out: 6 reduce(add, asequence, 10) # Out: 16 def multiply(s1, s2): print('{arg1} * {arg2} = {res}'.format(arg1=s1, arg2=s2, res=s1*s2)) return s1 * s2 asequence = [1, 2, 3] cumprod = reduce(multiply, asequence, 5) # Out: 5 * 1 = 5 # 5 * 2 = 10 # 10 * 3 = 30 print(cumprod) # Out: 30 cumprod = reduce(multiply, asequence) # Out: 1 * 2 = 2 reduce reduceuniterableaplicandounafunciónrepetidamenteenelsiguienteelementodeun resultado iterable y acumulativo hasta el momento. Eneste ejemplo, definimos nuestra propia funciónde add .Sin embargo,Python viene con una función equivalente estándar en el módulo del operator : reduce también se puede pasar un valor inicial: Utilizando reducir Dado un initializer la función se inicia aplicándola al inicializador y al primer elemento iterable: Sin el parámetro initializer , la reduce inicia al aplicar la función a los dos primeros elementos de la lista: from functools import reduce # ... but it can be loaded from the functools module from functools import reduce # mandatory
    • 926. 861 import operator reduce(operator.mul, [10, 5, -3]) # Out: -150 import operator # non short-circuit "all" reduce(operator.and_, [False, True, True, True]) # = False # non short-circuit "any" reduce(operator.or_, [True, False, False, False]) # = True # First falsy element or last element if all are truthy: reduce(lambda i, j: i and j, [100, [], 20, 10]) # = [] reduce(lambda i, j: i and j, [100, 50, 20, 10]) #= 10 # First truthy element or last element if all falsy: reduce(lambda i, j: i or j, [100, [], 20, 0]) # = 100 reduce(lambda i, j: i or j, ['', {}, [], None]) #=None # = 100 # = [] def do_or(i, j): return i or j def do_and(i, j): return i andj reduce(do_or, [100, [], 20, 0]) reduce(do_and, [100, [], 20, 0]) Producto acumulativo Variante sin cortocircuito de alguno / todos. reducenoterminarálaiteraciónantesdeque el iterablesehayaiteradocompletamente, porlo que se puede usar para crear una función sin cortocircuito en any() o all() : Primer elemento verdadero / falso de una secuencia (o último elemento si no hay ninguno) En lugar de crear una función lambda , generalmente se recomienda crear una función nombrada: print(cumprod) # Out: 6 # 2 * 3 = 6
    • 927. 862 object -> string -> object def repr (self): return "Card(%s, %d)" % (self.suit, self.pips) Capítulo 177: Representaciones de cadena de instancias de clase: métodos repr str y Observaciones Una nota sobre la implementación de ambos métodos. Cuandoseimplementanambosmétodos,esalgocomúntenerunmétodo str que devuelve unarepresentaciónamigableparaelserhumano(porejemplo,"AsofSpaces")y repr devuelve una representación amigable deeval . De hecho, la documentación de Python para repr() nota exactamente esto: Para muchos tipos, esta función intenta devolver una cadena que produciría un objeto con el mismo valor cuando se pasa a eval (), de lo contrario, la representación es una cadena entre paréntesis angulares que contiene el nombre del tipo de objeto. con información adicional que a menudo incluye el nombre y la dirección del objeto. Lo que eso significa esque str podría implementarse para devolver algo como "As of Spaces" como se mostró anteriormente, repr podría implementarse para devolver una Card('Spades', 1) Esta cadena podría pasarse directamente a eval en una especie de "ida y vuelta": Un ejemplo de una implementación de tal método podría ser: Notas [1] Esta salida es específica de la implementación. La cadena mostrada es de cpython. [2] Es posible que ya hayas visto el resultado de esta división str() / repr() y no lo hayas conocido.Cuandolascadenasquecontienencaracteresespeciales,comolasbarrasinvertidas, se convierten en cadenas a través de str() las barras diagonales aparecen como están (aparecenunavez).Cuandoseconviertenencadenasmedianterepr()(porejemplo,como
    • 928. 863 class Card: def init (self, suit, pips): self.suit = suit self.pips = pips ace_of_spades = Card('Spades', 1) four_of_clubs = Card('Clubs', 4) six_of_hearts = Card('Hearts', 6) my_hand = [ace_of_spades, four_of_clubs, six_of_hearts] print(my_hand) [< main .Card instance at 0x0000000002533788>, < main .Card instance at 0x00000000025B95C8>, < main .Card instance at 0x00000000025FF508>] print(ace_of_spades) < main .Card instance at 0x0000000002533788> elementos de una lista que se muestra), las barras invertidas se escapan y, por lo tanto, aparecen dos veces. Examples Motivación Así que acabas de crear tu primera clase en Python, una clase pequeña y ordenada que encapsula una carta de juego: En otra parte de tu código, creas algunas instancias de esta clase: Incluso has creado una lista de cartas para representar una "mano": Ahora, durante la depuración, quieres ver cómo se ve tu mano, así que haces lo que es natural y escribes: Pero lo que obtienes es un montón de galimatías: Confundido, intenta simplemente imprimir una sola tarjeta: Y de nuevo, obtienes esta salida extraña: No tener miedo. Estamos a punto de arreglar esto. Primero, sin embargo, es importante entender lo que está pasando aquí. Cuando escribió print(ace_of_spades) le dijo a Python que quería que imprimiera información sobre la instancia de
    • 929. 864 string_of_card = str(ace_of_spades) print(string_of_card) class Card: def init (self, suit, pips): self.suit = suit self.pips = pips def str (self): special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'} card_name = special_names.get(self.pips, str(self.pips)) return "%s of %s" % (card_name, self.suit) la Card su código está llamando ace_of_spades . Y para ser justos, lo hizo. Esasalidasecomponededosbits importantes:el typedeobjetoylaiddel objeto.La segunda parte sola (el número hexadecimal) es suficiente para identificar de forma única el objeto en el momento de la llamada de print . [1] Lo que realmente sucedió fue que le pediste a Python que "expresara con palabras" la esencia de ese objeto y luego te lo mostrara. Una versión más explícita de la misma maquinaria podría ser: En la primera línea, intenta convertir la instancia de su Card en una cadena, y en la segunda, la muestra. El problema El problema con el que se encuentra surge debido al hecho de que, mientras le contaba a Python todo lo que necesitaba saber sobre la clase de la Card para que usted creara las tarjetas, no le dijo cómo quería que las instancias de la Card se convirtieran en cadenas. Y como no lo sabía, cuando usted (implícitamente) escribió str(ace_of_spades) , le dio lo que vio, una representación genérica de la instancia de la Card . La Solución (Parte 1) Pero podemos decirle a Python cómo queremos que las instancias de nuestras clases personalizadas se conviertan en cadenas. Y la forma en que lo hacemos es con el método str "dunder" (para subrayado doble) o "magic". Siempre quele digas aPythonque cree una cadena desde unainstancia declase, buscará un método str en la clase y lo llamará. Considere la siguiente versión actualizada de nuestra clase de Card : Aquí, ahora hemos definido el método str en nuestra clase de Card que, después deuna
    • 930. 865 ace_of_spades = Card('Spades', 1) print(ace_of_spades) Ace of Spades my_hand = [ace_of_spades, four_of_clubs, six_of_hearts] print(my_hand) [< main .Card instance at 0x00000000026F95C8>, < main .Card instance at 0x000000000273F4C8>, < main .Card instance at 0x0000000002732E08>] simple búsqueda en el diccionario de tarjetas de caras, devuelve una cadena con el formato que decidamos. (Tenga en cuenta que las "devoluciones" están en negrita aquí, para resaltar la importancia de devolver una cadena y no simplemente de imprimirla. La impresión puede parecer que funciona, pero luego se imprimirá la tarjeta cuando hizo algo como str(ace_of_spades) , sin siquiera tener una llamada a la función de impresión en su programa principal. Para que quede claro, asegúrese de que str devuelva una cadena. El método str esun método, porlo que elprimerargumentoserá selfy no debería aceptar, ni pasar argumentos adicionales. Volviendo a nuestro problema de mostrar la tarjeta de una manera más fácil para el usuario, si volvemos a ejecutar: Veremos que nuestra salida es mucho mejor: Muy bien, hemos terminado, ¿verdad? Bueno, solo para cubrir nuestras bases, verifiquemos que hemos resuelto el primer problema que encontramos, imprimiendo la lista de instancias de la Card , la hand . Así que volvemos a comprobar el siguiente código: Y, para nuestra sorpresa, volvemos a obtener esos divertidos códigos hex: ¿Que esta pasando? Le dijimos a Python cómo queríamos que se mostraran nuestras instancias de la Card , ¿por qué parece que aparentemente se olvidó? La Solución (Parte 2) Bueno, la maquinaria detrás de escena es un poco diferente cuando Python quiere obtener la representación de cadena de los elementos en una lista. Resulta que a Python no le importa str para este propósito. En su lugar, busca un método diferente, repr , y si eso no es encontrado, se recurre a la "cosa
    • 931. 866 class Card: special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'} def init (self, suit, pips): self.suit = suit self.pips = pips def str (self): card_name = Card.special_names.get(self.pips, str(self.pips)) return "%s of %s (S)" % (card_name, self.suit) def repr (self): card_name = Card.special_names.get(self.pips, str(self.pips)) return "%s of %s (R)" % (card_name, self.suit) print(ace_of_spades) # Ace of Spades (S) print(my_hand) # [Ace of Spades (R), 4 of Clubs (R), 6 of Hearts (R)] ace_of_spades = Card('Spades', 1) four_of_clubs = Card('Clubs', 4) six_of_hearts = Card('Hearts', 6) my_hand = [ace_of_spades, four_of_clubs, six_of_hearts] str_card = str(four_of_clubs) hexadecimal". [2] Entonces, ¿estás diciendo que tengo que hacer dos métodos para hacer lo mismo? ¿Uno para cuando quiero print mi tarjeta por sí mismo y otro cuando está en algún tipo de contenedor? No, pero primero veamos cómo sería nuestra clase si implementáramos los métodos str y repr : Aquí, la implementación de los dos métodos str y repr son exactamente iguales, excepto que, paradiferenciarlosdos métodos, seagrega(S)alascadenas devueltas por str y(R)se agrega a las cadenas devueltas por repr . Tenga en cuenta que al igual que nuestro método str , repr no acepta argumentosy devuelve una cadena. Podemos ver ahora qué método es responsable de cada caso: Comosecubrió, sellamóalmétodo str cuandopasamosnuestrainstanciadeCardaprinty al método repr cuando pasamos una lista de nuestras instancias a print . Eneste punto, vale la pena señalar que al igual que podemos crear explícitamente una cadena desde una instancia de clase personalizada usando str() comolo hicimos anteriormente, también podemoscrearexplícitamenteuna representacióndecadenadenuestraclaseconunafunción incorporada llamada repr() . Por ejemplo:
    • 932. 867 print(four_of_clubs. repr ()) # 4 of Clubs (R) print(four_of_clubs. str ()) # 4 of Clubs (S) class Card: special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'} def init (self, suit, pips): self.suit = suit self.pips = pips def repr (self): card_name = Card.special_names.get(self.pips, str(self.pips)) return "%s of %s" % (card_name, self.suit) # 6 of Hearts (implicit conversion) # 6 of Hearts (explicit conversion) print(six_of_hearts) print(str(six_of_hearts)) #[6 of Hearts] (implicit conversion) # 6 of Hearts (explicit conversion) print([six_of_hearts]) print(repr(six_of_hearts)) Y además, si está definido, podríamos llamar a los métodos directamente (aunque parece un poco incierto e innecesario): Sobre esas funciones duplicadas ... Losdesarrolladores de Python se dieron cuenta de que, en el caso de quequisieras que se devolvieran cadenas idénticas desde str() y repr() es posible que tengas que duplicar funcionalmente los métodos, algo que a nadie le gusta. Entonces, en cambio, existe un mecanismo para eliminar la necesidad de eso. Una que te colgué hasta este punto. Resulta que si una clase implementa el método repr pero no el método str , y usted pasaunainstanciadeesaclaseastr()(yasea de maneraimplícita oexplícita), Python repr su implementación repr y lo usará. Entonces, para ser claros, considere la siguiente versión de la clase de Card : Tengaencuentaqueestaversiónsoloimplementaelmétodo repr .Noobstante,lasllamadas a str()dan como resultado una versión fácil de usar: al igual que las llamadas a repr() : Resumen # 4 of Clubs (R) repr_card = repr(four_of_clubs) print(repr_card) print(str_card) # 4 of Clubs (S)
    • 933. 868 class Card: special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'} def init (self, suit, pips): self.suit = suit self.pips = pips # Called when instance is converted to a string via str() # Examples: # print(card1) # print(str(card1) def str (self): card_name = Card.special_names.get(self.pips, str(self.pips)) return "%s of %s" % (card_name, self.suit) # Called when instance is converted to a string via repr() # Examples: # print([card1, card2, card3]) # print(repr(card1)) def repr (self): return "Card(%s, %d)" % (self.suit, self.pips) Para que pueda habilitar las instancias de su clase para que se "muestren" de manera fácil de usar, querrá considerar implementar al menos el método repr su clase. Si la memoria sirve, durante una charla, Raymond Hettinger dijo que asegurarse de que las clasesimplementen repr es una de las primeras cosas que busca mientras hace revisiones de código Python, y hasta ahora debería estar claro por qué. La cantidad de información que podría haber agregado a las declaraciones de depuración, los informes de fallos o los archivos de registro con un método simple es abrumadora en comparación con la información más escasa y, a menudo, poco útil (tipo, id) que se proporciona de forma predeterminada. Sideseadiferentes representaciones paracuando,porejemplo,dentrodeuncontenedor,querrá implementar los métodos repr y str . (Más sobre cómo puede usar estos dos métodos de manera diferente a continuación). Ambos métodos implementados, eval-round-trip style repr ()
    • 934. 869 a = 7 if a > 5: print "foo" else: print "bar" print "done" if True: print "true" if True: a = 6 b = 5 def isEven(a): if a%2 ==0: return True #this next line should be even with the if return False print isEven(7) class ExampleClass: #Every function belonging to a class must be indented equally def init (self): Capítulo 178: Sangría Examples Errores de sangría El espacio debe ser uniforme y uniforme en todo. La sangría incorrecta puede causar un IndentationError o hacer que el programa haga algo inesperado. El siguiente ejemplo genera un IndentationError : O si la línea que sigue a dos puntos no tiene sangría, también se levantará un IndentationError : Si agrega sangría donde no pertenece, se generará un IndentationError : Si olvida desmarcar la funcionalidad podría perderse. En este ejemplo, None se devuelve en lugar del False esperado: Ejemplo simple Para Python, Guido van Rossum basó la agrupación de declaraciones en sangría. Las razones de esto se explican en la primera sección de las "Preguntas frecuentes sobre Python de diseño e historia" . Los dos puntos, : , se utilizan para declarar un bloque de código con sangría , como el siguiente ejemplo:
    • 935. 870 if foo: if bar: x = 42 ¿Espacios o pestañas? La sangría recomendada es de 4 espacios, pero se pueden usar tabulaciones o espacios siempre que sean consistentes. No mezcle tabulaciones y espacios en Python ya que esto causará un error en Python 3 y puede causar errores en Python 2 . Cómo se analiza la sangría Los espacios en blanco son manejados por el analizador léxico antes de ser analizados. El analizadorléxico usa una pila para almacenar niveles de sangría.Al principio, la pila contiene solo el valor 0, que es la posición más a la izquierda. Cada vez que comienza un bloque anidado, el nuevo nivel de sangría se empuja en la pila, y se inserta un token "INDENT" en el flujo de token que se pasa al analizador. Nunca puede haber más de un token "INDENT" en una fila ( IndentationError ). Cuando se encuentra una línea con un nivel de sangría más pequeño, los valores se extraen de la pila hasta que un valor está en la parte superior, que es igual al nuevo nivel de sangría (si no se encuentra ninguno, se produce un error de sintaxis). Para cada valor que aparece, se genera un token "DEDENT". Obviamente, puede haber múltiples tokens "DEDENT" en una fila. El analizador léxico omite líneas vacías (aquellas que solo contienen espacios en blanco y posiblemente comentarios), y nunca generará tokens "INDENT" o "DEDENT" para ellas. Al final del código fuente, se generan tokens "DEDENT" para cada nivel de sangrado que queda en la pila, hasta que solo queda el 0. Por ejemplo: name = "example" def someFunction(self, a): #Notice everything belonging to a function must be indented if a > 5: return True else: return False #If a function is not indented to the same level it will not be considers as part of the parent class def separateFunction(b): for i in b: #Loops are also indented and nested conditions start a new indentation if i == 1: return True return False separateFunction([2,3,5,6,1])
    • 936. 871 se analiza como: <if> <foo> <:> [0] <INDENT> <if> <bar> <:> [0, 4] <INDENT> <x> <=> <42> [0, 4, 8] <DEDENT> <DEDENT> <else> <:> [0] <INDENT> <print> <foo> [0, 2] <DEDENT> El analizador que maneja los tokens "INDENT" y "DEDENT" como delimitadores de bloque. else: print foo
    • 937. 872 "This is a string" b"This is a buffer of bytes" import hashlib h = hashlib.new('sha256') h.update(b'Nobody expects the Spanish Inquisition.') h.digest() # ==> b'.\xdf\xda\xdaVR[\x12\x90\xff\x16\xfb\x17D\xcf\xb4\x82\xdd)\x14\xff\xbc\xb6Iy\x0c\x0eX\x9eF- =' h.hexdigest() Capítulo 179: Seguridad y criptografía Introducción Python, siendo uno de los lenguajes más populares en seguridad de computadoras y redes, tiene un gran potencial en seguridad y criptografía. Este tema trata sobre las funciones criptográficas y las implementaciones en Python desde sus usos en seguridad informática y de red hasta algoritmos de hash y cifrado / descifrado. Sintaxis • hashlib.new (nombre) • hashlib.pbkdf2_hmac (nombre, contraseña, salt, rounds, dklen = Ninguno) Observaciones Muchos de los métodos en hashlib requerirán que usted pase valores interpretables como buffers de bytes, en lugar de cadenas. Este es el caso de hashlib.new().update() así como hashlib.pbkdf2_hmac .Sitieneunacadena, puedeconvertirla enunbúfer debytesal añadirel carácter b al comienzo de lacadena: Examples Cálculo de un resumen del mensaje El módulo hashlib permite crear generadores de resumen de mensajes a través del new método. Estos generadores convertirán una cadena arbitraria en un compendio de longitud fija: Tengaencuentaquepuedellamaralaupdateunnúmeroarbitrariodevecesantesdellamaral digestqueesútilparaagruparunfragmentodearchivograndeporfragmento.Tambiénpuede obtener el resumen en formato hexadecimal utilizandohexdigest :
    • 938. 873 import hashlib hashlib.algorithms_available # ==> {'sha256', 'DSA-SHA', 'SHA512', 'SHA224', 'dsaWithSHA', 'SHA', 'RIPEMD160', 'ecdsa-withSHA1', 'sha1', 'SHA384', 'md5', 'SHA1', 'MD5', 'MD4', 'SHA256', 'sha384', 'md4', 'ripemd160', 'sha224', 'sha512', 'DSA', 'dsaEncryption', 'sha', 'whirlpool'} hashlib.algorithms_guaranteed # ==> {'sha256', 'sha384', 'sha1', 'sha224', 'md5', 'sha512'} import hashlib import os salt = os.urandom(16) hash = hashlib.pbkdf2_hmac('sha256', b'password', salt, 100000) import binascii hexhash = binascii.hexlify(hash) Algoritmos de hash disponibles hashlib.new requiere el nombre de un algoritmo cuando lo llama para producir un generador. Para averiguar qué algoritmos están disponibles en el intérprete de Python actual, use hashlib.algorithms_available : La lista devuelta variará según la plataforma y el intérprete; Asegúrate de comprobar que tu algoritmo está disponible. Tambiénhayalgunosalgoritmosqueestángarantizadosparaestardisponiblesentodaslas plataformas e intérpretes, que están disponibles usando hashlib.algorithms_guaranteed : Contraseña segura Hashing El algoritmo hashlib expuesto por el módulo hashlib se puede usar para realizar el hashing de contraseña seguro. Si bien este algoritmo no puede evitar los ataques de fuerza bruta para recuperar la contraseña original del hash almacenado, hace que dichos ataques sean muy costosos. PBKDF2 puede funcionar con cualquier algoritmo de resumen, el ejemplo anterior utiliza SHA256, que generalmente se recomienda. La sal aleatoria debe almacenarse junto con la contraseña hash, la necesitará nuevamente para comparar una contraseña ingresada con el hash almacenado. Es esencial que cada contraseña tenga una sal diferente. En cuanto al número de rondas, se recomienda establecerlo lo más alto posible para su aplicación . Si desea que el resultado sea hexadecimal, puede usar el módulo binascii : Nota : si bien PBKDF2 no es malo, bcrypt y especialmente scrypt se consideran más fuertes contra los ataques de fuerza bruta. Tampoco es parte de la biblioteca estándar de Python en este # ==> '2edfdada56525b1290ff16fb1744cfb482dd2914ffbcb649790c0e589e462d3d'
    • 939. 874 import hashlib hasher = hashlib.new('sha256') with open('myfile', 'r') as f: contents = f.read() hasher.update(contents) print hasher.hexdigest() import hashlib SIZE = 65536 hasher = hashlib.new('sha256') with open('myfile', 'r') as f: buffer = f.read(SIZE) while len(buffer) > 0: hasher.update(buffer) buffer = f.read(SIZE) print(hasher.hexdigest()) import hashlib import math import os from Crypto.Cipher import AES IV_SIZE = 16 # 128 bit, fixed for the AES algorithm KEY_SIZE = 32 # 256 bit meaning AES-256, can also be 128 or 192 bits SALT_SIZE = 16 # This size is arbitrary cleartext = b'Lorem ipsum' password = b'highly secure encryption password' salt = os.urandom(SALT_SIZE) derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000, momento. Hash de archivo Un hash es una función que convierte una secuencia de longitud variable de bytes en una secuencia de longitud fija. Los archivos de hash pueden ser ventajosos por muchas razones. Los hash se pueden usar para verificar si dos archivos son idénticos o verificar que el contenido de un archivo no se haya dañado o cambiado. Puedes usar hashlib para generar un hash para un archivo: Para archivos más grandes, se puede usar un búfer de longitud fija: Cifrado simétrico utilizando pycrypto La funcionalidad criptográfica incorporada de Python se limita actualmente al hashing. El cifrado requiere un módulo de terceros como pycrypto . Por ejemplo, proporciona el algoritmo AES que se considera el estado de la técnica para el cifrado simétrico. El siguiente código cifrará un mensaje dado usando una frase de contraseña:
    • 940. 875 salt = encrypted[0:SALT_SIZE] derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000, dklen=IV_SIZE + KEY_SIZE) iv = derived[0:IV_SIZE] key = derived[IV_SIZE:] cleartext = AES.new(key, AES.MODE_CFB, iv).decrypt(encrypted[SALT_SIZE:]) import errno from Crypto.Hash import SHA256 from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 message = b'This message is from me, I promise.' try: with open('privkey.pem', 'r') as f: key = RSA.importKey(f.read()) except IOError as e: if e.errno != errno.ENOENT: El algoritmo AES toma tres parámetros: clave de cifrado, vector de inicialización (IV) y el mensaje real a cifrar. Si tiene una clave AES generada aleatoriamente, puede usarla directamente y simplemente generar un vector de inicialización aleatorio. Sin embargo, una frase de contraseña no tiene el tamaño correcto, ni sería recomendable utilizarla directamente, ya que no esrealmente aleatoria y, por lo tanto, tiene una entropía relativamente pequeña. En su lugar, usamos la implementación incorporada del algoritmo PBKDF2 para generar un vector de inicialización de 128 bits y una clave de cifrado de 256 bits a partir de la contraseña. Tenga en cuenta la sal aleatoria que es importante tener un vector de inicialización diferente y una clave para cada mensaje cifrado. Esto garantiza en particular que dos mensajes iguales no darán como resultado un texto cifrado idéntico, pero también evita que los atacantes reutilicen el trabajo empleado en adivinar una frase de contraseña en los mensajes cifrados con otra frase de contraseña. Esta sal debe almacenarse junto con el mensaje cifrado para poder derivar el mismo vector de inicialización y la clave para descifrar. El siguiente código volverá a descifrar nuestro mensaje: Generando firmas RSA usando pycrypto RSA se puede utilizar para crear una firma de mensaje. Una firma válida solo se puede generar con acceso a la clave RSA privada, por lo que la validación es posible con la clave pública correspondiente. Por lo tanto, mientras la otra parte sepa su clave pública, podrán verificar el mensaje que usted firmará y no se modificará, por ejemplo, un enfoque utilizado para el correo electrónico. Actualmente, se requiere un módulo de terceros como pycrypto para esta funcionalidad. dklen=IV_SIZE + KEY_SIZE) iv = derived[0:IV_SIZE] key = derived[IV_SIZE:] encrypted = salt + AES.new(key, AES.MODE_CFB, iv).encrypt(cleartext)
    • 941. 876 with open('pubkey.pem', 'rb') as f: key = RSA.importKey(f.read()) hasher = SHA256.new(message) verifier = PKCS1_v1_5.new(key) if verifier.verify(hasher, signature): print('Nice, the signature is valid!') else: print('No, the message was signed with the wrong private key or modified') from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA message = b'Thisis a very secret message.' with open('pubkey.pem', 'rb') as f: key = RSA.importKey(f.read()) cipher = PKCS1_OAEP.new(key) encrypted = cipher.encrypt(message) with open('privkey.pem', 'rb') as f: key = RSA.importKey(f.read()) cipher = PKCS1_OAEP.new(key) decrypted = cipher.decrypt(encrypted) La verificación de la firma funciona de manera similar pero usa la clave pública en lugar de la clave privada: Nota : los ejemplos anteriores utilizan el algoritmo de firma PKCS # 1 v1.5, que es muy común. pycrypto también implementa el nuevo algoritmo PKCS # 1 PSS, reemplazando PKCS1_v1_5 por PKCS1_PSS en los ejemplos debería funcionar si desea usar ese. Sin embargo, actualmente parece que hay pocas razones para usarlo . Cifrado RSA asimétrico utilizando pycrypto El cifrado asimétrico tiene la ventaja de que un mensaje puede cifrarse sin intercambiar una clave secreta con el destinatario del mensaje. El remitente simplemente necesita conocer la clave pública de los destinatarios, esto permite cifrar el mensaje de manera que solo el destinatario designado (que tiene la clave privada correspondiente) pueda descifrarlo. Actualmente, se requiere un módulo de terceros como pycrypto para esta funcionalidad. El destinatario puede descifrar el mensaje si tiene la clave privada correcta: raise # No private key, generate a new one. This can take a few seconds. key = RSA.generate(4096) with open('privkey.pem', 'wb') as f: f.write(key.exportKey('PEM')) with open('pubkey.pem', 'wb') as f: f.write(key.publickey().exportKey('PEM')) hasher = SHA256.new(message) signer = PKCS1_v1_5.new(key) signature = signer.sign(hasher)
    • 942. 877 Nota : Los ejemplos anteriores utilizan el esquema de cifrado OPAP PKCS # 1. pycrypto también implementa el esquema de cifrado PKCS # 1 v1.5, este no se recomienda para nuevos protocolos, sin embargo, debido a advertencias conocidas .
    • 943. 878 Capítulo 180: Serialización de datos Sintaxis • unpickled_string = pickle.loads (cadena) • unpickled_string = pickle.load (file_object) • pickled_string = pickle.dumps ([('', 'cmplx'), {('object',): None}], pickle.HIGHEST_PROTOCOL) • pickle.dump (('', 'cmplx'), {('object',): None}], file_object, pickle.HIGHEST_PROTOCOL) • unjsoned_string = json.loads (cadena) • unjsoned_string = json.load (file_object) • jsoned_string = json.dumps (('a', 'b', 'c', [1, 2, 3])) • json.dump (('' a ',' b ',' c ', [1, 2, 3]), file_object) Parámetros Parámetro Detalles Usando pickle o cPickle , es el método por el cual los objetos se serializan o no protocol serializan.Probablementequierasusar pickle.HIGHEST_PROTOCOL aquí,loque significa el método más nuevo. Observaciones ¿Por qué usar JSON? • Soporte de idiomas • Legible para humanos • A diferencia de Pickle, no tiene el peligro de ejecutar código arbitrario ¿Por qué no usar JSON? • No admite tipos de datos Pythonic • Las claves en los diccionarios no deben ser más que tipos de datos de cadena. ¿Por qué Pickle? • Gran manera de serializar Pythonic (tuplas, funciones, clases) • Las claves en los diccionarios pueden ser de cualquier tipo de datos. ¿Por qué no pickle? • Falta soporte de idiomas • No es seguro cargar datos arbitrarios.
    • 944. 879 import json families = (['John'], ['Mark', 'David', {'name': 'Avraham'}]) # Dumping it into string json_families = json.dumps(families) # [["John"], ["Mark", "David", {"name": "Avraham"}]] # Dumping it to file with open('families.json', 'w') as json_file: json.dump(families, json_file) # Loading it from string json_families = json.loads(json_families) # Loading it from file with open('families.json', 'r') asjson_file: json_families = json.load(json_file) # Importing pickle try: import cPickle as pickle # Python 2 except ImportError: import pickle # Python 3 # Creating Pythonic object: class Family(object): def init (self, names): self.sons = names def str (self): return ' '.join(self.sons) my_family = Family(['John', 'David']) # Dumping to string pickle_data = pickle.dumps(my_family, pickle.HIGHEST_PROTOCOL) # Dumping to file Examples Serialización utilizando JSON JSON es un método de lenguaje cruzado, ampliamente utilizado para serializar datos. Tipos de datos admitidos: int , float , booleano , cadena , lista y dict . Ver -> JSON Wiki para más Aquí hay un ejemplo que demuestra el uso básico de JSON : Consulte el módulo JSON para obtener información detallada sobre JSON. Serialización utilizando Pickle Aquí hay un ejemplo que demuestra el uso básico de pickle :
    • 945. 880 Consulte Pickle para obtener información detallada acerca de Pickle. ADVERTENCIA : La documentación oficial para pickle deja en claro que no hay garantías de seguridad. No cargues ningún dato en el que no confíes en su origen. withopen('family.p', 'w') as pickle_file: pickle.dump(families, pickle_file, pickle.HIGHEST_PROTOCOL) # Loading from string my_family = pickle.loads(pickle_data) # Loading from file with open('family.p', 'r') as pickle_file: my_family =pickle.load(pickle_file)
    • 946. 881 Capítulo 181: Serialización de datos de salmuera Sintaxis • pickle.dump (objeto, archivo, protocolo) # Para serializar un objeto • pickle.load (archivo) # Para des-serializar un objeto • pickle.dumps (objeto, protocolo) # Para serializar un objeto a bytes • pickle.loads (buffer) # Para eliminar un serial de un objeto de bytes Parámetros Parámetro Detalles objeto El objeto que se va a almacenar. expediente El archivo abierto que contendrá el objeto. protocolo El protocolo utilizado para el decapado del objeto (parámetro opcional) buffer Un objeto de bytes que contiene un objeto serializado. Observaciones Tipos pickleable Los siguientes objetos son desmontables. • None , True y False • números (de todos los tipos) • cuerdas (de todo tipo) • tuple s, list s, set s y dict s que solo contienen objetos que se pueden recoger • Funciones definidas en el nivel superior de un módulo. • funciones integradas • Clases que se definen en el nivel superior de un módulo. ○ instancias de dichas clases cuyo dict o el resultado de llamar a getstate () es seleccionable (consulte los documentos oficialespara obtener más información). Basado en la documentación oficial de Python .
    • 947. 882 import pickle # An arbitrary collection of objects supported by pickle. data = { 'a': [1, 2.0, 3, 4+6j], 'b': ("character string", b"byte string"), 'c': {None, True, False} } with open('data.pickle', 'wb') as f: # Pickle the 'data' dictionary using the highest protocol available. pickle.dump(data, f, pickle.HIGHEST_PROTOCOL) import pickle with open('data.pickle', 'rb') as f: # The protocol version used is detected automatically, so we do not # have to specify it. data = pickle.load(f) pickle y seguridad El módulo pickle no es seguro . No debe utilizarse cuando se reciben datos serializados de una parte que no es de confianza, como a través de Internet. Examples Usando Pickle para serializar y deserializar un objeto El módulo pickle implementa un algoritmo para convertir un objeto Python arbitrario en una serie de bytes. Este proceso también se llama serializar el objeto. El flujo de bytes que representa el objeto se puede transmitir o almacenar, y luego reconstruir para crear un nuevo objeto con las mismas características. Para el código más simple, usamos las funciones dump() y load() . Para serializar el objeto. Deserializar el objeto. Usando objetos de pickle y byte También es posible serializar y deserializar objetos de byte, utilizando la función de dumps y loads ,
    • 948. 883 serialized_data = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) # type(serialized_data) is bytes deserialized_data = pickle.loads(serialized_data) # deserialized_data == data class A(object): def init (self, important_data): self.important_data = important_data # Add data which cannot be pickled: self.func = lambda: 7 # Add data which should never be pickled, because it expires quickly: self.is_up_to_date = False def getstate (self): return [self.important_data] # only this is needed def setstate (self, state): self.important_data = state[0] self.func = lambda: 7 # just some hard-coded unpicklable function self.is_up_to_date = False # even if it was before pickling >>> a1 = A('very important') >>> >>> s = pickle.dumps(a1) # calls a1. getstate () >>> >>> a2 = pickle.loads(s) # calls a1. setstate (['very important']) >>> a2 < main .A object at 0x0000000002742470> >>> a2.important_data 'very important' >>> a2.func() 7 que son equivalentes a dump y load . Personalizar datos en escabeche Algunos datos no pueden ser decapados. Otros datos no deben ser decapados por otras razones. Lo que será decapado se puede definir en el método getstate . Este método debe devolver algo que sea pickable. En el lado opuesto está setstate : recibirá lo que getstate creóytienequeinicializarel objeto. Ahora, esto se puede hacer: La implementación aquí muestra una lista con un valor: [self.important_data] .Eso fue solo un ejemplo, getstate podríahaberdevueltocualquiercosaquesepuedarecoger,siemprey cuando setstate sepa cómo hacerel oppoisite.Unabuena alternativa esundiccionario de
    • 949. 884 todos los valores: {'important_data': self.important_data} . ¡Elconstructornosellama!Tengaencuentaqueenelejemploanterior,lainstanciaa2secreó en pickle.loads sin haber llamado a A. init , por lo que A. setstate tuvo que inicializar todo lo que init se habría inicializado si se hubierallamado.
    • 950. 885 python -m SimpleHTTPServer 9000 python -m http.server 9000 import sys import BaseHTTPServer from SimpleHTTPServer import SimpleHTTPRequestHandler HandlerClass = SimpleHTTPRequestHandler ServerClass = BaseHTTPServer.HTTPServer Protocol = "HTTP/1.0" if sys.argv[1:]: port = int(sys.argv[1]) else: port = 8000 server_address = ('127.0.0.1', port) HandlerClass.protocol_version = Protocol httpd = ServerClass(server_address, HandlerClass) sa = httpd.socket.getsockname() print "Serving HTTP on", sa[0], "port", sa[1], "..." httpd.serve_forever() Capítulo 182: Servidor HTTP de Python Examples Ejecutando un servidor HTTP simple Python 2.x 2.3 Python 3.x 3.0 La ejecución de este comando sirve los archivos del directorio actual en el puerto 9000 . Si no se proporciona ningún argumento como número de puerto, el servidor se ejecutará en el puerto predeterminado 8000 . El indicador -m buscará en sys.path el archivo .py correspondiente para ejecutarse como un módulo. Si solo quieres servir en localhost, deberás escribir un programa Python personalizado como: Archivos de servicio Suponiendo que tiene el siguiente directorio de archivos:
    • 951. 886 import SimpleHTTPServer import SocketServer PORT = 8000 handler = SimpleHTTPServer.SimpleHTTPRequestHandler httpd = SocketServer.TCPServer(("localhost", PORT), handler) print "Serving files at port {}".format(PORT) httpd.serve_forever() import http.server import socketserver PORT = 8000 handler = http.server.SimpleHTTPRequestHandler httpd = socketserver.TCPServer(("", PORT), handler) print("serving at port", PORT) httpd.serve_forever() Puede configurar un servidor web para servir estos archivos de la siguiente manera: Python 2.x 2.3 Python 3.x 3.0 El módulo SocketServer proporciona las clases y funcionalidades para configurar un servidor de red. SocketServer 's TCPServer clase configura un servidor utilizando el protocolo TCP. El constructor aceptauna tupla que representa la dirección del servidor(es decir, ladirección IP y el puerto) y la clase que maneja las solicitudes del servidor. El SimpleHTTPRequestHandler clase del SimpleHTTPServer módulo permite a los archivos en el directorio actual para ser servido. Guarde el script en el mismo directorio y ejecútelo. Ejecuta el servidor HTTP: Python 2.x 2.3 python -m SimpleHTTPServer 8000 Python 3.x 3.0
    • 952. 887 def test(HandlerClass = SimpleHTTPRequestHandler, ServerClass =BaseHTTPServer.HTTPServer): BaseHTTPServer.test(HandlerClass, ServerClass) if name == ' main ': test() def test(HandlerClass = BaseHTTPRequestHandler, ServerClass = HTTPServer, protocol="HTTP/1.0"): """Test the HTTP request handler class. Thisruns an HTTP server on port 8000 (or the first command line argument). """ if sys.argv[1:]: port = int(sys.argv[1]) else: port = 8000 python -m http.server 8000 El indicador '-m' buscará 'sys.path' para que el archivo '.py' correspondiente se ejecute como un módulo. Abra localhost: 8000 en el navegador, le dará lo siguiente: API programática de SimpleHTTPServer ¿Qué sucede cuando ejecutamos python -m SimpleHTTPServer 9000 ? Para responder a esta pregunta, debemos entender el constructo de SimpleHTTPServer ( https://hg.python.org/cpython/file/2.7/Lib/SimpleHTTPServer.py) y BaseHTTPServer ( https://hg.python.org/cpython/file /2.7/Lib/BaseHTTPServer.py) . En primer lugar, Python invoca el módulo SimpleHTTPServer con 9000 como argumento. Ahora observando el código SimpleHTTPServer, La función de prueba se invoca después de los controladores de solicitudes y ServerClass. Ahora se invoca BaseHTTPServer.test
    • 953. 888 |UDPServer| ------->|UnixDatagramServer| +-----------+ +--------------------+ +--------------------+ +-----------+ +------------------+ | v +-----------+ |TCPServer| ------- >|UnixStreamServer| +------------------+ +------------+ |BaseServer| +------------+ | v +-----------+ # from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer # python2 from http.server import BaseHTTPRequestHandler, HTTPServer # python3 class HandleRequests(BaseHTTPRequestHandler): def _set_headers(self): self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() def do_GET(self): self._set_headers() self.wfile.write("received get request") def do_POST(self): '''Reads post request body''' self._set_headers() content_len = int(self.headers.getheader('content-length', 0)) post_body = self.rfile.read(content_len) self.wfile.write("received post request:<br>{}".format(post_body)) def do_PUT(self): self.do_POST() Por lo tanto, aquí se analiza el número de puerto, que el usuario pasó como argumento y está vinculado a la dirección del host. Se llevan a cabo otros pasos básicos de programación de socket con puerto y protocolo dados. Finalmente se inicia el servidor socket. Esta es una descripción básica de la herencia de la clase SocketServer a otras clases: Los enlaces https://hg.python.org/cpython/file/2.7/Lib/BaseHTTPServer.py y https://hg.python.org/cpython/file/2.7/Lib/SocketServer.py son útiles para encontrar más información. información. Manejo básico de GET, POST, PUT usando BaseHTTPRequestHandler server_address = ('', port) HandlerClass.protocol_version = protocol httpd = ServerClass(server_address, HandlerClass) sa = httpd.socket.getsockname() print "Serving HTTP on", sa[0], "port", sa[1], "..." httpd.serve_forever()
    • 954. 889 $ curl http://localhost/ received get request% $ curl -X POST http://localhost/ received post request:<br>% $ curl -X PUT http://localhost/ received post request:<br>% $ echo 'hello world' | curl --data-binary @- http://localhost/ received post request:<br>hello world Ejemplo de salida utilizando curl : host = '' port = 80 HTTPServer((host, port), HandleRequests).serve_forever()
    • 955. 890 from distutils.core import setup setup(name='foo', version='1.0', py_modules=['foo'], ) Capítulo 183: setup.py Parámetros Parámetro Uso name Nombre de su distribución. version Cadena de versión de su distribución. packages ListadepaquetesdePython (esdecir,directoriosquecontienenmódulos)para incluir. Esto se puede especificar manualmente, pero en su setuptools.find_packages() se suele usar una llamada a setuptools.find_packages() . py_modules Lista de módulos de Python de nivel superior (es decir, archivos .py individuales) para incluir. Observaciones Para más información sobre el embalaje de python, consulte: Introducción Para escribir paquetes oficiales hay una guía de usuario de empaquetado . Examples Propósito de setup.py El script de configuración es el centro de toda actividad en la construcción, distribución e instalación de módulos utilizando los Distutils. Su propósito es la correcta instalación del software. Si todo lo que quiere hacer es distribuir un módulo llamado foo, contenido en un archivo foo.py, su secuencia de comandos de instalación puede ser tan simple como esto: Para crear una distribución de origen para este módulo, debe crear un script de configuración, setup.py, que contenga el código anterior, y ejecutar este comando desde una terminal:
    • 956. 891 python setup.py install greetings/ greetings/ init .py hello_world.py python greetings/greetings/hello_world.py hello_world.py from setuptools import setup setup( name='greetings', scripts=['hello_world.py'] ) sdist creará un archivo de archivo (por ejemplo, tarball en Unix, archivo ZIP en Windows) que contiene su script de configuración setup.py y su módulo foo.py. El archivo comprimido se llamará foo-1.0.tar.gz (o .zip) y se descomprimirá en un directorio foo-1.0. Si un usuario final desea instalar su módulo foo, todo lo que tiene que hacer es descargar foo1.0.tar.gz (o .zip), descomprimirlo y, desde el directorio foo-1.0, ejecutar Agregando scripts de línea de comandos a su paquete de Python Los guiones de línea de comando dentro de los paquetes de python son comunes. Puede organizar su paquete de tal manera que cuando un usuario instala el paquete, el script estará disponible en su ruta. Si tenía el paquete de greetings que tenía la secuencia de comandos script hello_world.py . Puedes ejecutar ese script ejecutando: Sin embargo si quieres correrlo así: Puede lograr esto agregando scripts a su setup() en setup.py estamanera: Cuando instale el paquete de saludos ahora, se agregará a su ruta hello_world.py . Otra posibilidad sería agregar un punto de entrada: De esta manera solo tienes que ejecutarlo como: entry_points={'console_scripts': ['greetings=greetings.hello_world:main']} python setup.py sdist
    • 957. 892 from setuptools import setup, find_packages setup( setup_requires=['setuptools_scm'], use_scm_version=True, packages=find_packages(), include_package_data=True, ) python setup.py install python setup.py develop cmdclasses = dict() class BuildSphinx(Command): """Build Sphinx documentation.""" description = 'Build Sphinx documentation' user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): import sphinx Usando metadatos de control de fuente en setup.py setuptools_scm es un paquete oficialmente bendecido que puede usar metadatos de Git o Mercurial para determinar el número de versión de su paquete, y encontrar paquetes de Python y datos de paquetes para incluir en ellos. Esteejemploutilizaambas características;parausarsololosmetadatosdeSCMparalaversión, reemplace la llamada a find_packages() con su lista de paquetes del manual, o para usar solo el buscador de paquetes, elimine use_scm_version=True . Añadiendo opciones de instalación Como se vio en ejemplos anteriores, el uso básico de este script es: Pero hay aún más opciones, como instalar el paquete y tener la posibilidad de cambiar el código y probarlo sin tener que volver a instalarlo. Esto se hace usando: Si desea realizar acciones específicas como compilar una documentación de Sphinx o crear un código fortran , puede crear su propia opción como esta: greetings
    • 958. 893 python setup.py build_sphinx initialize_options y finalize_options se ejecutarán antes y después de la función de run , tal como lo sugieren susnombres. Después de eso, podrás llamar a tu opción: sphinx.build_main(['setup.py', '-b', 'html', './doc', './doc/_build/html']) sphinx.build_main(['setup.py', '-b', 'man', './doc', './doc/_build/man']) cmdclasses['build_sphinx'] = BuildSphinx setup( ... cmdclass=cmdclasses, )
    • 959. 894 2 in [2, 3] {'0': 2, '1': 3} Capítulo 184: Similitudes en la sintaxis, diferencias en el significado: Python vs. JavaScript Introducción A veces sucede que dos idiomas ponen significados diferentes en la misma expresión desintaxis o similar. Cuando ambos lenguajes son de interés para un programador, aclarar estos puntos de bifurcación ayuda a comprender mejor los dos lenguajes en sus conceptos básicos y sutilezas. Examples `in` con listas En Python esto se evalúa como Verdadero, pero en JavaScript como falso. Esto se debe a queen Python comprueba si un valor está contenido en una lista, por lo que 2 está en [2, 3] como su primer elemento. En JavaScript se usa con objetos y comprueba si un objeto contiene la propiedad con el nombre expresado por el valor. Así que JavaScript considera [2, 3] como un objeto o un mapa de clave-valor como este: y verifica si tiene una propiedad o una clave '2' en ella. El entero 2 se convierte silenciosamente a la cadena '2'.
    • 960. 895 import math class Vector(object): # instantiation def init (self, x, y): self.x = x self.y = y # unary negation (-v) def neg (self): return Vector(-self.x, -self.y) # addition (v + u) def add (self, other): return Vector(self.x + other.x, self.y + other.y) # subtraction (v - u) def sub (self, other): return self + (-other) # equality (v == u) def eq (self, other): return self.x == other.x and self.y == other.y # abs(v) def abs (self): return math.hypot(self.x, self.y) # str(v) def str (self): return '<{0.x}, {0.y}>'.format(self) # repr(v) def repr (self): return 'Vector({0.x}, {0.y})'.format(self) v = Vector(1, 4) Capítulo 185: Sobrecarga Examples Métodos de magia / Dunder Los métodos de Magic (también llamados dunder como abreviatura de subrayado doble) en Python tienen un propósito similar al de la sobrecarga de operadores en otros idiomas. Permiten a una clase definir su comportamiento cuando se usa como un operando en expresiones de operador unarias o binarias. También sirven como implementaciones llamadas por algunas funciones integradas. Considere esta implementación de vectores bidimensionales. Ahora es posible usar naturalmente instancias de la clase Vector en varias expresiones.
    • 961. 896 class sparselist(object): def init (self, size): self.size = size self.data = {} # l[index] def getitem (self, index): if index < 0: index += self.size if index >= self.size: raise IndexError(index) try: return self.data[index] except KeyError: return 0.0 # l[index] = value def setitem (self, index, value): self.data[index] = value # del l[index] def delitem (self, index): if index in self.data: del self.data[index] # value in l def contains (self, value): return value == 0.0 or value in self.data.values() # len(l) def len (self): return self.size # for value in l: ... def iter (self): return (self[i] for i in range(self.size)) # use xrange for python2 l = sparselist(10 ** 6) # list with 1 million elements 0 in l # True Contenedor y tipos de secuencia. Es posible emular tipos de contenedores, que admiten el acceso a valores por clave o índice. Considere esta implementación ingenua de una lista dispersa, que almacena solo los elementos que no son cero para conservar la memoria. Entonces, podemos usar una lista sparselist como una list normal. u = Vector(2, 0) u + v # Vector(3, 4) print(u + v) # "<3, 4>" (implicit string conversion) u - v # Vector(1, -4) u == v # False u + v == v + u # True abs(u + v) # 5.0
    • 962. 897 class adder(object): def init (self, first): self.first = first # a(...) def call (self, second): return self.first + second add2 = adder(2) add2(1) # 3 add2(2) # 4 class NotAddable(object): def init (self, value): self.value = value def add (self, other): return NotImplemented class Addable(NotAddable): def add (self, other): return Addable(self.value + other.value) radd = add Tipos callables Manejando conductas no implementadas. Sisuclasenoimplementaunoperadorsobrecargadoespecíficoparalostiposdeargumentos provistos, debería return NotImplemented (tenga en cuenta que esta es una constante especial , nolamisma que NotImplementedError ).Estopermitirá aPythonvolver aprobar otros métodos para hacer que la operaciónfuncione: Cuando se devuelve NotImplemented , el intérprete intentará la operación reflejada en el otro tipo,o algún otro repliegue, dependiendo del operador.Si todas las operaciones intentadas devuelven No NotImplemented , el intérprete generará una excepción apropiada. Por ejemplo, dado x + y , si x. add (y) devuelve no implementado, y. radd (x) se intenta en su lugar. for v in l: pass # 0, 0, 0, ... 10, 0, 0 ... 0 # True # 10 l[12345] = 10 10 in l l[12345] 10 in l # False
    • 963. 898 >>> x = NotAddable(1) >>> y = Addable(2) >>> x + x Traceback (most recent call last): File "<stdin>", line 1, in<module> TypeError: unsupported operand type(s) for +: 'NotAddable' and 'NotAddable' >>> y + y <so.Addable object at 0x1095974d0> >>> z = x + y >>> z <so.Addable object at 0x109597510> >>> z.value 3 Como este es el método reflejado , debemos implementar add y radd para obtener el comportamientoesperadoentodosloscasos;afortunadamente,comoambosestánhaciendolo mismo en este simple ejemplo, podemos tomar un atajo. En uso: Sobrecarga del operador A continuación se muestran los operadores que pueden sobrecargarse en clases, junto con las definiciones de métodos que se requieren y un ejemplo del operador en uso dentro de una expresión. Nota: el uso de other como nombre de variable no es obligatorio, pero se considera la norma. Operador Método Expresión + Adición add (self, other) a1 + a2 - Resta sub (self, other) a1 - a2 * Multiplicación mul (self, other) a1 * a2 @ Matrix Multiplication matmul (self, other) a1 @ a2 ( Python 3.5 ) / División div (self, other) a1 / a2 ( solo Python 2 ) / División truediv (self, other) a1 / a2 ( Python 3 ) //División del piso floordiv (self, other) a1 // a2 % Modulo / resto mod (self, other) a1 % a2 ** Poder pow (self, other[, modulo]) a1 ** a2 << Bitwise Left Shift lshift (self, other) a1 << a2 >> Bitwise Right Shift rshift (self, other) a1 >> a2
    • 964. 899 class A: def init (self, a): self.a = a def add (self, other): return self.a + other def radd (self, other): print("radd") return other + self.a A(1) + 2 # Out: 3 2 + A(1) # prints radd. Out: 3 Operador Método Expresión & Bitwise Y ^ Bitwise XOR and (self, other) xor (self, other) a1 a1 & ^ a2 a2 |(Bitwise OR) or (self, other) a1 | a2 - Negación(Aritmética) neg (self) -a1 + Positivo pos (self) +a1 ~ Bitwise NO invert (self) ~a1 < Menos que lt (self, other) a1 < a2 <= Menor que o igual a le (self, other) a1 <= a2 == Igual a eq (self, other) a1 == a2 != No es igual a ne (self, other) a1 != a2 > Mayor que gt (self, other) a1 > a2 >= Mayor que o igual a ge (self, other) a1 >= a2 [index] operador deíndice getitem (self, index) a1[index] in En operador contains (self, other) a2 in a1 (*args, ...) Llamando call (self, *args, **kwargs) a1(*args, **kwargs) El modulo parámetro opcionalpara pow solo lo utiliza la función incorporada pow . Cadaunodelosmétodoscorrespondientes a unoperadorbinariotieneunmétodo"correcto" correspondiente que comienza con r , por ejemplo radd : así como una versión in situ correspondiente, comenzando con i :
    • 965. 900 Como no hay nada especial en estos métodos, muchas otras partes del lenguaje, partes de la biblioteca estándar e incluso módulos de terceros agregan métodos mágicos por sí mismos, como métodos para convertir un objeto en un tipo o verificar las propiedades del objeto. Por ejemplo, la función str() incorporada llama al método str del objeto, si existe. Algunos de estos usos se enumeran a continuación. Función Método Expresión Casting a int int (self) int(a1) Función absoluta abs (self) abs(a1) Casting a str str (self) str(a1) Casting a unicode unicode (self) unicode(a1) (solo Python 2) Representación de cuerdas repr (self) repr(a1) Casting a bool nonzero (self) bool(a1) Formato de cadena format (self, formatstr) "Hi {:abc}".format(a1) Hash hash (self) hash(a1) Longitud len (self) len(a1) Invertido reversed (self) reversed(a1) Piso floor (self) math.floor(a1) Techo ceil (self) math.ceil(a1) También existen los métodos especiales enter y exit paraadministradoresdecontexto,y muchos más. class B: def init (self, b): self.b = b def iadd (self, other): self.b += other print("iadd") return self b = B(2) b.b # Out: 2 b += 1 # prints iadd b.b # Out: 3
    • 966. 901 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) host = raw_input("Server Address To Be Connected -> ") port = int(input("Port of The Server -> ")) server.connect((host, port)) Capítulo 186: Sockets y cifrado / descifrado de mensajes entre el cliente y el servidor Introducción La criptografía se utiliza para fines de seguridad. No hay tantos ejemplos de cifrado / descifrado en Python utilizando el CTR de MODO de cifrado de IDEA. Objetivo de esta documentación: Ampliación e implementación del esquema de firma digital RSA en la comunicación de estación a estación. Usando Hashing para la integridad del mensaje, eso es SHA-1. Produce un protocolo simple de transporte de llaves. Cifrar clave con cifrado IDEA. El modo de cifrado de bloque es el modo contador. Observaciones Idioma utilizado: Python 2.7 (enlace de descarga: https://www.python.org/downloads/ ) Biblioteca utilizada: * PyCrypto (Enlace de descarga: https://pypi.python.org/pypi/pycrypto ) * PyCryptoPlus (Enlace de descarga: https://github.com/doegox/python-cryptoplus ) Instalación de la biblioteca: PyCrypto: descomprime el archivo. Vaya al directorio y abra el terminal para Linux (alt + ctrl + t) y CMD (Mayús + clic con el botón derecho + seleccionar indicador de comando abrir aquí) para Windows. Después de eso, escriba python setup.py install (Asegúrese de que Python Environment esté configurado correctamente en el sistema operativo Windows) PyCryptoPlus: igual que la última biblioteca. Implementación de tareas: La tarea se divide en dos partes. Uno es el proceso de apretón de manos y otro es el proceso de comunicación. Configuración de zócalo: • Como la creación de claves públicas y privadas, así como el hashing de la clave pública, necesitamos configurar el socket ahora. Para configurar el socket, debemos importar otro módulo con "importar socket" y conectar (para el cliente) o vincular (para el servidor) la dirección IP y el puerto con el socket que recibe del usuario. ----------Lado del cliente----------
    • 967. 902 try: #setting up socket server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind((host,port)) server.listen(5) except BaseException: print "-----Check Server Address or Port-------" random_generator = Random.new().read key = RSA.generate(1024,random_generator) public = key.publickey().exportKey() hash_object = hashlib.sha1(public) hex_digest = hash_object.hexdigest() ----------Lado del servidor--------- "Socket.AF_INET, socket.SOCK_STREAM" nos permitirá utilizar la función accept () y los aspectos básicos de los mensajes. En lugar de eso, también podemos usar "socket.AF_INET, socket.SOCK_DGRAM", pero esa vez tendremos que usar setblocking (valor). Proceso de apretón de manos: • (CLIENTE) La primera tarea es crear claves públicas y privadas. Para crear la clave privada y pública, tenemos que importar algunos módulos. Son: desde Crypto import Random y desde Crypto.PublicKey import RSA. Para crear las claves, tenemos que escribir algunas líneas simples de códigos: random_generator se deriva del módulo " desde Crypto import Random ". La clave se deriva de " from Crypto.PublicKey import RSA " que creará una clave privada, tamaño de 1024 generando caracteres aleatorios. Público está exportando clave pública desde clave privada generada anteriormente. • (CLIENTE) Después de crear la clave pública y privada, debemos codificar la clave pública para enviarla al servidor mediante el hash SHA-1. Para usar el hash SHA-1 necesitamos importar otro módulo escribiendo "importar hashlib". Para codificar la clave pública, escribimos dos líneas de código: Aquíhash_objectyhex_digestesnuestravariable.Despuésdeesto,elclienteenviaráhex_digest y public al servidor y el Servidorlos verificará comparando el hash obtenido del cliente y el nuevo hash de la clave pública. Si el nuevo hash y el hash del cliente coinciden, pasará al siguiente procedimiento. Como el público enviado desde el cliente está en forma de cadena, no podrá utilizarse como clave en el lado del servidor. Para evitar esto y convertir la clave pública de cadena en rsa clave pública, necesitamos escribir server_public_key = RSA.importKey(getpbk) , aquí getpbk es la clave pública del cliente. • (SERVIDOR) El siguiente paso es crear una clave de sesión. Aquí, he usado el módulo "os" para crear una clave aleatoria "key = os.urandom (16)" que nos dará una clave de 16 bits y después de eso he cifrado esa clave en "AES.MODE_CTR" y la hash de nuevo conSHA-1:
    • 968. 903 #encrypting session key and public key E = server_public_key.encrypt(encrypto,16) en = eval(msg) decrypt = key.decrypt(en) # hashing sha1 en_object = hashlib.sha1(decrypt) en_digest = en_object.hexdigest() Así que el en_digest será nuestra clave de sesión. • (SERVIDOR) Para la parte final del proceso de protocolo de enlace es cifrar la clave pública obtenida del cliente y la clave de sesión creada en el lado del servidor. Después del cifrado, el servidor enviará la clave al cliente como una cadena. • (CLIENTE) Después de obtener la cadena cifrada (pública y clave de sesión) del servidor, el cliente los descifra usando la clave privada que se creó anteriormente junto con la clave pública. Como el cifrado (público y clave de sesión) estaba en forma de cadena, ahora debemos recuperarlo como clave mediante el uso de eval (). Si se realiza el descifrado, el proceso de intercambio se completa también, ya que ambas partes confirman que están utilizando las mismas claves. Para descifrar: He usado el SHA-1 aquí para que sea legible en la salida. Proceso de comunicación: Para el proceso de comunicación, tenemos que usar la clave de sesión de ambos lados como la CLAVE para el cifrado IDEA MODE_CTR. Ambos lados cifrarán y descifrarán mensajes con IDEA.MODE_CTR usando la clave de sesión. • (Cifrado) Para el cifrado IDEA, necesitamos una clave de 16 bits de tamaño y contador, como debe ser reclamable. El contador es obligatorio en MODE_CTR. La clave de la sesión que ciframos y hash tiene ahora un tamaño de 40 que excederá la clave límite del cifrado IDEA. Por lo tanto, necesitamos reducir el tamaño de la clave de sesión. Para reducir, podemos usar la función normal python integrada en la cadena de función [valor: valor]. Donde el valor puede ser cualquier valor según la elección del usuario. En nuestro caso, he hecho "clave [: 16]" donde tomará de 0 a 16 valores de la clave. Esta conversión se puede hacer de muchas maneras, como la clave [1:17] o la clave [16:]. La siguiente parte es crear una nueva función de cifrado de IDEA escribiendo IDEA.new () que tomará 3 argumentos para su procesamiento. El primer argumento será CLAVE, el segundo será el modo del cifrado de IDEA (en nuestro caso, IDEA.MODE_CTR) y el tercer argumento será el contador = que es una función que se debe llamar. El contador = mantendrá un tamaño de cadena #encrypt CTR MODE session key en = AES.new(key_128,AES.MODE_CTR,counter = lambda:key_128) encrypto = en.encrypt(key_128) #hashing sha1 en_object = hashlib.sha1(encrypto) en_digest = en_object.hexdigest()
    • 969. 904 ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key) eMsg = ideaEncrypt.encrypt(whole) #convertingthe encryptedmessage to HEXADECIMALtoreadable eMsg= eMsg.encode("hex").upper() decoded = newmess.decode("hex") ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key) dMsg = ideaDecrypt.decrypt(decoded) import socket import hashlib import os import time import itertools import threading import sys import Crypto.Cipher.AES as AES from Crypto.PublicKey import RSA que será devuelto por la función. Para definir el contador =, debemos tener que usar unos valores razonables. En este caso, he usado el tamaño de la CLAVE definiendo lambda. En lugar de usar lambda, podríamos usar Counter.Util que genera un valor aleatorio para counter =. Para usar Counter.Util, necesitamos importar el módulo de contador desde crypto. Por lo tanto, el código será: Una vez que definimos el "IdeaEncrypt" como nuestra variable de cifrado IDEA, podemos usar la función integrada de cifrado para cifrar cualquier mensaje. En este segmento de código, entero es el mensaje que se va a cifrar y eMsg es el mensaje cifrado. Después de cifrar el mensaje, lo he convertido en HEXADECIMAL para que sea legible y upper () es la función incorporada para hacer que los caracteres estén en mayúsculas. Después de eso, este mensaje cifrado se enviará a la estación opuesta para su descifrado. • (Descifrado) Para descifrar los mensajes cifrados, necesitaremos crear otra variable de cifrado utilizando los mismos argumentos y la misma clave, pero esta vez la variable descifrará los mensajes cifrados. El código para este mismo que la última vez. Sin embargo, antes de descifrar los mensajes, necesitamos decodificar el mensaje de hexadecimal porque en nuestra parte de cifrado, codificamos el mensaje cifrado en hexadecimal para que sea legible. Por lo tanto, todo el código será: Estos procesos se realizarán tanto en el servidor como en el lado del cliente para el cifrado y descifrado. Examples Implementación del lado del servidor
    • 970. 905 from CryptoPlus.Cipher import IDEA #server address and port number input from admin host= raw_input("Server Address - > ") port = int(input("Port - > ")) #boolean for checking server and port check = False done = False def animate(): for c in itertools.cycle(['....','.......','..........','................. ']): if done: break sys.stdout.write('\rCHECKING IP ADDRESS AND NOT USED PORT '+c) sys.stdout.flush() time.sleep(0.1) sys.stdout.write('\r-----SERVERSTARTED.WAITINGFORCLIENT -----\n') try: #setting up socket server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind((host,port)) server.listen(5) check = True except BaseException: print "-----Check Server Address or Port ------" check = False if check is True: # server Quit shutdown = False # printing "Server Started Message" thread_load = threading.Thread(target=animate) thread_load.start() time.sleep(4) done = True #binding client and address client,address = server.accept() print ("CLIENT IS CONNECTED. CLIENT'S ADDRESS ->",address) print ("\n-----WAITING FOR PUBLIC KEY & PUBLIC KEY HASH--------\n") #client's message(Public Key) getpbk = client.recv(2048) #conversion of string to KEY server_public_key = RSA.importKey(getpbk) #hashing the public key in server side for validating the hash from client hash_object = hashlib.sha1(getpbk) hex_digest = hash_object.hexdigest() if getpbk != "": print (getpbk) client.send("YES") gethash = client.recv(1024) print ("\n-----HASH OF PUBLIC KEY --------\n"+gethash) if hex_digest == gethash: # creating session key key_128 = os.urandom(16) #encrypt CTR MODE session key en = AES.new(key_128,AES.MODE_CTR,counter = lambda:key_128)
    • 971. 906 import time import socket import threading import hashlib import itertools import sys from Crypto import Random from Crypto.PublicKey import RSA from CryptoPlus.Cipher import IDEA #animating loading done = False def animate(): for c in itertools.cycle(['....','.......','..........','................. ']): if done: break sys.stdout.write('\rCONFIRMING CONNECTION TO SERVER '+c) sys.stdout.flush() time.sleep(0.1) Implementación del lado del cliente encrypto = en.encrypt(key_128) #hashing sha1 en_object = hashlib.sha1(encrypto) en_digest = en_object.hexdigest() print ("\n-----SESSION KEY ----- \n"+en_digest) #encrypting session key and public key E =server_public_key.encrypt(encrypto,16) print ("\n-----ENCRYPTED PUBLIC KEY AND SESSION KEY ------ \n"+str(E)) print("\n-----HANDSHAKECOMPLETE ----- ") client.send(str(E)) while True: #message from client newmess = client.recv(1024) #decoding the message from HEXADECIMAL to decrypt the ecrypted version of the message only decoded = newmess.decode("hex") #making en_digest(session_key) as the key key = en_digest[:16] print ("\nENCRYPTED MESSAGE FROM CLIENT -> "+newmess) #decrypting message from the client ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key) dMsg = ideaDecrypt.decrypt(decoded) print ("\n**New Message** "+time.ctime(time.time()) +" > "+dMsg+"\n") mess = raw_input("\nMessage To Client -> ") if mess != "": ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key) eMsg = ideaEncrypt.encrypt(mess) eMsg = eMsg.encode("hex").upper() if eMsg != "": print ("ENCRYPTED MESSAGE TO CLIENT-> " + eMsg) client.send(eMsg) client.close() else: print ("\n-----PUBLIC KEY HASH DOESNOT MATCH ------ \n")
    • 972. 907 #public key and private key random_generator = Random.new().read key =RSA.generate(1024,random_generator) public = key.publickey().exportKey() private = key.exportKey() #hashing the public key hash_object = hashlib.sha1(public) hex_digest = hash_object.hexdigest() #Setting up socket server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #host and port input user host = raw_input("Server Address To Be Connected -> ") port = int(input("Port of The Server -> ")) #binding the address and port server.connect((host, port)) # printing "Server Started Message" thread_load = threading.Thread(target=animate) thread_load.start() time.sleep(4) done = True def send(t,name,key): mess = raw_input(name + " : ") key = key[:16] #merging the message and the name whole = name+" : "+mess ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key) eMsg = ideaEncrypt.encrypt(whole) #converting the encrypted message to HEXADECIMAL to readable eMsg = eMsg.encode("hex").upper() if eMsg != "": print ("ENCRYPTED MESSAGE TO SERVER-> "+eMsg) server.send(eMsg) def recv(t,key): newmess = server.recv(1024) print ("\nENCRYPTED MESSAGE FROM SERVER-> " + newmess) key = key[:16] decoded = newmess.decode("hex") ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key) dMsg = ideaDecrypt.decrypt(decoded) print ("\n**New MessageFrom Server** " + time.ctime(time.time()) + " : " + dMsg + "\n") while True: server.send(public) confirm = server.recv(1024) if confirm == "YES": server.send(hex_digest) #connected msg msg = server.recv(1024) en = eval(msg) decrypt = key.decrypt(en) # hashing sha1 en_object = hashlib.sha1(decrypt) en_digest = en_object.hexdigest() print("\n-----ENCRYPTEDPUBLIC KEY AND SESSION KEY FROM SERVER-------")
    • 973. 908 print (msg) print ("\n-----DECRYPTEDSESSION KEY-------") print (en_digest) print("\n-----HANDSHAKECOMPLETE-------\n") alais = raw_input("\nYour Name -> ") while True: thread_send = threading.Thread(target=send,args=("------Sending Message------ ",alais,en_digest)) thread_recv = threading.Thread(target=recv,args=("------Recieving Message------ ",en_digest)) thread_send.start() thread_recv.start() thread_send.join() thread_recv.join() time.sleep(0.5) time.sleep(60) server.close()
    • 974. 909 usage: sub <command> commands: status - showstatus list - print list """ usage: sub <command> commands: status - showstatus list - print list """ import sys def check(): print("status") return 0 if sys.argv[1:] == ['status']: sys.exit(check()) elif sys.argv[1:] == ['list']: print("list") else: print( doc .strip()) Capítulo 187: Subcomandos CLI con salida de ayuda precisa Introducción Diferentes formas de crear subcomandos como en hg o svn con la interfaz de línea de comandos exacta y la salida de ayuda, como se muestra en la sección Comentarios. Análisis de los argumentos de la línea de comandos cubre un tema más amplio de análisis de argumentos. Observaciones Diferentes formas de crear subcomandos como en hg o svn con la interfaz de línea de comandos que se muestra en el mensaje de ayuda: Examples Forma nativa (sin bibliotecas)
    • 975. 910 usage: sub <command> commands: status - showstatus list - print list import argparse import sys def check(): print("status") return 0 parser = argparse.ArgumentParser(prog="sub", add_help=False) subparser = parser.add_subparsers(dest="cmd") subparser.add_parser('status', help='show status') subparser.add_parser('list', help='print list') # hack to show help when no arguments supplied if len(sys.argv) == 1: parser.print_help() sys.exit(0) args = parser.parse_args() if args.cmd == 'list': print('list') elif args.cmd == 'status': sys.exit(check()) usage: sub {status,list} ... positional arguments: {status,list} status show status list print list Salida sin argumentos: Pros: • no deps • todo el mundo debería ser capaz de leer eso • Control completo sobre el formato de ayuda. argparse (formateador de ayuda predeterminado) Salida sin argumentos: Pros: • viene con Python • Opción de análisis está incluido
    • 976. 911 argparse (formateador de ayuda personalizado) Versión extendida de http://www.levcode.com/python/example/25282/argparse--default-helpformatter- que solucionó la salida de ayuda. import argparse import sys class CustomHelpFormatter(argparse.HelpFormatter): def _format_action(self, action): if type(action) == argparse._SubParsersAction: # inject newclass variable forsubcommand formatting subactions = action._get_subactions() invocations = [self._format_action_invocation(a) for a in subactions] self._subcommand_max_length = max(len(i) for i in invocations) if type(action) == argparse._SubParsersAction._ChoicesPseudoAction: # format subcommand help line subcommand = self._format_action_invocation(action) # type: str width = self._subcommand_max_length help_text = "" if action.help: help_text = self._expand_help(action) return " {:{width}} - {}\n".format(subcommand, help_text, width=width) elif type(action) == argparse._SubParsersAction: # process subcommand help section msg = '\n' for subaction in action._get_subactions(): msg += self._format_action(subaction) return msg else: return super(CustomHelpFormatter, self)._format_action(action) def check(): print("status") return 0 parser = argparse.ArgumentParser(usage="sub <command>", add_help=False, formatter_class=CustomHelpFormatter) subparser = parser.add_subparsers(dest="cmd") subparser.add_parser('status', help='show status') subparser.add_parser('list', help='print list') # custom help messge parser._positionals.title = "commands" # hack to show help when no arguments supplied if len(sys.argv) == 1: parser.print_help() sys.exit(0) args = parser.parse_args() if args.cmd == 'list': print('list') elif args.cmd == 'status':
    • 977. 912 usage: sub <command> commands: status - showstatus list - print list Salida sin argumentos: sys.exit(check())
    • 978. 913 import sys from sys import exit raise RuntimeError("expected 3 command line arguments") f = open(sys.argv[1], 'rb') # Use first command line argument. start_line = int(sys.argv[2]) # All arguments come as strings,so need to be end_line = int(sys.argv[3]) # converted explicitly if other types are required. if len(sys.argv) != 4: # The script name needs to be accounted for as well. # The name of the executed script is at the beginning of the argv list. print('usage:', sys.argv[0], '<filename> <start> <end>') Capítulo 188: sys Introducción El módulo sys proporciona acceso a funciones y valores relacionados con el entorno de ejecución del programa, como los parámetros de la línea de comando en sys.argv o la función sys.exit() para finalizar el proceso actual desde cualquier punto del flujo del programa. Aunque está bien separado en un módulo, en realidad está incorporado y, como tal, siempre estará disponible en circunstancias normales. Sintaxis • Importe el módulo sys y haga que esté disponible en el espacio de nombres actual: • Importe una función específica del módulo sys directamente al espacio de nombres actual: Observaciones Para obtener detalles sobre todos los miembros del módulo sys , consulte la documentación oficial . Examples Argumentos de línea de comando Tenga en cuenta que en programas más grandes y más pulidos, usaría módulos como hacer clic para manejar los argumentos de la línea de comandos en lugar de hacerlo usted mismo. Nombre del script
    • 979. 914 # Error messages should not go to standard output, if possible. print('ERROR: We have no cheese at all.', file=sys.stderr) try: f = open('nonexistent-file.xyz', 'rb') except OSError as e: print(e, file=sys.stderr) process_data() sys.exit(1) # use an exit code to signal the program was unsuccessful def main(): if len(sys.argv) != 4 or '--help' in sys.argv[1:]: print('usage: my_program <arg1> <arg2> <arg3>',file=sys.stderr) Flujo de error estándar Finalización prematura del proceso y devolución de un código de salida. # You can use it to generate the path prefix of the executed program # (as opposed to the current module) to access files relative to that, # which would be good for assets of a game, for instance. program_file = sys.argv[0] import pathlib program_path = pathlib.Path(program_file).resolve().parent
    • 980. 915 import tempfile with tempfile.NamedTemporaryFile(delete=False) as t: t.write('Hello World!') path = t.name print path with open(path) as t: print t.read() /tmp/tmp6pireJ Hello World! Capítulo 189: tempfile NamedTemporaryFile Parámetros param descripción modo Modo para abrir archivo, por defecto = w + b borrar Para borrar el archivo al cierre, por defecto = Verdadero sufijo sufijo de nombre de archivo, por defecto = '' prefijo prefijo de nombre de archivo, por defecto = 'tmp' dir dirname para colocar tempfile, default = None buffsize por defecto = -1, (se usa por defecto el sistema operativo) Examples Cree (y escriba en) un archivo temporal persistente conocido Puedecrear archivos temporalesque tengan unnombre visibleen el sistemade archivosal que se puede acceder a través de la propiedad del name .El archivo se puede configurar en sistemas Unix para que se elimine en el cierre (establecido por delete param, el valor predeterminado es True) o se puede volver a abrir mástarde. Lo siguiente creará y abrirá un archivo temporal nombrado y escribirá '¡Hola mundo!' a ese archivo. Se puede acceder a la path de archivo del archivo temporal a través del name , en este ejemplo, se guarda en la path variable y se imprime para el usuario. El archivo se vuelve a abrir después de cerrar el archivo y el contenido del archivo temporal se lee e imprime para el usuario. Salida:
    • 981. 916
    • 982. 917 import typing T = typing.TypeVar("T") def get_first_element(l: typing.Sequence[T]) -> T: """Gets the first element of a sequence.""" return l[0] def two_sum(a, b): return a + b Capítulo 190: Tipo de sugerencias Sintaxis • typing.Callable [[int, str], None] -> def func (a: int, b: str) -> None • escribiendo.Mapping [str, int] -> {"a": 1, "b": 2, "c": 3} • escribiendo.Lista [int] -> [1, 2, 3] • escribiendo.configurar [int] -> {1, 2, 3} • escribiendo.Opcional [int] -> Ninguno o int • escribiendo.Secuencia [int] -> [1, 2, 3] o (1, 2, 3) • escribiendo.cualquier -> cualquier tipo • escribiendo.Union [int, str] -> 1 o "1" • T = escribiendo.TypeVar ('T') -> Tipo genérico Observaciones La sugerencia de tipo, tal como se especifica en PEP 484 , es una solución formalizada para indicar de forma estática el tipo de valor para el Código Python. Al aparecer junto al módulo de typing , las sugerencias de tipo ofrecen a los usuarios de Python la capacidad de anotar su código, ayudando así a los verificadores de tipos, mientras que, de forma indirecta, documentan su código con más información. Examples Tipos genéricos El typing.TypeVar es una fábrica de tipo genérico. Su objetivo principal es servir como parámetro / marcador de posición para las anotaciones genéricas de función / clase / método: Añadiendo tipos a una función Tomemos un ejemplo de una función que recibe dos argumentos y devuelve un valor que indica su suma:
    • 983. 918 print(two_sum(2, 1)) # result: 3 print(two_sum("a", "b")) # result: "ab" def two_sum(a: int, b: int): return a + b def two_sum(a: str, b: str): return a + b def two_sum(a: int, b: int) -> int: return a + b two_sum. annotations Al observar este código, uno no puede indicar de forma segura y sin duda el tipo de argumentos para la función two_sum . Funciona tanto cuando se suministra con valores int : y con cuerdas: y con otros valores, como list s, tuple s etcétera. Debido a esta naturaleza dinámica de los tipos de python, donde muchos son aplicables para una operación determinada, cualquier verificador de tipo no podría afirmar razonablemente si una llamada para esta función debería permitirse o no. Para ayudar a nuestro verificador de tipos, ahora podemos proporcionarle sugerencias detipo en la definición de función que indica el tipo que permitimos. Para indicar que solo queremos permitirtipos int , podemos cambiar nuestra definición de función para que se vea así: Las anotaciones siguen al nombre del argumento y están separadas por un carácter : . De forma similar, para indicar que solo se permiten los tipos str ,cambiaríamos nuestra función para especificarlo: Ademásde especificarel tipo de los argumentos,también se podríaindicarel valor de retornode unallamada defunción.Estosehaceagregandoel carácter-> seguidodeltipodespués del paréntesisde cierreenlalista de argumentos pero antes de:alfinal dela declaración dela función: Ahorahemos indicadoqueel valorderetornoalllamaratwo_sum debeserdetipoint .De manera similar, podemos definir valores apropiados para str ,float , list , set y otros. Aunque las sugerencias de tipo son utilizadas principalmente por los verificadores de tipo y los IDE, a veces es posible que necesite recuperarlos. Esto se puede hacer usando el annotations especial annotations :
    • 984. 919 class A: x = None # type: float def init (self, x: float) -> None: """ self should not be annotated init should be annotated to return None """ self.x = x @classmethod def from_int(cls, x: int) -> 'A': """ cls should not be annotated Use forward reference to refer to current class with string literal 'A' """ return cls(float(x)) x = 3 # type: int x = negate(x) x = 'a type-checker might catch this error' x: int = 3 y: int class Foo: x: int y: str = 'abc' Miembros de la clase y métodos La referencia hacia adelante de la clase actual es necesaria ya que las anotaciones se evalúan cuando se define la función. Las referencias directas también se pueden usar cuando se hace referencia a una clase que causaría una importación circular si se importara. Variables y atributos Las variables son anotadas usando comentarios: Python 3.x 3.6 A partir de Python 3.6, también hay una nueva sintaxis para las anotaciones de variables . El código de arriba podría usar el formulario A diferencia de los comentarios, también es posible simplemente agregar una sugerencia de tipo a una variable que no se declaró anteriormente, sin establecer un valor para ella: Además, si se utilizan en el módulo o en el nivel de clase, las sugerencias de tipo se pueden recuperar utilizando typing.get_type_hints(class_or_module) : # {'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>}
    • 985. 920 x: int print( annotations ) # {'x': <class 'int'>} class C: s: str print(C. annotations ) # {'s': <class 'str'>} import typing Point = typing.NamedTuple('Point', [('x', int), ('y', int)]) def hello_world(greeting: str = 'Hello'): print(greeting + 'world!') Alternativamente, se puede acceder a ellos usando el atributo o variable especial annotations : NamedTuple La creación de una doble con nombre con sugerencias de tipo se realiza utilizando la función NamedTuple del módulo de typing : Tenga en cuenta que el nombre del tipo resultante es el primer argumento de la función, pero debe asignarse a una variable con el mismo nombre para facilitar el trabajo de los verificadores de tipos. Escriba sugerencias para argumentos de palabras clave Tenga en cuenta los espacios alrededor del signo igual en contraposición a la forma en que se suelen diseñar los argumentos de palabras clave. print(typing.get_type_hints(Foo)) # ChainMap({'x': <class 'int'>, 'y': <class 'str'>}, {})
    • 986. 921 float_num = 10.2 #float value complex_num = 3.14j #complex value long_num = 1234567L #long value int_num = 10 #int value a_str = 'Hello World' print(a_str) #output will be whole string. Hello World print(a_str[0]) #output will be first character. H print(a_str[0:5]) #output will be first five characters. Hello print(list) #will ouput whole list. [123,'abcd',10.2,'d'] print(list[0:2]) #will output first two element of list. [123,'abcd'] print(list1 * 2) #will gave list1 two times. ['hello','world','hello','world'] print(list + list1) #willgaveconcatenationofboththelists. [123,'abcd',10.2,'d','hello','world'] list = [123,'abcd',10.2,'d'] #can be a array of any data type or single data type. list1 = ['hello','world'] Capítulo 191: Tipos de datos de Python Introducción Los tipos de datos no son más que variables que utilizaste para reservar algo de espacio en la memoria. Las variables de Python no necesitan una declaración explícita para reservar espacio de memoria. La declaración ocurre automáticamente cuando asignas un valor a una variable. Examples Tipo de datos numeros Los números tienen cuatro tipos en Python. Int, flotador, complejo, y largo. Tipo de datos de cadena Las cadenas se identifican como un conjunto contiguo de caracteres representados en las comillas. Python permite pares de comillas simples o dobles. Las cadenas son tipos de datos de secuencia inmutables, es decir, cada vez que se realizan cambios en una cadena, se crea un objeto de cadena completamente nuevo. Tipo de datos de lista Una lista contiene elementos separados por comas y encerrados entre corchetes []. Las listas son casi similares a las matrices en C. Una diferencia es que todos los elementos que pertenecen a una lista pueden ser de diferentes tipos de datos. Tipo de datos de la tupla
    • 987. 922 tuple = (123,'hello') tuple1 = ('world') print(tuple) #will output whole tuple. (123,'hello') print(tuple[0]) #will output first value. (123) print(tuple + tuple1)#will output (123,'hello','world') tuple[1]='update' #this will give you error. print(dic['name']) #will output only value with 'name' key. 'red' print(dic.values()) #will output list of values in dic. ['red',10] print(dic.keys()) #will output list of keys. ['name','age'] print(dic) #will output all the key-value pairs. {'name':'red','age':10} dic={'name':'red','age':10} basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} print(basket) # duplicates will beremoved > {'orange', 'banana', 'pear', 'apple'} a = set('abracadabra') print(a) # unique letters in a > {'a', 'r', 'b', 'c', 'd'} a.add('z') print(a) > {'a', 'c', 'r', 'b', 'z', 'd'} b = frozenset('asdfagsa') print(b) > frozenset({'f', 'g', 'd', 'a', 's'}) cities = frozenset(["Frankfurt", "Basel","Freiburg"]) print(cities) > frozenset({'Frankfurt', 'Basel', 'Freiburg'}) Las listas están entre paréntesis [] y sus elementos y tamaño pueden cambiarse, mientras que las tuplas están entre paréntesis () y no se pueden actualizar. Las tuplas son inmutables. Tipo de datos del diccionario El diccionario consta de pares clave-valor. Está encerrado entre llaves {} y los valores se pueden asignar y acceder mediante corchetes []. Establecer tipos de datos Los conjuntos son colecciones desordenadas de objetos únicos, hay dos tipos de conjuntos: 1. Conjuntos: son mutables y se pueden agregar nuevos elementos una vez que se definen los conjuntos 2. Conjuntos congelados: son inmutables y no se pueden agregar nuevos elementos después de su definición.
    • 988. 923 foo = "bar" foo[0] = "c" # Error foo = ("bar", 1, "Hello!",) foo[1] = 2 # ERROR!! foo = frozenset(["bar", 1, "Hello!"]) foo[2] = 7 #ERROR foo.add(3) # ERROR Capítulo 192: Tipos de datos inmutables (int, float, str, tuple y frozensets) Examples Los caracteres individuales de las cadenas no son asignables El valor de la variable inmutable no se puede cambiar una vez que se crean. Los miembros individuales de Tuple no son asignables La segunda línea devolvería un error ya que los miembros de la tupla una vez creados no son asignables. Debido a la inmutabilidad de la tupla. Los Frozenset son inmutables y no asignables. La segunda línea devolvería un error ya que los miembros de frozenset una vez creados no son asignables. La tercera línea devolvería el error, ya que los frozensets no admiten funciones que puedan manipular a los miembros.
    • 989. 924 from Tkinter import * # Capitalized from tkinter import * # Lowercase try: from Tkinter import * except ImportError: from tkinter import * from sys import version_info if version_info.major == 2: from Tkinter import * elif version_info.major == 3: from tkinter import * Capítulo 193: tkinter Introducción Lanzado en Tkinter es la biblioteca GUI (interfaz gráfica de usuario) más popular de Python. Este tema explica el uso adecuado de esta biblioteca y sus características. Observaciones La capitalización del módulo tkinter es diferente entre Python 2 y 3. Para Python 2 use lo siguiente: Para Python 3 usa lo siguiente: Para el código que funciona con Python 2 y 3, puede hacer o Ver la Documentación tkinter para más detalles. Examples Una aplicación tkinter mínima tkinter es un kit de herramientas de GUI que proporciona un envoltorio alrededor de la biblioteca de GUI de Tk / Tcl y se incluye con Python. El siguiente código crea una nueva ventana usando tkinter y coloca algún texto en el cuerpo de la ventana. Nota: En Python 2, el uso de mayúsculas puede ser ligeramente diferente, consulte la sección de Comentarios a continuación.
    • 990. 925 Gerentes de geometría Tkinter tiene tres mecanismos para la gestión de la geometría: place , pack y grid . El place gestor utiliza coordenadas absolutas de píxeles. El gestor de pack coloca los widgets en uno de los 4 lados. Los nuevos widgets se colocan al lado de los widgets existentes. El administrador de grid coloca los widgets en una cuadrícula similar a una hoja de cálculo de cambio de tamaño dinámico. Lugar Los argumentos de palabras clave más comunes para widget.place son los siguientes: • x , la coordenada x absoluta del widget • y , la coordenada y absoluta del widget • height , la altura absoluta delwidget • width ,elanchoabsoluto del widget Un ejemplo de código usando place : class PlaceExample(Frame): def init (self,master): Frame. init(self,master) self.grid() top_text=Label(master,text="This is on top at the origin") import tkinter as tk # GUI window is a subclass of the basic tkinter Frame object class HelloWorldFrame(tk.Frame): def init (self, master): # Call superclass constructor tk.Frame. init (self, master) # Place frame into main window self.grid() # Create text box with "Hello World" text hello = tk.Label(self, text="Hello World! This label can hold strings!") # Place text box into frame hello.grid(row=0, column=0) # Spawn window if name == " main ": # Create main window object root = tk.Tk() # Set title of window root.title("Hello World!") # Instantiate HelloWorldFrame object hello_frame = HelloWorldFrame(root) # Start GUI hello_frame.mainloop()
    • 991. 926 from tkinter import * class GridExample(Frame): def init (self,master): Frame. init(self,master) self.grid() top_text=Label(self,text="This text appears on top left") top_text.grid() # Default position 0, 0 bottom_text=Label(self,text="This text appears on bottom left") bottom_text.grid() # Default position 1, 0 right_text=Label(self,text="This text appears on the right and spans both rows", wraplength=100) # Position is 0,1 Paquete widget.pack puede tomar los siguientes argumentos de palabras clave: • expand , ya sea para llenar o no el espacio dejado por elpadre • fill,sideseaexpandirparallenartodoelespacio(NINGUNO(predeterminado),X,Yo AMBOS) • side , el lado contra el que empacar (TOP (predeterminado), ABAJO, IZQUIERDO o DERECHO) Cuadrícula Los argumentos de palabras clave más utilizados de widget.grid son los siguientes: • row , la fila del widget (por defecto el más pequeño desocupado) • rowspan , el número de columnas que un widget abarca (valor predeterminado 1) • column , la columna del widget (por defecto 0) • columnspan , el número de columnas que abarca un widget (por defecto1) • sticky , dónde colocar el widget si la celda de la cuadrícula es más grande que él (combinación de N, NE, E, SE, S, SW, W, NW) Las filas y columnas están indexadas a cero. Las filas aumentan bajando y las columnas aumentan yendo a la derecha. Un ejemplo de código usando grid : #top_text.pack() top_text.place(x=0,y=0,height=50,width=200) bottom_right_text=Label(master,text="This is at position 200,400") #top_text.pack() bottom_right_text.place(x=200,y=400,height=50,width=200) # Spawn Window if name ==" main ": root=Tk() place_frame=PlaceExample(root) place_frame.mainloop()
    • 992. 927 ¡Nunca mezcle el pack y la griddentro del mismo marco! ¡Al hacerlo se producirá un interbloqueo en la aplicación! # Rowspan means actual position is [0-1],1 right_text.grid(row=0,column=1,rowspan=2) # Spawn Window if name ==" main ": root=Tk() grid_frame=GridExample(root) grid_frame.mainloop()
    • 993. 928 Capítulo 194: Trabajando alrededor del bloqueo global de intérpretes (GIL) Observaciones ¿Por qué hay un GIL? El GIL ha existido en CPython desde el inicio de los hilos de Python, en 1992. Está diseñado para garantizar la seguridad de los hilos al ejecutar el código de Python. Los intérpretes de Python escritos con un GIL impiden que varios subprocesos nativos ejecuten códigos de byte de Python a la vez. Esto facilita que los complementos se aseguren de que su código sea seguro para subprocesos: simplemente bloquee la GIL, y solo su subproceso activo puede ejecutarse, por lo que su código es automáticamente seguro para subprocesos. Versión corta: la GIL garantiza que no importa cuántos procesadores y subprocesos tenga, solo se ejecutará un subproceso de un intérprete de Python al mismo tiempo. Esto tiene muchos beneficios de facilidad de uso, pero también tiene muchos beneficios negativos. Tenga en cuenta que un GIL no es un requisito del lenguaje Python. Por consiguiente, no puede acceder a la GIL directamente desde el código estándar de Python. No todas las implementaciones de Python utilizan un GIL. Intérpretes que tienen un GIL: CPython, PyPy, Cython (pero puede desactivar el GIL con nogil ) Intérpretes que no tienen un GIL: Jython, IronPython Detalles sobre cómo funciona el GIL: Cuando se está ejecutando un hilo, bloquea la GIL. Cuando un hilo quiere ejecutarse, solicita el GIL y espera hasta que esté disponible. En CPython, antes de la versión 3.2, el hilo en ejecución verificaba después de un cierto número de instrucciones de Python para ver si otro código quería el bloqueo (es decir, liberó el bloqueo y luego lo solicitó nuevamente). Este método tendía a provocar la hambruna de hilos, en gran parte porque el hilo que liberaba el bloqueo lo volvería a adquirir antes de que los hilos en espera tuvieran la oportunidad de despertarse. Desde la versión 3.2, los subprocesos que desean que el GIL espere el bloqueo por algún tiempo, y después de ese tiempo, establecen una variable compartida que obliga al hilo en ejecución a ceder. Sin embargo, esto todavía puede resultar en tiempos de ejecución drásticamente más largos. Consulte los siguientes enlaces en dabeaz.com (en la sección de referencias) para obtener más detalles. CPython libera automáticamente la GIL cuando un hilo realiza una operación de E / S. Las
    • 994. 929 bibliotecas de procesamiento de imágenes y las operaciones de procesamiento de números numpy liberan la GIL antes de realizar su procesamiento. Beneficios de la GIL Para los intérpretes que usan la GIL, la GIL es sistémica. Se utiliza para preservar el estado de la aplicación. Beneficios incluidos: • Recolección de basura: los recuentos de referencia seguros para subprocesos deben modificarse mientras la GIL está bloqueada. En CPython, toda la colección de garbarge está vinculada a la GIL. Este es un grande; vea el artículo de la wiki de python.org sobre la GIL (que se encuentra en las Referencias, a continuación) para obtener detalles sobre lo que aún debe ser funcional si se desea eliminar la GIL. • Facilidad para los programadores que tratan con GIL: bloquear todo es simplista, pero fácil de codificar • Facilita la importación de módulos desde otros idiomas. Consecuencias de la GIL La GIL solo permite que un hilo ejecute el código de Python a la vez dentro del intérprete de python. Esto significa que el multihilo de procesos que ejecutan código de Python estricto simplemente no funciona. Al usar subprocesos contra GIL, es probable que tenga un peor rendimiento con los subprocesos que si se ejecutara en un solo subproceso. Referencias: https://wiki.python.org/moin/GlobalInterpreterLock - resumen rápido de lo que hace, detalles finos sobre todos los beneficios http://programmers.stackexchange.com/questions/186889/why-was-python-written-with-the-gil - resumen claramente escrito http://www.dabeaz.com/python/UnderstandingGIL.pdf : cómo funciona GIL y por qué se ralentiza en varios núcleos http://www.dabeaz.com/GIL/gilvis/index.html : visualización de los datos que muestran cómo GIL bloquea los subprocesos http://jeffknupp.com/blog/2012/03/31/pythons-hardest-problem/ - fácil de entender la historia del problema GIL https://jeffknupp.com/blog/2013/06/30/pythons-hardest-problem-revisited/ - detalles sobre las formas de solucionar las limitaciones de la GIL
    • 995. 930 from threading import Thread import time def countdown(n): while n > 0: n -= 1 COUNT = 10000000 t1 = Thread(target=countdown,args=(COUNT/2,)) t2 = Thread(target=countdown,args=(COUNT/2,)) start = time.time() t1.start();t2.start() t1.join();t2.join() end = time.time() print end-start import multiprocessing import time def countdown(n): while n > 0: n -= 1 COUNT = 10000000 start = time.time() with multiprocessing.Pool as pool: pool.map(countdown, [COUNT/2, COUNT/2]) pool.close() pool.join() end = time.time() print(end-start) Examples Multiprocesamiento.Pool La respuesta simple, cuando se pregunta cómo usar hilos en Python es: "No. Utilice procesos, en su lugar". El módulo de multiprocesamiento le permite crear procesos con una sintaxis similar a la creación de subprocesos, pero prefiero usar su conveniente objeto Pool. Usando el código que David Beazley utilizó por primera vez para mostrar los peligros de los hilos en contra de la GIL , lo reescribiremos usando multiprocesamiento . Código de David Beazley que mostraba problemas de subprocesos de GIL Reescrita utilizando multiproceso. En lugar de crear hilos, esto crea nuevos procesos. Dado que cada proceso es su propio
    • 996. 931 from threading import Thread import time def countdown(n): while n > 0: n -= 1 COUNT = 10000000 t1 = Thread(target=countdown,args=(COUNT/2,)) t2 = Thread(target=countdown,args=(COUNT/2,)) start = time.time() t1.start();t2.start() t1.join();t2.join() end = time.time() print end-start from threading import Thread import time def countdown(n): while n > 0: n -= 1 COUNT = 10000000 intérprete, no hay colisiones de GIL. multiprocessing.Pool abrirá tantos procesos como núcleos haya en la máquina, aunque en el ejemplo anterior solo necesitaría dos. En un escenario del mundo real, desea diseñar su lista para que tenga al menos la misma longitud que procesadores en su máquina. El Pool ejecutará la función que le indica que ejecute con cada argumento, hasta el número de procesos que cree. Cuando la función finalice, cualquier función restante en la lista se ejecutará en ese proceso. Descubrí que, incluso utilizando la instrucción with , si no cierra y se une al grupo, los procesos continúan existiendo. Para limpiar recursos, siempre cierro y me uno a mis piscinas. Cython Nogil: Cython es un intérprete alternativo de python. Utiliza el GIL, pero te permite deshabilitarlo. Ver su documentación Como ejemplo, usando el código que David Beazley usó por primera vez para mostrar los peligros de los hilos contra la GIL , lo reescribiremos usando nogil: Código de David Beazley que mostraba problemas de subprocesos de GIL Reescrito usando nogil (SOLO FUNCIONA EN CYTHON):
    • 997. 932 Es así de simple, siempre y cuando estés usando cython. Tenga en cuenta que la documentación indica que debe asegurarse de no cambiar ningún objeto de Python: El código en el cuerpo de la declaración no debe manipular los objetos de Python de ninguna manera, y no debe llamar a nada que manipule los objetos de Python sin volver a adquirir la GIL. Cython actualmente no comprueba esto. with nogil: t1 = Thread(target=countdown,args=(COUNT/2,)) t2 = Thread(target=countdown,args=(COUNT/2,)) start = time.time() t1.start();t2.start() t1.join();t2.join() end = time.time() print end-start
    • 998. 933 import zipfile filename = 'zipfile.zip' zip = zipfile.ZipFile(filename) print(zip) # <zipfile.ZipFile object at 0x0000000002E51A90> zip.close() with zipfile.ZipFile(filename, 'r') as z: print(zip) # <zipfile.ZipFile object at 0x0000000002E51A90> Capítulo 195: Trabajando con archivos ZIP Sintaxis • importar archivo zip • clase zipfile. ZipFile ( archivo, modo = 'r', compresión = ZIP_STORED, allowZip64 = True ) Observaciones Si intenta abrir un archivo que no es un archivo ZIP, se zipfile.BadZipFile la excepción zipfile.BadZipFile . En Python 2.7, este fue escrito zipfile.BadZipfile , y este nombre antiguo se conserva junto con el nuevo en Python 3.2+ Examples Apertura de archivos zip Para comenzar, importe el módulo zipfile y establezca el nombre del archivo. Trabajar con archivos zip es muy similar a trabajar con archivos , usted crea el objeto abriendo el archivo zip, que le permite trabajar en él antes de cerrar el archivo nuevamente. EnPython 2.7 y enPython 3 versiones superiores a 3.2, podemos usar el administrador de contexto with .Abrimos el archivo en modo "leer", y luego imprimimos una lista de nombres de archivos: Examinando los contenidos de Zipfile Hay algunas formas de inspeccionar el contenido de un archivo zip. Se puede utilizar el printdir que acaba de obtener una variedad de información que se envía a stdout
    • 999. 934 with zipfile.ZipFile(filename) as zip: zip.printdir() with zipfile.ZipFile(filename) as zip: print(zip.namelist()) # Out: ['pyexpat.pyd', 'python.exe', 'python3.dll', 'python35.dll', ... etc...... ] with zipfile.ZipFile(filename) as zip: info = zip.infolist() print(zip[0].filename) print(zip[0].date_time) print(info[0].file_size) # Out: pyexpat.pyd # Out: (2016, 6, 25, 22, 13, 34) # Out: 157336 import zipfile with zipfile.ZipFile('zipfile.zip','r') as zfile: zfile.extractall('path') import zipfile f=open('zipfile.zip','rb') zfile=zipfile.ZipFile(f) forcontinzfile.namelist(): zfile.extract(cont,path) # # Out: File Name Modified Size # pyexpat.pyd 2016-06-25 22:13:34 157336 # python.exe 2016-06-25 22:13:34 39576 # python3.dll 2016-06-25 22:13:34 51864 # python35.dll 2016-06-25 22:13:34 3127960 # etc. También podemos obtener una lista de nombres de archivo con la namelist método. Aquí, simplemente imprimimos la lista: En lugar de namelist de namelist , podemos llamar al método infolist , que devuelve una lista de objetosZipInfo,quecontieneninformaciónadicionalsobrecadaarchivo,porejemplo,unamarca de tiempo y el tamaño delarchivo: Extraer el contenido del archivo zip a un directorio. Extraer todo el contenido de un archivo zip Si desea extraer un solo archivo, use el método de extracción, toma la lista de nombres y la ruta como parámetro de entrada Creando nuevos archivos
    • 1000. 935 import zipfile new_arch=zipfile.ZipFile("filename.zip",mode="w") new_arch.write('filename.txt','filename_in_archive.txt') #first parameter is filename and second parameter is filename in archive by default filename will taken if not provided new_arch.close() str_bytes="string buffer" new_arch.writestr('filename_string_in_archive.txt',str_bytes) new_arch.close() Para crear un nuevo archivo, abra el archivo zip con el modo de escritura. Para agregar archivos a este archivo use el método write (). Si desea escribir una cadena de bytes en el archivo, puede usar el método writestr ().
    • 1001. 936 plt.plot(x, y) plt.show() # sine function # Plotting tutorials in Python # Launching a simple plot import numpy as np import matplotlib.pyplot as plt # angle varying between 0 and 2*pi x = np.linspace(0, 2.0*np.pi, 101) y = np.sin(x) Capítulo 196: Trazado con matplotlib Introducción Matplotlib ( https://matplotlib.org/) es una biblioteca para el trazado 2D basada en NumPy. Aquí hay algunos ejemplos básicos. Se pueden encontrar más ejemplos en la documentación oficial ( https://matplotlib.org/2.0.2/gallery.html y https://matplotlib.org/2.0.2/examples/index.html) , así como en http: //www.levcode.com/topic/881 Examples Una parcela simple en Matplotlib Este ejemplo ilustra cómo crear una curva sinusoidal simple utilizando Matplotlib
    • 1002. 937 # Plotting tutorials in Python # Enhancing a plot import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2.0*np.pi, 101) y = np.sin(x) # values for making ticks in x and y axis xnumbers = np.linspace(0, 7, 15) ynumbers = np.linspace(-1, 1, 11) plt.plot(x, y, color='r', label='sin') # r - red colour plt.xlabel("Angle in Radians") plt.ylabel("Magnitude") plt.title("Plot of some trigonometric functions") plt.xticks(xnumbers) plt.yticks(ynumbers) plt.legend() plt.grid() plt.axis([0, 6.5, -1.1, 1.1]) # [xstart, xend, ystart, yend] Agregar más características a un gráfico simple: etiquetas de eje, título, marcas de eje, cuadrícula y leyenda En este ejemplo, tomamos una gráfica de curva sinusoidal y le agregamos más características; a saber, el título, etiquetas de eje, título, marcas de eje, cuadrícula y leyenda.
    • 1003. 938 # Plotting tutorials in Python # Adding Multiple plots by superimposition # Good for plots sharing similar x, y limits # Using single plot command and legend import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2.0*np.pi, 101) y = np.sin(x) z = np.cos(x) # values for making ticks in x and y axis xnumbers = np.linspace(0, 7, 15) ynumbers = np.linspace(-1, 1, 11) plt.plot(x, y, 'r', x, z, 'g') # r, g - red, green colour plt.xlabel("Angle in Radians") plt.ylabel("Magnitude") Haciendo múltiples parcelas en la misma figura por superposición similar a MATLAB En este ejemplo, una curva sinusoidal y una curva de coseno se trazan en la misma figura mediante la superposición de los gráficos uno encima del otro. plt.show()
    • 1004. 939 # Plotting tutorials in Python # Adding Multiple plots by superimposition # Good for plots sharing similar x, y limits # Using multiple plot commands # Much better and preferred than previous import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2.0*np.pi, 101) y = np.sin(x) z = np.cos(x) Realización de varios gráficos en la misma figura utilizando la superposición de gráficos con comandos de gráficos separados Al igual que en el ejemplo anterior, aquí, una curva senoidal y una curva coseno se trazan en la misma figura utilizando comandos de trazado separados. Esto es más Pythonic y se puede usar para obtener identificadores separados para cada gráfico. plt.title("Plot of some trigonometric functions") plt.xticks(xnumbers) plt.yticks(ynumbers) plt.legend(['sine', 'cosine']) plt.grid() plt.axis([0, 6.5, -1.1, 1.1]) # [xstart, xend, ystart, yend] plt.show()
    • 1005. 940 # Plotting tutorials in Python # Adding Multiple plots by twin x axis # Good for plots having different y axis range # Separate axes and figure objects Gráficos con eje X común pero eje Y diferente: usando twinx () En este ejemplo, trazaremos una curva sinusoidal y una curva sinusoidal hiperbólica en la misma gráfica con un eje x común que tiene un eje y diferente. Esto se logra mediante el uso del comando twinx () . # values for making ticks in x and y axis xnumbers = np.linspace(0, 7, 15) ynumbers = np.linspace(-1, 1, 11) plt.plot(x, y, color='r', label='sin') # r - red colour plt.plot(x, z, color='g', label='cos') # g - green colour plt.xlabel("Angle in Radians") plt.ylabel("Magnitude") plt.title("Plot of some trigonometric functions") plt.xticks(xnumbers) plt.yticks(ynumbers) plt.legend() plt.grid() plt.axis([0, 6.5, -1.1, 1.1]) # [xstart, xend, ystart, yend] plt.show()
    • 1006. 941 # replicate axes object and plot curves # use axes to set attributes # Note: # Grid for second curve unsuccessful : let me know if you find it! :( import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2.0*np.pi, 101) y = np.sin(x) z = np.sinh(x) # separate the figure object and axes object # from the plotting object fig, ax1 = plt.subplots() # Duplicate the axes with a different y axis # and the same x axis ax2 = ax1.twinx() # ax2 and ax1 will have common x axis and different y axis # plot the curves on axes 1, and 2, and get the curve handles curve1, = ax1.plot(x, y, label="sin", color='r') curve2, = ax2.plot(x, z, label="sinh", color='b') # Make a curves list to access the parameters in the curves curves = [curve1, curve2] # add legend via axes 1 or axes 2 object. # one command is usuallysufficient # ax1.legend() # will not display the legend of ax2 # ax2.legend() # will not display the legend of ax1 ax1.legend(curves, [curve.get_label() for curve in curves]) # ax2.legend(curves, [curve.get_label() for curve in curves]) # also valid # Global figure properties plt.title("Plot of sine and hyperbolic sine") plt.show()
    • 1007. 942 # Plotting tutorials in Python # Adding Multiple plots by twin y axis # Good for plots having different x axis range # Separate axes and figure objects # replicate axes object and plot curves # use axes to set attributes import numpy as np import matplotlib.pyplot as plt y = np.linspace(0, 2.0*np.pi, 101) x1 = np.sin(y) x2 = np.sinh(y) # values for making ticks in x and y axis ynumbers = np.linspace(0, 7, 15) xnumbers1 = np.linspace(-1, 1, 11) xnumbers2 = np.linspace(0, 300, 7) # separate the figure object and axes object # from the plotting object Gráficos con eje Y común y eje X diferente usando twiny () En este ejemplo, una gráfica con curvas que tienen un eje y común pero un eje x diferente se demuestra utilizando el método twiny () . Además, algunas características adicionales como el título, la leyenda, las etiquetas, las cuadrículas, las marcas de eje y los colores se agregan a la trama.
    • 1008. 943 fig, ax1 = plt.subplots() # Duplicate the axes with a different x axis # and the same y axis ax2 = ax1.twiny() # ax2 and ax1 will have common y axis and different x axis # plot the curves on axes 1, and 2, and get the axes handles curve1, = ax1.plot(x1, y, label="sin", color='r') curve2, = ax2.plot(x2, y, label="sinh", color='b') # Make a curves list to access the parameters in the curves curves = [curve1, curve2] # add legend via axes 1 or axes 2 object. # one command is usually sufficient # ax1.legend() # will not display the legend of ax2 # ax2.legend() # will not display the legend of ax1 # ax1.legend(curves, [curve.get_label() for curve in curves]) ax2.legend(curves, [curve.get_label() for curve in curves]) # also valid # x axis labels via the axes ax1.set_xlabel("Magnitude", color=curve1.get_color()) ax2.set_xlabel("Magnitude", color=curve2.get_color()) # y axis label via the axes ax1.set_ylabel("Angle/Value", color=curve1.get_color()) # ax2.set_ylabel("Magnitude", color=curve2.get_color()) # does not work # ax2 has no property control over y axis # y ticks - make them coloured as well ax1.tick_params(axis='y', colors=curve1.get_color()) # ax2.tick_params(axis='y', colors=curve2.get_color()) # does not work # ax2 has no property control over y axis # x axis ticks via the axes ax1.tick_params(axis='x', colors=curve1.get_color()) ax2.tick_params(axis='x', colors=curve2.get_color()) # set x ticks ax1.set_xticks(xnumbers1) ax2.set_xticks(xnumbers2) # set y ticks ax1.set_yticks(ynumbers) # ax2.set_yticks(ynumbers) # also works # Grids via axes 1 # use this if axes 1 is used to # define the properties of common x axis # ax1.grid(color=curve1.get_color()) # To make grids using axes 2 ax1.grid(color=curve2.get_color()) ax2.grid(color=curve2.get_color()) ax1.xaxis.grid(False) # Global figure properties plt.title("Plot of sine and hyperbolic sine") plt.show()
    • 1009. 944
    • 1010. 945 x = (1, 2, 3) x[0] # 1 x[1] # 2 x[2] # 3 x[3] # IndexError: tuple index out of range Capítulo 197: Tupla Introducción Una tupla es unalistainmutable de valores. Las tuplas son uno de los tipos de colección más simples y comunes de Python, y se pueden crear con el operador de coma ( value = 1, 2, 3 ). Sintaxis • (1, a, "hola") # a debe ser una variable • () # una tupla vacía • (1,) # una tupla de 1 elemento. (1) no es una tupla. • 1, 2, 3 # la tupla de 3 elementos (1, 2, 3) Observaciones Los paréntesis solo son necesarios para las tuplas vacías o cuando se usan en una llamada de función. Una tupla es una secuencia de valores. Los valores pueden ser de cualquier tipo, y están indexados por números enteros, por lo que en este aspecto las tuplas se parecen mucho a las listas. La diferencia importante es que las tuplas son inmutables y hashable, por lo que se pueden usar en conjuntos y mapas Examples Tuplas de indexación La indexación con números negativos comenzará desde el último elemento como -1: x[-1] # 3 x[-2] # 2 x[-3] # 1 x[-4] # IndexError: tuple index out of range Indexando una gama de elementos
    • 1011. 946 >>> t = (1, 4, 9) >>> t[0] = 2 Traceback (most recent call last): File "<stdin>", line 1, in<module> TypeError: 'tuple' object does not support item assignment >>> t = (1, 2) >>> q = t >>> t += (3, 4) >>> t (1, 2, 3, 4) >>> q (1, 2) >>> t = (1, 2, 3, [1, 2, 3]) (1, 2, 3, [1, 2, 3]) >>> t[3] += [4, 5] TypeError: 'tuple' object does not support item assignment >>> t (1, 2, 3, [1, 2, 3, 4, 5]) hash( (1, 2) ) # ok Las tuplas son inmutables Una de las principales diferencias entre las list y las tuple enPython es que las tuplas son inmutables, esdecir,no sepueden agregar o modificarelementos una vez que seinicializa la tupla. Por ejemplo: De manera similar, las tuplas no tienen los métodos .append y .extend como la list . Usar += es posible, pero cambia el enlace de la variable, y no la tupla en sí: Tenga cuidado al colocar objetos mutables, como lists, dentro de tuplas.Esto puede llevar a resultados muy confusos al cambiarlos. Por ejemplo: Ayude a poner de un error y cambiar el contenido de la lista dentro de la tupla: Puede usar el operador += para "agregar" a una tupla; esto funciona creando una nueva tupla con el nuevo elemento que "agregó" y asignándola a su variable actual; La tupla antigua no se cambia, pero se reemplaza! Esto evita la conversión hacia y desde una lista, pero esto es lento y es una mala práctica, especialmente si se va a agregar varias veces. Tuple son elementos sabios hashable y equiparables print(x[:-1]) # (1, 2) print(x[-1:]) # (3,) print(x[1:3]) # (2, 3)
    • 1012. 947 { (1, 2)} # ok { ([], {"hello"}) ) # not ok t = 'a', 'b', 'c', 'd', 'e' t = ('a', 'b', 'c', 'd', 'e') # <type 'tuple'> t0 = () type(t0) # <type 'tuple'> t1 = 'a', type(t1) # <type 'str'> t2 = ('a') type(t2) # <type 'tuple'> t2 = ('a',) type(t2) # PEP8-compliant # this notation is not recommended by PEP8 # this notation is not recommended by PEP8 t2 = ('a',) t2 = 'a', t2 = ('a', ) Por lo tanto, una tupla se puede poner dentro de un set o como una clave en un dict solo si cada uno de sus elementos puede. Tupla Sintácticamente, una tupla es una lista de valores separados por comas: Aunque no es necesario, es común encerrar las tuplas entre paréntesis: Crea una tupla vacía con paréntesis: Para crear una tupla con un solo elemento, debe incluir una coma final: Tenga en cuenta que un solo valor entre paréntesis no es una tupla: Para crear una tupla de singleton es necesario tener una coma al final. Tenga en cuenta que para las tuplas singleton se recomienda (vea PEP8 en comas al final ) usar paréntesis. Además, no hay espacios en blanco después de la coma final (ver PEP8 en espacios en blanco ) Otra forma de crear una tupla es la función integrada tuple . hash( ([], {"hello"}) # not ok, since lists and sets are not hashabe
    • 1013. 948 a = 1, 2, 3 # a is the tuple (1, 2, 3) a = (1, 2, 3) # a is the tuple (1, 2, 3) a = 1 # a is the value1 a = 1, # a is the tuple (1,) a = (1,) # a is the tuple (1,) a = (1) # a is the value 1 and not a tuple # unpacking AKA multiple assignment x, y, z = (1, 2, 3) # x == 1 # y == 2 # z == 3 a = 1, 2, 3, 4 _, x, y, _ = a # x == 2 # y == 3 t = tuple('lupins') print(t) t =tuple(range(3)) print(t) # ('l', 'u', 'p', 'i', 'n', 's') # (0, 1, 2) Estos ejemplos se basan en material del libro Think Python de Allen B. Downey . Embalaje y desembalaje de tuplas Las tuplas en Python son valores separados por comas. Los paréntesis que se incluyen para ingresar las tuplas son opcionales, por lo que las dos asignaciones y son equivalentes La asignación a = 1, 2, 3 también se denomina empaquetamiento porque reúne valores en una tupla. Tenga en cuenta que una tupla de un solo valor también es una tupla. Para decirle a Python que una variable es una tupla y no un solo valor, puedes usar una coma al final También se necesita una coma si usa paréntesis Para desempaquetar valores de una tupla y hacer múltiples asignaciones use El símbolo _ se puede usar como un nombre de variable desechable si solo se necesitan algunos elementos de una tupla, actuando como un marcador de posición: Tuplas de un solo elemento:
    • 1014. 949 first, *more, last = (1, 2, 3, 4, 5) # first ==1 # more == [2, 3, 4] # last == 5 colors = "red", "green", "blue" rev = colors[::-1] # rev: ("blue", "green", "red") colors = rev # colors: ("blue", "green", "red") rev = tuple(reversed(colors)) # rev: ("blue", "green", "red") colors = rev # colors: ("blue", "green", "red") tuple1 = ('a', 'b', 'c', 'd', 'e') tuple2 = ('1','2','3') tuple3 = ('a', 'b', 'c', 'd', 'e') En Python 3, una variable de destino con un prefijo * se puede usar como una variable de captura (ver Desempaquetando los iterables ): Python 3.x 3.0 Elementos de inversión Invertir elementos dentro de una tupla O usando reversa (invertida da un iterable que se convierte en una tupla): Funciones de tupla incorporadas Las tuplas soportan las siguientes funciones integradas Comparación Si los elementos son del mismo tipo, python realiza la comparación y devuelve el resultado. Si los elementos son de diferentes tipos, verifica si son números. • Si son números, realice la comparación. • Si cualquiera de los elementos es un número, se devuelve el otro elemento. • De lo contrario, los tipos se ordenan alfabéticamente. Si llegamos al final de una de las listas, la lista más larga es "más grande". Si ambas listas son iguales devuelve 0. x, = 1, # x is the value1 x = 1, # x is the tuple (1,)
    • 1015. 950 len(tuple1) Out: 5 max(tuple1) Out: 'e' max(tuple2) Out: '3' min(tuple1) Out: 'a' min(tuple2) Out: '1' list = [1,2,3,4,5] tuple(list) Out: (1, 2, 3, 4, 5) Longitud de la tupla La función len devuelve la longitud total de la tupla. Max de una tupla La función max devuelve el elemento de la tupla con el valor máximo Min de una tupla La función min devuelve el elemento de la tupla con el valor mínimo Convertir una lista en tupla La función integrada tuple convierte una lista en una tupla. cmp(tuple1, tuple2) Out: 1 cmp(tuple2, tuple1) Out: -1 cmp(tuple1, tuple3) Out: 0
    • 1016. 951 tuple1 + tuple2 Out: ('a', 'b', 'c', 'd', 'e', '1', '2', '3') Concatenación de tuplas Usa + para concatenar dos tuplas
    • 1017. 952 >>> u'□'.encode('utf-8') '\xf0\x9f\x90\x8d' >>> b'\xf0\x9f\x90\x8d'.decode('utf-8') u'\U0001f40d' Capítulo 198: Unicode Examples Codificación y decodificación. Codifique siempre de unicode a bytes. En esta dirección, puedes elegir la codificación . La otra forma es decodificar de bytes a unicode. En esta dirección, tienes que saber qué es la codificación .
    • 1018. 953 type("f") == type(u"f") # True, <class 'str'> type(b"f") # <class 'bytes'> type("f") == type(b"f") # True, <type 'str'> type(u"f") # <type 'unicode'> >>> "£13.55".encode('utf8') Capítulo 199: Unicode y bytes Sintaxis • str.encode (codificación, errores = 'estricto') • bytes.decode (codificación, errores = 'estricto') • abierto (nombre de archivo, modo, codificación = Ninguno) Parámetros Parámetro Detalles codificación La codificación a utilizar, por ejemplo, 'ascii' , 'utf8' , etc ... errores El modo de errores, por ejemplo, 'replace' parareemplazarlos caracteres incorrectosconsignosdeinterrogación,'ignore'paraignorarloscaracteres incorrectos, etc. Examples Lo esencial En Python 3, str es el tipo para cadenas habilitadas para Unicode, mientras que bytes es el tipo para secuencias de bytes sin procesar. En Python 2, una cadena casual era una secuencia de bytes sin procesar por defecto y la cadena Unicode era cada cadena con el prefijo "u". Unicode a bytes Las cadenas Unicode se pueden convertir a bytes con .encode(encoding) . Python 3
    • 1019. 954 >>> print type(u"£13.55".encode('utf8')) <type 'str'> >>> print u"£13.55".encode('utf8') SyntaxError:Non-ASCII character'\xc2' in... # with encoding set inside a file # -*- coding: utf-8 -*- >>> print u"£13.55".encode('utf8') ┬ú13.55 >>> "£13.55".encode('ascii') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode character '\xa3' in position 0: ordinal not in range(128) >>> b'\xc2\xa313.55'.decode('utf8') '£13.55' >>> b'\xc2\xa313.55'.decode('utf16') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/csaftoiu/csaftoiu-github/yahoo-groupsbackup/.virtualenv/bin/../lib/python3.5/encodings/utf_16.py", line 16, in decode return codecs.utf_16_decode(input, errors, True) UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x35 in position 6: truncated data Python 2 enpy2,lacodificacióndelaconsolapredeterminadaessys.getdefaultencoding() == 'ascii'yno utf-8comoenpy3,porlotanto,imprimirlacomoenelejemploanteriornoesdirectamente posible. Si la codificación no puede manejar la cadena, se genera un `UnicodeEncodeError`: Bytes a Unicode Los bytes se pueden convertir en cadenas Unicode con .decode(encoding) . ¡Una secuencia de bytes solo se puede convertir en una cadena Unicode a través de la codificación apropiada! Si la codificación no puede manejar la cadena, se UnicodeDecodeError un UnicodeDecodeError : b'\xc2\xa313.55' >>> "£13.55".encode('utf16') b'\xff\xfe\xa3\x001\x003\x00.\x005\x005\x00'
    • 1020. 955 >>> "£13.55".encode('ascii', errors='replace') b'?13.55' >>> "£13.55".encode('ascii', errors='ignore') b'13.55' >>> "£13.55".encode('ascii', errors='namereplace') b'\\N{POUND SIGN}13.55' >>> "£13.55".encode('ascii', errors='xmlcharrefreplace') b'&#163;13.55' >>> "£13.55".encode('ascii', errors='backslashreplace') b'\\xa313.55' >>> b = "£13.55".encode('utf8') >>> b.decode('ascii', errors='replace') '��13.55' >>> b.decode('ascii', errors='ignore') '13.55' >>> b.decode('ascii', errors='backslashreplace') '\\xc2\\xa313.55' open(fn, mode='r', encoding='utf16') # opens file for reading utf16 #ERROR: cannot write byteswhena string is expected: open("foo.txt", "w").write(b"foo") open(fn, mode='r') # opens file for reading in utf8 Codificación / decodificación de manejo de errores. .encode y .decode tienen modos de error. Elvalorpredeterminadoes'strict',quegeneraexcepcionesencasodeerror.Otrosmodosson más indulgentes. Codificación Descodificación Moral De lo anterior se desprende claramente que es vital mantener sus codificaciones rectas cuando se trata de unicode y bytes. Archivo I / O Losarchivosabiertos enunmodonobinario (por ejemplo,'r'o'w') tratancon cadenas. La codificación sordera es 'utf8' . Los archivos abiertos en modo binario (por ejemplo, 'rb' o 'wb' ) tratan con bytes. No se puede
    • 1021. 956 open(fn, mode='wb') # open file for writing bytes # ERROR: cannot write string when bytes is expected: open(fn, mode='wb').write("hi") especificar ningún argumento de codificación ya que no hay codificación.
    • 1022. 957 import urllib response = urllib.urlopen('http://stackoverflow.com/documentation/') print response.code # Prints: 200 print response.read() '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n\r\n<title>Documentation - Stack. etc' import urllib.request print(urllib.request.urlopen("http://stackoverflow.com/documentation/")) # Prints: <http.client.HTTPResponse at 0x7f37a97e3b00> response = urllib.request.urlopen("http://stackoverflow.com/documentation/") print(response.code) # Prints: 200 print(response.read()) # Prints: b'<!DOCTYPE html>\r\n<html>\r\n<head>\r\n\r\n<title>Documentation - Stack Overflow</title> Capítulo 200: urllib Examples HTTP GET Python 2.x 2.7 Python 2 Elusodeurllib.urlopen() devolveráunobjetoderespuesta,quesepuedemanejardemanera similar a un archivo. El response.code representa el valor de retorno de http. 200 está bien, 404 es NotFound, etc. response.read() y response.readlines() se pueden usar para leer el archivo html real devuelto por la solicitud. Estos métodos funcionan de manera similar a file.read* Python 3.x 3.0 Python 3 El módulo se ha actualizado para Python 3.x, pero los casos de uso siguen siendo básicamente los mismos. urllib.request.urlopen devolverá un objeto similar a un archivo similar.
    • 1023. 958 import urllib query_parms = {'username':'stackoverflow', 'password':'me.me'} encoded_parms = urllib.urlencode(query_parms) response = urllib.urlopen("https://stackoverflow.com/users/login", encoded_parms) response.code # Output: 200 response.read() # Output: '<!DOCTYPE html>\r\n<html>\r\n<head>\r\n\r\n<title>Log In - Stack Overflow' import urllib query_parms = {'username':'stackoverflow', 'password':'me.me'} encoded_parms = urllib.parse.urlencode(query_parms).encode('utf-8') response = urllib.request.urlopen("https://stackoverflow.com/users/login", encoded_parms) response.code # Output: 200 response.read() #Output: b'<!DOCTYPEhtml>\r\n<html> ....etc' import urllib.request response = urllib.request.urlopen("http://stackoverflow.com/") data = response.read() encoding = response.info().get_content_charset() html = data.decode(encoding) import urllib2 response = urllib2.urlopen("http://stackoverflow.com/") data = response.read() encoding = response.info().getencoding() POST HTTP Para POST, los datos pasan los argumentos de consulta codificados como datos a urlopen () Python 2.x 2.7 Python 2 Python 3.x 3.0 Python 3 Decodificar bytes recibidos de acuerdo a la codificación del tipo de contenido Los bytes recibidos deben decodificarse con la codificación de caracteres correcta para interpretarlos como texto: Python 3.x 3.0 Python 2.x 2.7
    • 1024. 959 html = data.decode(encoding)
    • 1025. 960 def func(params): for value in params: print ('Got value {}'.format(value)) if value == 1: # Returns from function as soon as value is 1 print (">>>> Got 1") return print ("Still looping") return "Couldn't find 1" func([5, 3, 1, 2, 8, 9]) Got value 5 Still looping Got value 3 Still looping Got value 1 >>>> Got 1 Capítulo 201: Usando bucles dentro de funciones Introducción En Python, la función se devolverá tan pronto como la ejecución llegue a la declaración de "retorno". Examples Declaración de retorno dentro del bucle en una función En este ejemplo, la función regresará tan pronto como el valor var tenga 1 salida
    • 1026. 961 Capítulo 202: Uso del módulo "pip": PyPI Package Manager Introducción A veces es posible que necesite usar el administrador de paquetes pip dentro de Python, por ejemplo. cuando algunas importaciones pueden aumentar ImportError y desea manejar la excepción. Si desembala en Windows Python_root/Scripts/pip.exe dentro del archivo main .py se almacena, donde se importa la clase main del paquete pip . Esto significa que el paquete pip se usa siempre que uses el ejecutable pip.Para el uso de pip como ejecutable, consulte: pip: PyPI Package Manager Sintaxis • pip. <function | attribute | class> donde function es uno de: ○ autocompletar () ○ Finalización de comandos y opciones para el analizador de opciones principal (y opciones) y sus subcomandos (y opciones). Habilite mediante la obtención de uno de los scripts de shell de finalización (bash, zsh o fish). ○ check_isolated (args) ○ param args {lista} ○ devuelve {booleano} ○ create_main_parser () ○ devuelve el objeto {pip.baseparser.ConfigOptionParser} ○ main (args = None) ○ param args {lista} ○ devuelve {entero} Si no falla, devuelve 0 ○ parseopts (args) ○ param args {lista} ○ get_installed_distributions () ○ devuelve {lista} ○ get_similar_commands (nombre) ○ Nombre del comando auto-correcto. ○ nombre de parámetro {cadena} ○ devuelve {booleano} ○ get_summaries (ordenado = Verdadero) ○ Rendimientos ordenados (nombre del comando, resumen del comando) tuplas. ○ get_prog () ○ devuelve {cadena} ○ dist_is_editable (dist) ○ ¿Es la distribución una instalación editable? ○ param dist {objeto} ○ devuelve {booleano}
    • 1027. 962 import pip command = 'install' parameter = 'selenium' second_param = 'numpy' # You can give as many package names as needed switch = '--upgrade' pip.main([command, parameter, second_param, switch]) import pip installed = pip.get_installed_distributions() list = [] for i in installed: list.append(i.key) pip.main(['install']+list+['--upgrade']) for i in installed: pip.main(['install']+i.key+['--upgrade']) if name == ' main ': try: import requests except ImportError: print("To use thismodule you need 'requests' module") t = input('Install requests? y/n: ') if t == 'y': import pip pip.main(['install', 'requests']) ○ comandos_dicto ○ Examples atributo {diccionario} Ejemplo de uso de comandos Solo los parámetros necesarios son obligatorios, por lo que tanto pip.main(['freeze']) como pip.main(['freeze', '', '']) son aceptables. Instalación por lotes Es posible pasar muchos nombres de paquetes en una llamada, pero si falla una instalación / actualización, todo el proceso de instalación se detiene y termina con el estado '1'. Si no desea detenerse cuando fallan algunas instalaciones, llame a la instalación en bucle. Manejo de la excepción de ImportError Cuando usa el archivo python como módulo, no es necesario verificar siempre si el paquete está instalado, pero sigue siendo útil para los scripts.
    • 1028. 963 Fuerza de instalación Muchos paquetes, por ejemplo, en la versión 3.4 se ejecutarán en 3.6 muy bien, pero si no hay distribuciones para una plataforma específica, no se pueden instalar, pero hay una solución alternativa. En la convención de nombres de los archivos .whl (conocidos como ruedas), decida si puede instalar el paquete en la plataforma especificada. P.ej. scikit_learn‑ 0.18.1‑ cp36‑ cp36m‑ win_amd64.whl [nombre_paquete] - [versión] - [intérprete de python] -[intérpretedepython]-[Sistemaoperativo].whl.Sisecambiaelnombredelarchivoderueda, para quelaplataforma coincida,pip intenta instalar el paquete incluso si la plataforma o la versión depythonnocoinciden.Eliminarlaplataformaoelintérpretedelnombregeneraráunerrorenla versión más reciente del módulo pip kjhfkjdf.whl is not a valid wheel filename. . Alternativamente, el archivo .whl se puede desempaquetar usando un archivador como 7-zip. - Por lo general, contiene la meta carpeta de distribución y la carpeta con archivos de origen.Estos archivos de origen se pueden desempaquetar simplemente en el directorio de site-packges menos que esta rueda contenga el script de instalación, de ser así, debe ejecutarse primero. import requests import os import sys pass else: import os import sys print('Some functionality can be unavailable.') else: import requests import os import sys
    • 1029. 964 def list_check(to_check, the_list): for item in the_list: if to_check == item: return True return False Capítulo 203: Velocidad de Python del programa. Examples Notación Idea básica La notación utilizada al describir la velocidad de su programa Python se llama notación Big-O. Digamos que tienes una función: Esta es una función simple para verificar si un elemento está en una lista. Para describir la complejidad de esta función, dirá O (n). Esto significa "Orden de n", ya que la función O se conoce como la función Orden. O (n): generalmente n es el número de elementos en el contenedor O (k): generalmente k es el valor del parámetro o el número de elementos en el parámetro Lista de operaciones Operaciones: Caso promedio (se supone que los parámetros se generan aleatoriamente) Anexo: O (1) Copia: O (n) Del slice: O (n) Eliminar elemento: O (n) Insertar: O (n) Obtener artículo: O (1) Elemento de ajuste: O (1) Iteración: O (n) Obtener rebanada: O (k)
    • 1030. 965 class Deque: def init (self): self.items = [] def isEmpty(self): return self.items == [] def addFront(self, item): self.items.append(item) def addRear(self, item): self.items.insert(0,item) def removeFront(self): return self.items.pop() def removeRear(self): return self.items.pop(0) def size(self): return len(self.items) Establecer rebanada: O (n + k) Extender: O (k) Ordenar: O (n log n) Multiplicar: O (nk) x en s: O (n) min (s), max (s): O (n) Obtener longitud: O (1) Operaciones de deque Un deque es una cola de doble final. Operaciones: Caso promedio (se supone que los parámetros se generan aleatoriamente) Anexo: O (1) Apéndice: O (1) Copia: O (n) Extender: O (k) Extendente: O (k) Pop: O (1) Personas: O (1)
    • 1031. 966 Eliminar: O (n) Girar: O (k) Establecer operaciones Operación: Caso promedio (asume parámetros generados aleatoriamente): Peor caso x en s: O (1) Diferencia s - t: O (len (s)) Intersección s & t: O (min (len (s), len (t))): O (len (s) * len (t) Intersección múltiple s1 & s2 & s3 & ... & sn:: (n-1) * O (l) donde l es max (len (s1), ..., len (sn)) s.difference_update (t): O (len (t)): O (len (t) * len (s)) ymetric_difference_update (t): O (len (t)) Diferencia simétrica s ^ t: O (len (s)): O (len (s) * len (t)) Unión s | t: O (len (s) + len (t)) Notaciones algorítmicas ... Hay ciertos principios que se aplican a la optimización en cualquier lenguaje de computadora, y Python no es una excepción. No optimice a medida que avanza : escriba su programa sin importar las posibles optimizaciones, concentrándose en asegurarse de que el código sea limpio, correcto y comprensible. Si es demasiado grande o demasiado lento cuando haya terminado, entonces puede considerar optimizarlo. Recuerde la regla 80/20 : en muchos campos puede obtener el 80% del resultado con el 20% del esfuerzo (también llamada regla 90/10 - depende de con quién hable). Cuando esté a punto de optimizar el código, use la creación de perfiles para averiguar a dónde va ese 80% del tiempo de ejecución, para que sepa dónde concentrar su esfuerzo. Ejecute siempre los puntos de referencia "antes" y "después" : ¿De qué otra manera sabrá que sus optimizaciones realmente hicieron una diferencia? Si su código optimizado resulta ser solo un poco más rápido o más pequeño que la versión original, deshaga los cambios y vuelva al código original y sin cifrar. Use los algoritmos y las estructuras de datos correctos: No use un algoritmo de clasificación de burbuja O (n2) para ordenar mil elementos cuando haya una ordenación rápida O (n log n) disponible. Del mismo modo, no almacene mil elementos en una matriz que requiera una búsqueda O (n) cuando podría usar un árbol binario O (log n) o una tabla hash O (1) de Python. Para más información, visite el siguiente enlace ... Python Speed Up Las siguientes 3 notaciones asintóticas se usan principalmente para representar la complejidad
    • 1032. 967 del tiempo de los algoritmos. 1. Θ Notación : la notación theta limita las funciones desde arriba y desde abajo, por lo que define el comportamiento asintótico exacto. Una forma sencilla de obtener la notación Theta de una expresión es eliminar los términos de orden inferior e ignorar las constantes iniciales. Por ejemplo, considere la siguiente expresión. 3n3 + 6n2 + 6000 = Θ (n3) La eliminación de los términos de orden inferior siempre está bien porque siempre habrá un n0, luego de lo cual Θ (n3) tiene valores más altos que Θn2) independientemente de las constantes involucradas. Para una función dada g (n), denotamos que Θ (g (n)) está siguiendo un conjunto de funciones. Θ (g (n)) = {f (n): existen constantes positivas c1, c2 y n0 tales que 0 <= c1 g (n) <= f (n) <= c2 g (n) para todo n> = n0} La definición anterior significa que si f (n) es theta de g (n), entonces el valor f (n) siempre está entre c1 g (n) y c2 g (n) para valores grandes de n (n> = n0). La definición de theta también requiere que f (n) no sea negativa para valores de n mayores que n0. 2. Notación Big O : La notación Big O define un límite superior de un algoritmo, limita una función solo desde arriba. Por ejemplo, considérese el caso de Insertion Sort. Lleva tiempo lineal en el mejor de los casos y el tiempo cuadrático en el peor de los casos. Podemos decir con seguridad que la complejidad temporal de la ordenación de inserción es O (n ^ 2). Tenga en cuenta que O (n ^ 2) también cubre el tiempo lineal. Si usamos la notación para representar la complejidad de tiempo de la ordenación por Inserción, tenemos que usar dos afirmaciones para el mejor y el peor de los casos: 1. La complejidad en el peor de los casos de Insertion Sort es Θ (n ^ 2). 2. El mejor caso de complejidad en el tiempo de Insertion Sort es Θ (n). La notación Big O es útil cuando solo tenemos un límite superior en la complejidad de tiempo de un algoritmo. Muchas veces encontramos fácilmente un límite superior simplemente mirando el algoritmo. O (g (n)) = {f (n): existen constantes positivas c y n0 tales que 0 <= f (n) <= cg (n) para todos n> = n0} 3. Ω Notación : al igual que la notación Big O proporciona un límite superior asintótico en una función, la notación provides proporciona un límite inferior asintótico. Ω La notación <puede ser útil cuando tenemos un límite inferior en la complejidad del tiempo de un algoritmo. Como se discutió en la publicación anterior, el mejor rendimiento de un algoritmo generalmente no es útil, la notación Omega es la notación menos utilizada entre las tres. Para una función dada g (n), denotamos por Ω (g (n)) el conjunto de funciones. Ω (g (n)) = {f (n): existen constantes positivas c y n0 tales que 0 <= cg (n) <= f (n) para todos n> = n0}. Consideremos el mismo ejemplo de orden de inserción aquí. La complejidad temporal de la clasificación de inserción se puede escribir como Ω (n), pero no es una información muy útil sobre la clasificación de inserción, ya que generalmente estamos interesados en el peor de los casos y, a veces, en el caso promedio.
    • 1033. 968 import matplotlib.pyplot as plt # Generate some data for plotting. x = [0, 1, 2, 3, 4, 5, 6] y = [i**2 for i in x] # Plot the data x, y with some keyword arguments that control the plot style. # Use two different plot commands to plot both points (scatter) and a line (plot). plt.scatter(x, y, c='blue', marker='x', s=100) # Create blue markers of shape "x" and size 100 plt.plot(x, y, color='red', linewidth=2) # Create a red line with linewidth 2. # Add some text to the axes and a title. plt.xlabel('x data') plt.ylabel('y data') plt.title('An example plot') # Generate the plot and show to the user. plt.show() Capítulo 204: Visualización de datos con Python Examples Matplotlib Matplotlib es una biblioteca de trazado matemático para Python que proporciona una variedad de funciones de trazado diferentes. La documentación de matplotlib se puede encontrar aquí , con los SO Docs disponibles aquí . Matplotlib proporciona dos métodos distintos para trazar, aunque son intercambiables en su mayor parte: • En primer lugar, matplotlib proporciona la interfaz pyplot , una interfaz directa y fácil de usar que permite trazar gráficos complejos en un estilo similar a MATLAB. • En segundo lugar, matplotlib permite al usuario controlar los diferentes aspectos (ejes, líneas, tics, etc.) directamente mediante un sistema basado en objetos. Esto es más difícil pero permite un control completo sobre toda la trama. A continuación se muestra un ejemplo del uso de la interfaz pyplot para trazar algunos datos generados:
    • 1034. 969 import numpy as np # numpy used to create data from plotting import seaborn as sns # common form of importingseaborn Tenga en cuenta que se plt.show() que plt.show() es problemático en algunos entornos debido a la ejecución de matplotlib.pyplot en modo interactivo, y si es así, el comportamiento de bloqueo se puede anular explícitamente al pasar un argumento opcional, plt.show(block=True) , para paliar el problema. Seaborn Seaborn es una envoltura alrededor de Matplotlib que facilita la creación de gráficos estadísticos comunes. La lista de gráficos admitidos incluye gráficos de distribución univariada y bivariada, gráficos de regresión y varios métodos para representar variables categóricas. La lista completa de las parcelas que proporciona Seaborn se encuentra en su referencia API . Crear gráficos en Seaborn es tan simple como llamar a la función de gráficos apropiada. Este es un ejemplo de la creación de un histograma, una estimación de la densidad del kernel y una gráfica de tap para datos generados aleatoriamente.
    • 1035. 970 # Using previously created imports and data. # Use a dark background with no grid. sns.set_style('dark') # Create the plot again sns.distplot(data, kde=True, rug=True) El estilo de la trama también se puede controlar mediante una sintaxis declarativa. # Generate normally distributed data data = np.random.randn(1000) # Plot a histogram with both a rugplot and kde graph superimposed sns.distplot(data, kde=True, rug=True)
    • 1036. 971 # Using previously created data and style # Access to matplotlib commands import matplotlib.pyplot as plt # Previously created plot. sns.distplot(data, kde=True, rug=True) # Set the axis labels. plt.xlabel('This is my x-axis') plt.ylabel('This is my y-axis') Como un bono adicional, los comandos normales de matplotlib todavía se pueden aplicar a los gráficos de Seaborn. Aquí hay un ejemplo de cómo agregar títulos de ejes a nuestro histograma creado anteriormente.
    • 1037. 972 MayaVI MayaVI es una herramienta de visualización 3D para datos científicos. Utiliza el kit de herramientas de visualización o VTK debajo del capó. Usando el poder de VTK , MayaVI es capaz de producir una variedad de gráficos y figuras tridimensionales. Está disponible como una aplicación de software independiente y también como una biblioteca. Similar a Matplotlib , esta biblioteca proporciona una interfaz de lenguaje de programación orientada a objetos para crear gráficos sin tener que saber acerca de VTK . ¡MayaVI está disponible solo en la serie Python 2.7x! ¡Se espera que esté disponible en la serie Python 3-x pronto! (Aunque se nota cierto éxito al usar sus dependencias en Python 3) La documentación se puede encontrar aquí . Algunos ejemplos de galerías se encuentran aquí. Aquí hay una muestra de la parcela creada usando MayaVI de la documentación. #Author: Gael Varoquaux<gael.varoquaux@normalesup.org> # Copyright (c) 2007, Enthought, Inc. # License: BSD Style.
    • 1038. 973 Plotly Plotly es una plataforma moderna para el trazado y visualización de datos. Útil para producir una variedad de gráficos, especialmente para ciencias de datos, Plotly está disponible como una biblioteca para Python , R , JavaScript , Julia y MATLAB . También se puede utilizar como una aplicación web con estos idiomas. Los usuarios pueden instalar plotly library y usarlo fuera de línea después de la autenticación del usuario. La instalación de esta biblioteca y la autenticación fuera de línea se da aquí . Además, las parcelas se pueden hacer en Jupyter Notebooks también. El uso de esta biblioteca requiere una cuenta con nombre de usuario y contraseña. Esto proporciona el espacio de trabajo para guardar gráficos y datos en la nube. La versión gratuita de la biblioteca tiene algunas características ligeramente limitadas y está from numpy import sin, cos, mgrid, pi, sqrt from mayavi import mlab mlab.figure(fgcolor=(0, 0, 0), bgcolor=(1, 1, 1)) u, v = mgrid[- 0.035:pi:0.01, - 0.035:pi:0.01] X = 2 / 3. * (cos(u) * cos(2 * v) + sqrt(2) * sin(u) * cos(v)) * cos(u) / (sqrt(2) - sin(2 * u) * sin(3 * v)) Y = 2 / 3. * (cos(u) * sin(2 * v) - sqrt(2) * sin(u) * sin(v)) * cos(u) / (sqrt(2) - sin(2 * u) * sin(3 * v)) Z = -sqrt(2) * cos(u) * cos(u) / (sqrt(2) - sin(2 * u) * sin(3 * v)) S = sin(u) mlab.mesh(X, Y, Z, scalars=S, colormap='YlGnBu', ) # Nice view from the front mlab.view(.0, - 5.0, 4) mlab.show()
    • 1039. 974 import plotly.graph_objs as go import plotly as ply # Create random data with numpy import numpy as np N = 100 random_x = np.linspace(0, 1, N) random_y0 = np.random.randn(N)+5 random_y1 = np.random.randn(N) random_y2 = np.random.randn(N)-5 # Create traces trace0 = go.Scatter( x = random_x, y = random_y0, mode = 'lines', name = 'lines' ) trace1 = go.Scatter( x = random_x, y = random_y1, mode = 'lines+markers', name = 'lines+markers' ) trace2 = go.Scatter( x = random_x, y = random_y2, mode = 'markers', name = 'markers' ) data = [trace0, trace1, trace2] ply.offline.plot(data, filename='line-mode') diseñada para hacer 250 parcelas por día. La versión de pago tiene todas las características, descargas de parcelas ilimitadas y más almacenamiento de datos privados. Para más detalles, se puede visitar la página principal aquí . Para documentación y ejemplos, se puede ir aquí. Un diagrama de muestra de los ejemplos de documentación:
    • 1040. 975
    • 1041. 976 Capítulo 205: Web raspado con Python Introducción El raspado web es un proceso automatizado y programático a través del cual los datos se pueden " raspar " constantemente de las páginas web. También conocido como raspado de pantalla o recolección web, el raspado web puede proporcionar datos instantáneos desde cualquier página web de acceso público. En algunos sitios web, el raspado web puede ser ilegal. Observaciones Paquetes de Python útiles para raspado web (orden alfabético) Realización de solicitudes y recogida de datos. requests Un paquete simple, pero poderoso para hacer peticiones HTTP. requests-cache Caché para requests ; almacenar datos en caché es muy útil. En desarrollo, significa que puede evitar golpear un sitio innecesariamente. Mientras ejecuta una colección real, significa que si su raspador se bloquea por algún motivo (tal vez no haya manejado algún contenido inusual en el sitio ... ¿Tal vez el sitio se haya caído ...?) Puede repetir la colección muy rápidamente de donde lo dejaste. scrapy Útil para crear rastreadores web, donde necesita algo más potente que usar requests e iterar a través de páginas. selenium Enlaces Python para Selenium WebDriver, para la automatización del navegador. El uso de requests para realizar solicitudes HTTP directamente es a menudo más sencillo para recuperar páginas web. Sin embargo, esto sigue siendo una herramienta útil cuando no es posible replicar el comportamiento deseado de un sitio usando solo las requests , particularmente cuando se requiere JavaScript para representar elementos en una página. Análisis de HTML
    • 1042. 977 # For Python 2 compatibility. from future import print_function import lxml.html import requests def main(): r = requests.get("https://httpbin.org") html_source = r.text root_element = lxml.html.fromstring(html_source) # Note root_element.xpath() gives a *list* of results. # XPath specifies a path to the element we want. page_title = root_element.xpath('/html/head/title/text()')[0] print(page_title) if name == ' main ': main() import requests with requests.Session() as session: # all requests through session now have User-Agent header set session.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'} # set cookies session.get('http://httpbin.org/cookies/set?key=value') # get cookies response = session.get('http://httpbin.org/cookies') print(response.text) BeautifulSoup ConsultedocumentosHTMLyXML,utilizandovariosanalizadoresdiferentes(elanalizadorHTML incorporado de Python, html5lib , lxml o lxml.html ) lxml Procesos HTML y XML. Puede usarse para consultar y seleccionar contenido de documentos HTML a través de selectores de CSS y XPath. Examples Ejemplo básico de uso de solicitudes y lxml para raspar algunos datos Mantenimiento de sesión web-scraping con peticiones. Es una buena idea mantener una sesión de raspado web para conservarlas cookies y otros parámetros. Además, puede dar lugar a una mejora del rendimiento porque requests.Session reutiliza la conexión TCP subyacente a un host:
    • 1043. 978 scrapy startproject projectName import scrapy class StackOverflowSpider(scrapy.Spider): name = 'stackoverflow' # each spider has a unique name start_urls = ['http://stackoverflow.com/questions?sort=votes'] # the parsing starts from a specific set of urls def parse(self, response): # for each request this generator yields, its response is sent to parse_question for href in response.css('.question-summary h3 a::attr(href)'): # do some scraping stuff using css selectors to find question urls full_url = response.urljoin(href.extract()) yield scrapy.Request(full_url, callback=self.parse_question) def parse_question(self, response): yield { 'title': response.css('h1 a::text').extract_first(), 'votes': response.css('.question .vote-count-post::text').extract_first(), 'body': response.css('.question .post-text').extract_first(), 'tags': response.css('.question .post-tag::text').extract(), 'link': response.url, } scrapy crawl stackoverflow #USER_AGENT = 'projectName (+http://www.yourdomain.com)' Raspado utilizando el marco de Scrapy Primero tienes que configurar un nuevo proyecto Scrapy. Ingrese un directorio donde le gustaría almacenar su código y ejecute: Para raspar necesitamos una araña. Las arañas definen cómo se raspará un determinado sitio. Aquí está el código para una araña que sigue los enlaces a las preguntas más votadas en StackOverflow y raspa algunos datos de cada página ( fuente ): Guarda tus clases de arañas en el directorio nombre de projectName\spiders . En este caso, projectName\spiders\stackoverflow_spider.py . Ahora puedes usar tu araña. Por ejemplo, intente ejecutar (en el directorio del proyecto): Modificar agente de usuario de Scrapy En ocasiones, el host bloquea el agente de usuario de Scrapy predeterminado ( "Scrapy/VERSION (+http://scrapy.org)" ). Para cambiar el agente de usuario predeterminado, abra settings.py , elimine el comentario y edite la siguiente línea como desee. Por ejemplo
    • 1044. 979 from bs4 import BeautifulSoup import requests # Use the requests module to obtain a page res = requests.get('https://www.codechef.com/problems/easy') # Create a BeautifulSoup object page = BeautifulSoup(res.text, 'lxml') # the text field contains the source of the page # Now use a CSS selector in order to get the table containing the list of problems datatable_tags = page.select('table.dataTable') # The problems are in the <table> tag, # with class "dataTable" # We extract the first tag from the list, since that's what we desire datatable = datatable_tags[0] # Now since we want problem names, they are contained in <b> tags, which are # directly nested under <a> tags prob_tags = datatable.select('a > b') prob_names = [tag.getText().strip() for tag in prob_tags] print prob_names title = browser.find_element_by_css_selector('h1').text # page title (first h1 element) questions = browser.find_elements_by_css_selector('.question-summary') # question list for question in questions: # iterate over questions question_title = question.find_element_by_css_selector('.summary h3 a').text question_excerpt = question.find_element_by_css_selector('.summary .excerpt').text question_vote = question.find_element_by_css_selector('.stats .vote .votes .vote-countpost').text print "%s\n%s\n%s votes\n----------- \n" % (question_title, question_excerpt, question_vote) # load url from selenium import webdriver browser = webdriver.Firefox() # launch firefox browser browser.get('http://stackoverflow.com/questions?sort=votes') Raspado utilizando BeautifulSoup4 Raspado utilizando Selenium WebDriver Algunos sitios web no les gusta ser raspado. En estos casos, es posible que necesite simular a un usuario real que trabaja con un navegador. Selenium lanza y controla un navegador web. El selenio puede hacer mucho más. Puede modificar las cookies del navegador, rellenar formularios, simular clics del ratón, tomar capturas de pantalla de páginas web y ejecutar JavaScript personalizado. Descarga de contenido web simple con urllib.request USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
    • 1045. 980 from urllib.request import urlopen response = urlopen('http://stackoverflow.com/questions?sort=votes') data = response.read() # The received bytes should usually be decoded according the response's character set encoding = response.info().get_content_charset() html = data.decode(encoding) from subprocess import Popen, PIPE from lxml import etree from io import StringIO user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36' url = 'http://stackoverflow.com' get = Popen(['curl', '-s', '-A', user_agent, url], stdout=PIPE) result = get.stdout.read().decode('utf8') El módulo de biblioteca estándar urllib.request se puede usar para descargar contenido web: Un módulo similar también está disponible en Python 2 . Raspado con rizo importaciones: Descargando: -s : descarga silenciosa -A : bandera de agente de usuario Análisis: tree = etree.parse(StringIO(result), etree.HTMLParser()) divs = tree.xpath('//div')
    • 1046. 981 import asyncio from aiohttp import ClientSession class EchoWebSocket(ClientSession): URL = "wss://echo.websocket.org" def init (self): super(). init () self.websocket=None async def connect(self): """Connect to the WebSocket.""" self.websocket = await self.ws_connect(self.URL) async def send(self, message): """Send a message to the WebSocket.""" assert self.websocket is not None, "You must connect first!" self.websocket.send_str(message) print("Sent:", message) import asyncio from aiohttp import ClientSession with ClientSession() as session: async def hello_world(): websocket = await session.ws_connect("wss://echo.websocket.org") websocket.send_str("Hello, world!") print("Received:", (await websocket.receive()).data) await websocket.close() loop = asyncio.get_event_loop() loop.run_until_complete(hello_world()) Capítulo 206: Websockets Examples Eco simple con aiohttp aiohttp proporciona websockets asíncronos. Python 3.x 3.5 Clase de envoltura con aiohttp aiohttp.ClientSession puede usarse como padre para una clase de WebSocket personalizada. Python 3.x 3.5
    • 1047. 982 python -m pip install autobahn from autobahn.asyncio.websocket import WebSocketServerProtocol class MyServerProtocol(WebSocketServerProtocol): Usando Autobahn como una Websocket Factory El paquete Autobahn se puede utilizar para las fábricas de servidores de socket web de Python. Documentación del paquete Python Autobahn Para instalar, normalmente uno simplemente usaría el comando de terminal (Para Linux): (Para ventanas): Luego, se puede crear un servidor de eco simple en un script de Python: sudo pip install autobahn async def receive(self): """Receive one message from the WebSocket.""" assert self.websocket is not None, "You must connect first!" return (await self.websocket.receive()).data async def read(self): """Read messages from the WebSocket.""" assert self.websocket is not None, "You must connect first!" while self.websocket.receive(): message = await self.receive() print("Received:", message) if message == "Echo9!": break async def send(websocket): for n in range(10): await websocket.send("Echo {}!".format(n)) await asyncio.sleep(1) loop = asyncio.get_event_loop() with EchoWebSocket() aswebsocket: loop.run_until_complete(websocket.connect()) tasks = ( send(websocket), websocket.read() ) loop.run_until_complete(asyncio.wait(tasks)) loop.close()
    • 1048. 983 '''When creating server protocol, the user defined class inheriting the WebSocketServerProtocol needstooverride the onMessage, onConnect, et-c eventsfor user specified functionality, these events define your server's protocol, in essence''' def onMessage(self,payload,isBinary): '''The onMessage routine is called when the server receives a message. It has the required arguments payload and the bool isBinary. The payload isthe actual contents of the "message" and isBinary is simply a flag to let the user know that the payload contains binary data. I typically elsewise assume that the payload is a string. In this example, the payload is returned to sender verbatim.''' self.sendMessage(payload,isBinary) if name ==' main ': try: importasyncio except ImportError: '''Trollius = 0.3 was renamed''' import trollius as asyncio from autobahn.asyncio.websocketimportWebSocketServerFactory factory=WebSocketServerFactory() '''Initialize the websocket factory, and set the protocol to the above defined protocol(the class that inherits from autobahn.asyncio.websocket.WebSocketServerProtocol)''' factory.protocol=MyServerProtocol '''This above line can be thought of as "binding" the methods onConnect, onMessage, et-c that were described in the MyServerProtocol class to the server, setting the servers functionality, ie, protocol''' loop=asyncio.get_event_loop() coro=loop.create_server(factory,'127.0.0.1',9000) server=loop.run_until_complete(coro) '''Run the server in an infinite loop''' try: loop.run_forever() except KeyboardInterrupt: pass finally: server.close() loop.close() En este ejemplo, se está creando un servidor en el host local (127.0.0.1) en el puerto 9000. Esta es la IP y el puerto de escucha. Esta información es importante, ya que al usar esto, puede identificar la dirección LAN de su computadora y el puerto hacia adelante desde su módem, aunque cualquier enrutador que tenga a la computadora. Luego, utilizando google para investigar su IP WAN, puede diseñar su sitio web para enviar mensajes WebSocket a su IP WAN, en el puerto 9000 (en este ejemplo). Es importante que retroceda desde su módem, lo que significa que si tiene enrutadores conectados en cadena al módem, ingrese a los ajustes de configuración del módem, transfiera el puerto desde el módem al enrutador conectado, y así sucesivamente hasta el enrutador final de su computadora está conectado está recibiendo la información que se está recibiendo en el puerto de módem 9000 (en este ejemplo).
    • 1049. 984
    • 1050. 985 Creditos S. No Capítulos Contributors 1 Empezando con Python Language A. Raza, Aaron Critchley, Abhishek Jain, AER, afeique, Akshay Kathpal, alejosocorro, Alessandro Trinca Tornidor, Alex Logan, ALinuxLover, Andrea, Andrii Abramov, Andy, Andy Hayden, angussidney, Ani Menon, Anthony Pham, Antoine Bolvy, Aquib Javed Khan, Ares, Arpit Solanki, B8vrede, Baaing Cow, baranskistad, Brian C, Bryan P, BSL-5, BusyAnt, Cbeb24404, ceruleus, ChaoticTwist, Charlie H, Chris Midgley, Christian Ternus, Claudiu, Clíodhna, CodenameLambda, cʟᴅs ᴇᴇᴅ, Community, Conrad.Dean, Daksh Gupta, Dania, Daniel Minnaar, Darth Shadow, Dartmouth, deeenes, Delgan, depperm, DevD, dodell, Douglas Starnes, duckman_1991, Eamon Charles, edawine, Elazar, eli-bd, Enrico Maria De Angelis, Erica, Erica, ericdwang, Erik Godard, EsmaeelE, Filip Haglund, Firix, fox, Franck Dernoncourt, Fred Barclay, Freddy, Gerard Roche, glS, GoatsWearHats, GThamizh, H. Pauwelyn, hardmooth, hayalci, hichris123, Ian, IanAuld, icesin, Igor Raush, Ilyas Mimouni, itsthejoker, J F, Jabba, jalanb, James, James Taylor, Jean-Francois T., jedwards, Jeffrey Lin, jfunez, JGreenwell, Jim Fasarakis Hilliard, jim opleydulven, jimsug, jmunsch, Johan Lundberg, John Donner, John Slegers, john400, jonrsharpe, Joseph True, JRodDynamite, jtbandes, Juan T, Kamran Mackey, Karan Chudasama, KerDam, Kevin Brown, Kiran Vemuri, kisanme, Lafexlos, Leon, Leszek Kicior, LostAvatar, Majid, manu, MANU, Mark Miller, Martijn Pieters, Mathias711, matsjoyce, Matt, Mattew Whitt, mdegis, Mechanic, Media, mertyildiran, metahost, Mike Driscoll, MikJR, Miljen Mikic, mnoronha, Morgoth, moshemeirelles, MSD, MSeifert, msohng, msw, muddyfish, Mukund B, Muntasir Alam, Nathan Arthur, Nathaniel Ford, Ned Batchelder, Ni., niyasc, noɥʇʎԀ ʎzɐɹƆ, numbermaniac, orvi, Panda, Patrick Haugh, Pavan Nath, Peter Masiar, PSN, PsyKzz, pylang, pzp, Qchmqs, Quill, Rahul Nair, Rakitić, Ram Grandhi, rfkortekaas, rick112358, Robotski, rrao, Ryan Hilbert, Sam Krygsheld, Sangeeth Sudheer, SashaZd, Selcuk, Severiano Jaramillo Quintanar, Shiven, Shoe, Shog9, Sigitas Mockus, Simplans, Slayther, stark, StuxCrystal, SuperBiasedMan, Sнаđошƒа, taylor swift, techydesigner, Tejus Prasad, TerryA, The_Curry_Man, TheGenie OfTruth, Timotheus.Kampik, tjohnson, Tom Barron, Tom de Geus, Tony Suffolk 66, tonyo, TPVasconcelos,
    • 1051. 986 user2314737, user2853437, user312016, Utsav T, vaichidrewar, vasili111, Vin, W.Wong, weewooquestionaire, Will, wintermute, Yogendra Sharma, Zach Janicki, Zags 2 * args y ** kwargs cjds, Eric Zhang, ericmarkmartin, Geeklhem, J F, Jeff Hutchins , Jim Fasarakis Hilliard, JuanPablo, kdopen, loading..., Marlon Abeykoon, Mattew Whitt, Pasha, pcurry, PsyKzz, Scott Mermelstein, user2314737, Valentin Lorentz, Veedrac 3 Acceso a la base de datos Alessandro Trinca Tornidor, Antonio, bee-sting, cʟᴅsᴇᴇᴅ, D. Alveno, John Y, LostAvatar, mbsingh, Michel Touw, qwertyuip9 , RamenChef, rrawat, Stephen Leppik, Stephen Nyamweya, sumitroy, user2314737, valeas, zweiterlinde 4 Acceso al código fuente y código de bytes de Python muddyfish, StuxCrystal, user2314737 5 Acceso de atributo Elazar, SashaZd, SuperBiasedMan 6 agrupar por() Parousia, Thomas Gerot 7 Alcance variable y vinculante Anthony Pham, davidism, Elazar, Esteis, Mike Driscoll, SuperBiasedMan, user2314737, zvone 8 Almohada Razik 9 Alternativas para cambiar la declaración de otros idiomas davidism, J F, zmo, Валерий Павлов 10 Ambiente Virtual Python - virtualenv Vikash Kumar Jain 11 Análisis de argumentos de línea de comandos amblina, Braiam, Claudiu, cledoux, Elazar, Gerard Roche, krato, loading..., Marco Pashkov, Or Duan, Pasha, RamenChef , rfkortekaas, Simplans, Thomas Gerot, Topperfalkon, zmo, zondo 12 Análisis de HTML alecxe, talhasch 13 Anti-patrones de Python Alessandro Trinca Tornidor, Annonymous, eenblam, Mahmoud Hashemi, RamenChef, Stephen Leppik 14 Apilar ADITYA, boboquack, Chromium, cjds, depperm, Hannes Karppila, JGreenwell, Jonatan, kdopen, OliPro007, orvi, SashaZd, Sнаđошƒа, textshell, Thomas Ahle, user2314737 15 Árbol de sintaxis Teepeemm
    • 1052. 987 abstracta 16 Archivos y carpetas I / O Ajean, Anthony Pham, avb, Benjamin Hodgson, Bharel, Charles, crhodes, David Cullen, Dov, Esteis, ilse2005, isvforall, jfsturtz, Justin, Kevin Brown, mattgathu, MSeifert, nlsdfnbch, Ozair Kafray, PYPL, pzp, RamenChef, Ronen Ness, rrao, Serenity, Simplans, SuperBiasedMan, Tasdik Rahman, Thomas Gerot, Umibozu, user2314737, Will, WombatPM, xgord 17 ArcPy Midavalo, PolyGeo, Zhanping Shi 18 Arrays Andy, Pavan Nath, RamenChef, Vin 19 Audio blueberryfields, Comrade SparklePony, frankyjuang, jmunsch, orvi, qwertyuip9, Stephen Leppik, Thomas Gerot 20 Aumentar errores / excepciones personalizados naren 21 Biblioteca de subproceso Adam Matan, Andrew Schade, Brendan Abel, jfs, jmunsch, Riccardo Petraglia 22 Bloques de código, marcos de ejecución y espacios de nombres. Jeremy, Mohammed Salman 23 Bucles Adriano, Alex L, alfonso.kim, Alleo, Anthony Pham, Antti Haapala, Chris Hunt, Christian Ternus, Darth Kotik, DeepSpace, Delgan, DhiaTN, ebo, Elazar, Eric Finn, Felix D., Ffisegydd, Gal Dreiman, Generic Snake, ghostarbeiter, GoatsWearHats, Guy, Inbar Rose, intboolstring, J F, James, Jeffrey Lin, JGreenwell, Jim Fasarakis Hilliard, jrast, Karl Knechtel, machine yearning, Mahdi, manetsus, Martijn Pieters, Math, Mathias711, MSeifert, pnhgiol, rajah9, Rishabh Gupta, Ryan, sarvajeetsuman, sevenforce, SiggyF, Simplans, skrrgwasme, SuperBiasedMan, textshell, The_Curry_Man, Thomas Gerot, Tom, Tony Suffolk 66, user1349663, user2314737, Vinzee, Will 24 buscando Dan Sanderson, Igor Raush, MSeifert 25 Características ocultas Aaron Hall, Akshat Mahajan, Anthony Pham, Antti Haapala, Byte Commander, dermen, Elazar, Ellis, ericmarkmartin, Fermi paradox, Ffisegydd, japborst, Jim Fasarakis Hilliard, jonrsharpe , Justin, kramer65, Lafexlos, LDP, Morgan Thrapp, muddyfish, nico, OrangeTux, pcurry, Pythonista, Selcuk, Serenity, Tejas
    • 1053. 988 Jadhav, tobias_k, Vlad Shcherbina, Will 26 ChemPy - paquete de python Biswa_9937 27 Clases base abstractas (abc) Akshat Mahajan, Alessandro Trinca Tornidor, JGreenwell, Kevin Brown, Mattew Whitt, mkrieger1, SashaZd, Stephen Leppik 28 Clasificación, mínimo y máximo Antti Haapala, APerson, GoatsWearHats, Mirec Miskuf, MSeifert, RamenChef, Simplans, Valentin Lorentz 29 Comentarios y Documentación Ani Menon, FunkySayu, MattCorr, SuperBiasedMan, TuringTux 30 Comparaciones Anthony Pham, Ares, Elazar, J F, MSeifert, Shawn Mehan, SuperBiasedMan, Will, Xavier Combelle 31 Complementos y clases de extensión 2Cubed, proprefenetre, pylang, rrao, Simon Hibbs, Simplans 32 Comprobando la existencia de ruta y permisos Esteis, Marlon Abeykoon, mnoronha, PYPL 33 Computación paralela Akshat Mahajan, Dair, Franck Dernoncourt, J F, Mahdi, nlsdfnbch, Ryan Smith, Vinzee, Xavier Combelle 34 Comunicación Serial Python (pyserial) Alessandro Trinca Tornidor, Ani Menon, girish946, mnoronha, Saranjith, user2314737 35 Concurrencia de Python David Heyman, Faiz Halde, Iván Rodríguez Torres, J F, Thomas Moreau, Tyler Gubala 36 Condicionales Andy Hayden, BusyAnt, Chris Larson, deepakkt, Delgan, Elazar, evuez, Ffisegydd, Geeklhem, Hannes Karppila, James, Kevin Brown, krato, Max Feng, noɥʇʎԀʎzɐɹƆ, rajah9, rrao, SashaZd, Simplans, Slayther, Soumendra Kumar Sahoo, Thomas Gerot, Trimax, Valentin Lorentz, Vinzee, wwii, xgord, Zack 37 Conectando Python a SQL Server metmirr 38 Conexión segura de shell en Python mnoronha, Shijo 39 configparser Chinmay Hegde, Dunatotatos 40 Conjunto Andrzej Pronobis, Andy Hayden, Bahrom, Cimbali, Cody
    • 1054. 989 Piersall, Conrad.Dean, Elazar, evuez, J F, James, Or East, pylang, RahulHP, RamenChef, Simplans, user2314737 41 Contando Andy Hayden, MSeifert, Peter Mølgaard Pallesen, pylang 42 Copiando datos hashcode55, StuxCrystal 43 Corte de listas (selección de partes de listas) Greg, JakeD 44 Creando paquetes de Claudiu, KeyWeeUsr, Marco Pashkov, pylang, Python SuperBiasedMan, Thtu 45 Creando un servicio de Windows usando Python Simon Hibbs Crear entorno virtual 46 con Sirajus Salayhin virtualenvwrapper en windows 47 ctypes Or East 48 Datos binarios Eleftheria, evuez, mnoronha 49 Decoradores Alessandro Trinca Tornidor, ChaoticTwist, Community, Dair, doratheexplorer0911, Emolga, greut, iankit, JGreenwell, jonrsharpe, kefkius, Kevin Brown, Mattew Whitt, MSeifert, muddyfish, Mukunda Modell, Nearoo, Nemo, Nuno André, Pasha, Rob Bednark, seenu s, Shreyash S Sarnayak, Simplans, StuxCrystal, Suhas K, technusm1, Thomas Gerot, tyteen4a03, Wladimir Palant, zvone 50 Definiendo funciones con argumentos de lista zenlc2000 51 dejar de lado Biswa_9937 52 Depuración Aldo, B8vrede, joel3000, Sardathrion, Sardorbek Imomaliev, Vlad Bezden 53 Descomprimir archivos andrew 54 Descriptor bbayles, cizixs, Nemo, pylang, SuperBiasedMan 55 Despliegue Gal Dreiman, Iancnorden, Wayne Werner
    • 1055. 990 56 Diccionario Amir Rachum, Anthony Pham, APerson, ArtOfCode, BoppreH, Burhan Khalid, Chris Mueller, cizixs, depperm, Ffisegydd, Gareth Latty, Guy, helpful, iBelieve, Igor Raush, Infinity, James , JGreenwell, jonrsharpe, Karsten 7., kdopen, machine yearning, Majid, mattgathu, Mechanic, MSeifert, muddyfish, Nathan, nlsdfnbch, noɥʇʎԀʎzɐɹƆ, ronrest, Roy Iacob, Shawn Mehan, Simplans, SuperBiasedMan, TehTris, Valentin Lorentz, viveksyngh, Xavier Combelle 57 Diferencia entre Módulo y Paquete DeepSpace, Simplans, tjohnson 58 Distribución Alessandro Trinca Tornidor, JGreenwell, metahost, Pigman168 , RamenChef, Stephen Leppik 59 Django code_geek, orvi 60 Ejecución de código dinámico con `exec` y` eval` Antti Haapala, Ilja Everilä 61 El dis módulo muddyfish, user2314737 62 El intérprete (consola de línea de comandos) Aaron Christiansen, David, Elazar, Peter Shinners, ppperry 63 El módulo base64 Thomas Gerot 64 El módulo de configuración regional Will, XonAether 65 El módulo os Andy, Christian Ternus, JelmerS, JL Peyret, mnoronha, Vinzee 66 Empezando con GZip orvi 67 Enchufes David Cullen, Dev, MattCorr, nlsdfnbch, Rob H, StuxCrystal, textshell, Thomas Gerot, Will 68 entorno virtual con virtualenvwrapper Sirajus Salayhin 69 Entornos virtuales Adrian17, Artem Kolontay, ArtOfCode, Bhargav, brennan, Dair, Daniil Ryzhkov, Darkade, Darth Shadow, edwinksl, Fernando, ghostarbeiter, ha_1694, Hans Then, Iancnorden, J F, Majid, Marco Pashkov, Matt Giltaji, Mattew Whitt, nehemiah, Nuhil Mehdy, Ortomala Lokni, Preston, pylang, qwertyuip9,
    • 1056. 991 RamenChef, Régis B., Sebastian Schrader, Serenity, Shantanu Alshi, Shrey Gupta, Simon Fraser, Simplans, wrwrwr , ychaouche, zopieux, zvezda 70 Entrada y salida básica Doraemon, GoatsWearHats, J F, JNat, Marco Pashkov, Mark Miller, Martijn Pieters, Nathaniel Ford, Nicolás, pcurry, pzp, SashaZd, SuperBiasedMan, Vilmar 71 Entrada, subconjunto y salida de archivos de datos externos utilizando Pandas Mark Miller 72 Enumerar Andy, Elazar, evuez, Martijn Pieters, techydesigner 73 Errores comunes abukaj, ADITYA, Alec, Alessandro Trinca Tornidor, Alex, Antoine Bolvy, Baaing Cow, Bhargav Rao, Billy, bixel, Charles, Cheney, Christophe Roussy, Dartmouth, DeepSpace, DhiaTN, Dilettant, fox, Fred Barclay, Gerard Roche, greatwolf, hiro protagonist, Jeffrey Lin, JGreenwell, Jim Fasarakis Hilliard, Lafexlos, maazza, Malt, Mark, matsjoyce, Matt Dodge, MervS, MSeifert, ncmathsadist, omgimanerd, Patrick Haugh, pylang, RamenChef, Reut Sharabani, Rob Bednark, rrao, SashaZd, Shihab Shahriar, Simplans, SuperBiasedMan, Tim D, Tom Dunbavan, tyteen4a03, user2314737, Will Vousden, Wombatz 74 Escribiendo a CSV desde String o List Hriddhi Dey, Thomas Crowley 75 Eventos enviados de Python Server Nick Humrich 76 Examen de la unidad Alireza Savand, Ami Tavory, antimatter15, Arpit Solanki, bijancn, Claudiu, Dartmouth, engineercoding, Ffisegydd, J F, JGreenwell, jmunsch, joel3000, Kevin Brown, Kinifwyne, Mario Corchero, Matt Giltaji, Mattew Whitt, mgilson, muddyfish, pylang, strpeter 77 Excepciones Adrian Antunez, Alessandro Trinca Tornidor, Alfe, Andy, Benjamin Hodgson, Brian Rodriguez, BusyAnt, Claudiu, driax, Elazar, flazzarini, ghostarbeiter, Ilia Barahovski, J F, Marco Pashkov, muddyfish, noɥʇʎԀʎzɐɹƆ, Paul Weaver, Rahul Nair, RamenChef, Shawn Mehan, Shiven, Shkelqim Memolla, Simplans, Slickytail, Stephen Leppik, Sudip Bhandari, SuperBiasedMan, user2314737 78 Excepciones del Commonwealth Juan T, TemporalWolf
    • 1057. 992 79 Explotación florestal Gal Dreiman, Jörn Hees, sxnwlfkk 80 Exposiciónción Anthony Pham, intboolstring, jtbandes, Luke Taylor, MSeifert, Pasha, supersam654 81 Expresiones Regulares (Regex) Aidan, alejosocorro, andandandand, Andy Hayden, ashes999, B8vrede, Claudiu, Darth Shadow, driax, Fermi paradox, ganesh gadila, goodmami, Jan, Jeffrey Lin, jonrsharpe, Julien Spronck, Kevin Brown, Md.Sifatul Islam, Michael M.,mnoronha , Nander Speerstra, nrusch, Or East, orvi, regnarg, sarvajeetsuman, Simplans, SN Ravichandran KR, SuperBiasedMan, user2314737, zondo 82 Extensiones de escritura Dartmouth, J F, mattgathu, Nathan Osman, techydesigner, ygram 83 Fecha y hora Ajean, alecxe, Andy, Antti Haapala, BusyAnt, Conrad.Dean, Elazar, ghostarbeiter, J F, Jeffrey Lin, jonrsharpe, Kevin Brown , Nicole White, nlsdfnbch, Ohad Eytan, Paul, paulmorriss, proprius, RahulHP, RamenChef, sagism, Simplans, Sirajus Salayhin, Suku, Will 84 Filtrar APerson, cfi, J Atkin, MSeifert, rajah9, SuperBiasedMan 85 Formato de cadena 4444, Aaron Christiansen, Adam_92, ADITYA, Akshit Soota, aldanor, alecxe, Alessandro Trinca Tornidor, Andy Hayden, Ani Menon, B8vrede, Bahrom, Bhargav, Charles, Chris, Darth Shadow, Dartmouth, Dave J, Delgan, dreftymac, evuez, Franck Dernoncourt, Gal Dreiman, gerrit, Giannis Spiliopoulos, GiantsLoveDeathMetal, goyalankit, Harrison, James Elderfield, Jean-Francois T., Jeffrey Lin, jetpack_guy, JL Peyret, joel3000, Jonatan, JRodDynamite, Justin, Kevin Brown, knight, krato, Marco Pashkov, Mark, Matt, Matt Giltaji, mu , MYGz, Nander Speerstra, Nathan Arthur, Nour Chawich, orion_tvv, ragesz, SashaZd, Serenity, serv-inc, Simplans, Slayther, Sometowngeek, SuperBiasedMan, Thomas Gerot, tobias_k, Tony Suffolk 66, UloPe, user2314737, user312016, Vin, zondo 86 Formato de fecha surfthecity 87 Función de mapa APerson, cfi, Igor Raush, Jon Ericson, Karl Knechtel, Marco Pashkov, MSeifert, noɥʇʎԀʎzɐɹƆ, Parousia, Simplans, SuperBiasedMan, tlama, user2314737 88 Funciones Adriano, Akshat Mahajan, AlexV, Andy, Andy Hayden, Anthony Pham, Arkady, B8vrede, Benjamin Hodgson, btel, CamelBackNotation, Camsbury, Chandan Purohit, ChaoticTwist, Charlie H, Chris Larson, Community, D. Alveno, danidee, DawnPaladin, Delgan, duan, duckman_1991, elegent
    • 1058. 993 , Elodin, Emma, EsmaeelE, Ffisegydd, Gal Dreiman, ghostarbeiter, Hurkyl, J F, James, Jeffrey Lin, JGreenwell, Jim Fasarakis Hilliard, jkitchen, Jossie Calderon, Justin, Kevin Brown, L3viathan, Lee Netherton, Martijn Pieters, Martin Thurau, Matt Giltaji, Mike - SMT, Mike Driscoll, MSeifert, muddyfish, Murphy4, nd., noɥʇʎԀʎzɐɹƆ, Pasha, pylang, pzp, Rahul Nair, Severiano Jaramillo Quintanar, Simplans, Slayther, Steve Barnes, Steven Maude, SuperBiasedMan, textshell, then0rTh, Thomas Gerot, user2314737, user3333708, user405 , Utsav T, vaultah, Veedrac, Will, Will, zxxz, λuser 89 Funciones parciales FrankBr 90 Generadores 2Cubed, Ahsanul Haque, Akshat Mahajan, Andy Hayden, Arthur Dent, ArtOfCode, Augustin, Barry, Chankey Pathak, Claudiu, CodenameLambda, Community, deeenes, Delgan, Devesh Saini, Elazar, ericmarkmartin, Ernir, ForceBru, Igor Raush, Ilia Barahovski, J0HN, jackskis, Jim Fasarakis Hilliard, Juan T, Julius Bullinger, Karl Knechtel, Kevin Brown, Kronen, Luc M, Lyndsy Simon, machine yearning, Martijn Pieters, Matt Giltaji, max, MSeifert, nlsdfnbch, Pasha, Pedro, PsyKzz, pzp, satsumas, sevenforce, Signal, Simplans, Slayther, StuxCrystal, tversteeg, Valentin Lorentz, Will, William Merrill, xtreak, Zaid Ajaj, zarak, λuser 91 Gestores de contexto (declaración “con”) Abhijeet Kasurde, Alessandro Trinca Tornidor, Andy Hayden, Antoine Bolvy, carrdelling, Conrad.Dean, Dartmouth, David Marx, DeepSpace, Elazar, Kevin Brown, magu_, Majid, Martijn Pieters, Matthew, nlsdfnbch, Pasha, Peter Brittain, petrs, Shuo, Simplans, SuperBiasedMan, The_Cthulhu_Kid, Thomas Gerot, tyteen4a03, user312016, Valentin Lorentz, vaultah, λuser 92 Gráficos de tortuga Luca Van Oort, Stephen Leppik 93 hashlib Mark Omo, xiaoyi 94 Heapq ettanany 95 Herramienta 2to3 Alessandro Trinca Tornidor, Dartmouth, Firix, Kevin Brown, Naga2Raja, Stephen Leppik 96 herramienta grafica xiaoyi 97 ijson Prem Narain 98 Implementaciones no oficiales de Python Jacques de Hooge, Squidward 99 Importando modulos angussidney, Anthony Pham, Antonis Kalou, Brett Cannon,
    • 1059. 994 BusyAnt, Casebash, Christian Ternus, Community, Conrad.Dean, Daniel, Dartmouth, Esteis, Ffisegydd, FMc, Gerard Roche, Gideon Buckwalter, J F, JGreenwell, Kinifwyne, languitar, Lex Scarisbrick, Matt Giltaji, MSeifert, niyasc, nlsdfnbch, Paulo Freitas, pylang, Rahul Nair, Saiful Azad, Serenity, Simplans, StardustGogeta, StuxCrystal, SuperBiasedMan, techydesigner, the_cat_lady, Thomas Gerot, Tony Meyer, Tushortz, user2683246, Valentin Lorentz, Valor Naram, vaultah, wnnmaw 100 Incompatibilidades que se mueven de Python 2 a Python 3 671620616, Abhishek Kumar, Akshit Soota, Alex Gaynor, Allan Burleson, Alleo, Amarpreet Singh, Andy Hayden, Ani Menon, Antoine Bolvy, AntsySysHack, Antti Haapala, Antwan, arekolek , Ares, asmeurer, B8vrede, Bakuriu, Bharel, Bhargav Rao, bignose, bitchaser, Bluethon, Cache Staheli, Cameron Gagnon , Charles, Charlie H, Chris Sprague, Claudiu, Clayton Wahlstrom, cʟᴅsᴇᴇᴅ, Colin Yang, Cometsong, Community, Conrad.Dean, danidee, Daniel Stradowski, Darth Shadow, Dartmouth, Dave J, David Cullen, David Heyman, deeenes, DeepSpace, Delgan, DoHe, Duh-Wayne-101, Dunno, dwanderson, Ekeyme Mo, Elazar, enderland, enrico.bacis, erewok, ericdwang, ericmarkmartin, Ernir, ettanany, Everyone_Else, evuez, Franck Dernoncourt, Fred Barclay, garg10may, Gavin, geoffspear, ghostarbeiter,GoatsWearHats, H. Pauwelyn, Haohu Shen, holdenweb, iScrE4m, Iván C., J F, J. C. Leitão, James Elderfield, James Thiele, jarondl, jedwards, Jeffrey Lin, JGreenwell, Jim Fasarakis Hilliard, Jimmy Song, John Slegers, Jojodmo, jonrsharpe, Josh, Juan T, Justin, Justin M. Ucar, Kabie, kamalbanga, Karl Knechtel, Kevin Brown, King's jester, Kunal Marwaha, Lafexlos, lenz, linkdd, l'L'l, Mahdi, Martijn Pieters, Martin Thoma, masnun, Matt, Matt Dodge, Matt Rowland, Mattew Whitt, Max Feng, mgwilliams, Michael Recachinas, mkj, mnoronha, Moinuddin Quadri, muddyfish, Nathaniel Ford, niemmi, niyasc, noɥʇʎԀʎzɐɹƆ, OrangeTux, Pasha, Paul Weaver, Paulo Freitas, pcurry, pktangyue, poppie, pylang, python273, Pythonista, RahulHP, Rakitić, RamenChef, Rauf, René G, rfkortekaas, rrao, Ryan, sblair, Scott Mermelstein, Selcuk, Serenity, Seth M. Larson, ShadowRanger, Simplans, Slayther, solarc, sricharan, Steven Hewitt, sth, SuperBiasedMan, Tadhg McDonald-Jensen, techydesigner, Thomas Gerot, Tim, tobias_k, Tyler, tyteen4a03 , user2314737, user312016, Valentin Lorentz, Veedrac, Ven, Vinayak, Vlad Shcherbina, VPfB, WeizhongTu, Wieland, wim, Wolf, Wombatz, xtreak, zarak, zcb, zopieux, zurfyx, zvezda 101 Indexación y corte Alleo, amblina, Antoine Bolvy, Bonifacio2, Ffisegydd, Guy, Igor Raush, Jonatan, Martec, MSeifert, MUSR, pzp, RahulHP, Reut
    • 1060. 995 Sharabani, SashaZd, Sayed M Ahamad, SuperBiasedMan, theheadofabroom, user2314737, yurib 102 Interfaz de puerta de enlace de servidor web (WSGI) David Heyman, Kevin Brown, Preston, techydesigner 103 Introducción a RabbitMQ utilizando AMQPStorm eandersson 104 Iterables e iteradores 4444, Conrad.Dean, demonplus, Ilia Barahovski, Pythonista 105 kivy - Framework Python multiplataforma para el desarrollo de NUI dhimanta 106 La declaración de pase Anaphory 107 La función de impresión Beall619, Frustrated, Justin, Leon Z., lukewrites, SuperBiasedMan, Valentin Lorentz 108 La variable especial name Annonymous, BusyAnt, Christian Ternus, jonrsharpe, Lutz Prechelt, Steven Elliott 109 Las clases Aaron Hall, Ahsanul Haque, Akshat Mahajan, Andrzej Pronobis , Anthony Pham, Avantol13, Camsbury, cfi, Community, Conrad.Dean, Daksh Gupta, Darth Shadow, Dartmouth, depperm, Elazar, Ffisegydd, Haris, Igor Raush, InitializeSahib, J F, jkdev, jlarsch, John Militer, Jonas S, Jonathan, Kallz, KartikKannapur, Kevin Brown, Kinifwyne, Leo, Liteye, lmiguelvargasf, Mailerdaimon, Martijn Pieters, Massimiliano Kraus, Mattew Whitt, MrP01, Nathan Arthur, ojas mohril, Pasha, Peter Steele, pistache, Preston, pylang, Richard Fitzhugh, rohittk239, Rushy Panchal, Sempoo, Simplans, Soumendra Kumar Sahoo, SuperBiasedMan, techydesigner, then0rTh, Thomas Gerot, Tony Suffolk 66, tox123, UltraBob, user2314737, wrwrwr, Yogendra Sharma 110 Lectura y Escritura CSV Adam Matan, Franck Dernoncourt, Martin Valgur, mnoronha, ravigadila, Setu 111 Lista Adriano, Alexander, Anthony Pham, Ares, Barry, blueenvelope, Bosoneando, BusyAnt, Çağatay Uslu, caped114, Chandan Purohit, ChaoticTwist, cizixs, Daniel Porteous, Darth Kotik, deeenes, Delgan, Elazar, Ellis, Emma, evuez, exhuma, Ffisegydd, Flickerlight, Gal Dreiman, ganesh gadila,
    • 1061. 996 ghostarbeiter, Igor Raush, intboolstring, J F, j3485, jalanb, James, James Elderfield, jani, jimsug, jkdev, JNat, jonrsharpe, KartikKannapur, Kevin Brown, Lafexlos, LDP, Leo Thumma, Luke Taylor, lukewrites, lxer, Majid, Mechanic, MrP01,MSeifert , muddyfish, n12312, noɥʇʎԀʎzɐɹƆ, Oz Bar-Shalom, Pasha, Pavan Nath, poke, RamenChef, ravigadila, ronrest, Serenity, Severiano Jaramillo Quintanar, Shawn Mehan, Simplans, sirin, solarc, SuperBiasedMan, textshell, The_Cthulhu_Kid, user2314737, user6457549, Utsav T, Valentin Lorentz, vaultah , Will, wythagoras, Xavier Combelle 112 Lista de Comprensiones 3442, Akshit Soota, André Laszlo, Andy Hayden, Annonymous , Ari, Bhargav, Chris Mueller, Darth Shadow, Dartmouth, Delgan, enrico.bacis, Franck Dernoncourt, garg10may, intboolstring, Jeff Langemeier, Josh Caswell, JRodDynamite, justhalf, kdopen, Ken T, Kevin Brown, kiliantics, longyue0521, Martijn Pieters, Mattew Whitt, Moinuddin Quadri, MSeifert, muddyfish, noɥʇʎԀʎzɐɹƆ, pktangyue, Pyth0nicPenguin, Rahul Nair, Riccardo Petraglia, SashaZd, shrishinde, Simplans, Slayther, sudo bangbang, theheadofabroom, then0rTh, Tim McNamara, Udi, Valentin Lorentz, Veedrac, Zags 113 Lista de desestructuración (también conocido como embalaje y desembalaje) J F, sth, zmo 114 Listar comprensiones 3442, 4444, acdr, Ahsanul Haque, Akshay Anand, Akshit Soota, Alleo, Amir Rachum, André Laszlo, Andy Hayden, Ankit Kumar Singh, Antoine Bolvy, APerson, Ashwinee K Jha, B8vrede, bfontaine, Brian Cline, Brien, Casebash, Celeo, cfi, ChaoticTwist, Charles, Charlie H, Chong Tang, Community, Conrad.Dean, Dair, Daniel Stradowski, Darth Shadow, Dartmouth, David Heyman, Delgan, Dima Tisnek, eenblam, Elazar, Emma, enrico.bacis, EOL, ericdwang, ericmarkmartin, Esteis, Faiz Halde, Felk, Fermi paradox, Florian Bender, Franck Dernoncourt, Fred Barclay, freidrichen, G M, Gal Dreiman, garg10may, ghostarbeiter, GingerHead, griswolf, Hannele, Harry, Hurkyl, IanAuld, iankit, Infinity, intboolstring, J F, J0HN, James, JamesS, Jamie Rees, jedwards, Jeff Langemeier, JGreenwell, JHS, jjwatt, JKillian, JNat, joel3000, John Slegers, Jon, jonrsharpe, Josh Caswell, JRodDynamite, Julian, justhalf, Kamyar Ghasemlou, kdopen, Kevin Brown, KIDJourney, Kwarrtz, Lafexlos, lapis, Lee Netherton, Liteye, Locane, Lyndsy Simon, machine yearning, Mahdi, Marc, Markus Meskanen, Martijn Pieters, Matt, Matt Giltaji, Matt S,
    • 1062. 997 116 Llama a Python desde C # Julij Jegorov 115 Listas enlazadas Nemo 117 Maldiciones básicas con pitón 4444, Guy, kollery, Vinzee 119 Matemáticas complejas Adeel Ansari, Bosoneando, bpachev 121 Matrices multidimensionales boboquack, Buzz, rrao 122 Metaclases 2Cubed, Amir Rachum, Antoine Pinsard, Camsbury, Community, driax, Igor Raush, InitializeSahib, Marco Pashkov, Martijn Pieters, Mattew Whitt, OozeMeister, Pasha, Paulo Scardine, RamenChef, Rob Bednark, Simplans, sisanared, zvone 123 Método Anulando DeepSpace, James 124 Métodos de cuerda Amitay Stern, Andy Hayden, Ares, Bhargav Rao, Brien, BusyAnt, Cache Staheli, caped114, ChaoticTwist, Charles, Dartmouth, David Heyman, depperm, Doug Henderson, Elazar , ganesh gadila, ghostarbeiter, GoatsWearHats, idjaw, Igor Raush, Ilia Barahovski, j , Jim Fasarakis Hilliard, JL Peyret, Kevin Brown, krato, MarkyPython, Metasomatism, Mikail Land, MSeifert, mu , Nathaniel Ford, OliPro007, orvi, pzp, ronrest, 120 Matraz Stephen Leppik, Thomas Gerot 118 Manipulando XML 4444, Brad Larson, Chinmay Hegde, Francisco Guimaraes, greuze, heyhey2k, Rob Murray Mattew Whitt, Maximillian Laumeister, mbrig, Mirec Miskuf, Mitch Talmadge, Morgan Thrapp, MSeifert, muddyfish, n8henrie, Nathan Arthur, nehemiah, noɥʇʎԀʎzɐɹƆ, Or East, Ortomala Lokni, pabouk, Panda, Pasha, pktangyue, Preston, Pro Q, pylang, R Nar, Rahul Nair, rap-2-h, Riccardo Petraglia, rll, Rob Fagen, rrao, Ryan Hilbert, Ryan Smith, ryanyuyu, Samuel McKay, sarvajeetsuman, Sayakiss, Sebastian Kreft, Shoe, SHOWMEWHATYOUGOT, Simplans, Slayther, Slickytail, solidcell, StuxCrystal, sudo bangbang, Sunny Patel, SuperBiasedMan, syb0rg, Symmitchry, The_Curry_Man, theheadofabroom, Thomas Gerot, Tim McNamara, Tom Barron, user2314737, user2357112, Utsav T, Valentin Lorentz, Veedrac, viveksyngh, vog, W.P. McNeill, Will, Will, Wladimir Palant, Wolf, XCoder Real, yurib, Yury Fedorov, Zags, Zaz
    • 1063. 998 Shrey Gupta, Simplans, SuperBiasedMan, theheadofabroom, user1349663, user2314737, Veedrac, WeizhongTu, wnnmaw 125 Métodos definidos por el usuario Alessandro Trinca Tornidor, Beall619, mnoronha, RamenChef, Stephen Leppik, Sun Qingyao 126 Mixins Doc, Rahul Nair, SashaZd 127 Modismos Benjamin Hodgson, Elazar, Faiz Halde, J F, Lee Netherton, loading..., Mister Mister 128 Módulo aleatorio Alex Gaynor, Andrzej Pronobis, Anthony Pham, Community, David Robinson, Delgan, giucal, Jim Fasarakis Hilliard, michaelrbock, MSeifert, Nobilis, ppperry, RamenChef, Simplans, SuperBiasedMan 129 Módulo asyncio 2Cubed, Alessandro Trinca Tornidor, Cimbali, hiro protagonist, obust, pylang, RamenChef, Seth M. Larson, Simplans, Stephen Leppik, Udi 130 Módulo de cola Prem Narain 131 Módulo de colecciones asmeurer, Community, Elazar, jmunsch, kon psych, Marco Pashkov, MSeifert, RamenChef, Shawn Mehan, Simplans, Steven Maude, Symmitchry, void, XCoder Real 132 Módulo de funciones Alessandro Trinca Tornidor, enrico.bacis, flamenco, RamenChef, Shrey Gupta, Simplans, Stephen Leppik, StuxCrystal 133 Módulo de matemáticas Anthony Pham, ArtOfCode, asmeurer, Christofer Ohlsson, Ellis , fredley, ghostarbeiter, Igor Raush, intboolstring, J F, James Elderfield, JGreenwell, MSeifert, niyasc, RahulHP, rajah9, Simplans, StardustGogeta, SuperBiasedMan, yurib 134 Módulo de navegador web Thomas Gerot 135 Módulo Deque Anthony Pham, BusyAnt, matsjoyce, ravigadila, Simplans, Thomas Ahle, user2314737 136 Módulo Itertools ADITYA, Alessandro Trinca Tornidor, Andy Hayden, balki, bpachev, Ffisegydd, jackskis, Julien Spronck, Kevin Brown, machine yearning, nlsdfnbch, pylang, RahulHP, RamenChef, Simplans, Stephen Leppik, Symmitchry, Wickramaranga, wnnmaw 137 Módulo JSON Indradhanush Gupta, Leo, Martijn Pieters, pzp, theheadofabroom, Underyx, Wolfgang
    • 1064. 999 138 Módulo operador MSeifert 139 módulo pyautogui Damien, Rednivrug 140 Módulo Sqlite3 Chinmay Hegde, Simplans 141 Multihilo Alu, cʟᴅsᴇᴇᴅ, juggernaut, Kevin Brown, Kristof,mattgathu, Nabeel Ahmed, nlsdfnbch, Rahul, Rahul Nair, Riccardo Petraglia, Thomas Gerot, Will, Yogendra Sharma 142 Multiprocesamiento Alon Alexander, Nander Speerstra, unutbu, Vinzee, Will 143 Mutable vs Inmutable (y Hashable) en Python Cilyan 144 Neo4j y Cypher usando Py2Neo Wingston Sharon 145 Nodo de lista enlazada orvi 146 Objetos de propiedad Alessandro Trinca Tornidor, Darth Shadow, DhiaTN, J F, Jacques de Hooge, Leo, Martijn Pieters, mnoronha, Priya, RamenChef, Stephen Leppik 147 Operadores booleanos boboquack, Brett Cannon, Dair, Ffisegydd, John Zwinck, Severiano Jaramillo Quintanar, Steven Maude 148 Operadores de Bitwise Abhishek Jain, boboquack, Charles, Gal Dreiman, intboolstring , JakeD, JNat, Kevin Brown, Matías Brignone, nemesisfixx, poke, R Colmenares, Shawn Mehan, Simplans, Thomas Gerot, tmr232, Tony Suffolk 66, viveksyngh 149 Operadores matemáticos simples amin, blueenvelope, Bryce Frank, Camsbury, David, DeepSpace, Elazar, J F, James, JGreenwell, Jon Ericson, Kevin Brown, Lafexlos, matsjoyce, Mechanic, Milo P, MSeifert, numbermaniac, sarvajeetsuman, Simplans, techydesigner, Tony Suffolk 66, Undo, user2314737, wythagoras, Zenadix 150 Optimización del rendimiento A. Ciclet, RamenChef, user2314737 151 os.path Claudiu, Fábio Perez, girish946, Jmills, Szabolcs Dombi, VJ Magar 152 Pandas Transform: Preforma operaciones en grupos y concatena Dee
    • 1065. 1000 los resultados. 153 Patrones de diseño Charul, denvaar, djaszczurowski 154 Perfilado J F, keiv.fly, SashaZd 155 Persistencia Python RamenChef, user2728397 156 pip: PyPI Package Manager Andy, Arpit Solanki, Community, InitializeSahib, JNat, Mahdi, Majid, Matt Giltaji, Nathaniel Ford, Rápli András, SerialDev, Simplans, Steve Barnes, StuxCrystal, tlo 157 Plantillas en python 4444, Alessandro Trinca Tornidor, Fred Barclay, RamenChef, Ricardo, Stephen Leppik 158 Polimorfismo Benedict Bunting, DeepSpace, depperm, Simplans, skrrgwasme, Vinzee 159 PostgreSQL Alessandro Trinca Tornidor, RamenChef, Stephen Leppik, user2027202827 160 Precedencia del operador HoverHell, JGreenwell, MathSquared, SashaZd, Shreyash S Sarnayak 161 Procesos e hilos Claudiu, Thomas Gerot 162 Programación Funcional en Python Imran Bughio, mvis89, Rednivrug 163 Programación IoT con Python y Raspberry PI dhimanta 164 py.test Andy, Claudiu, Ffisegydd, Kinifwyne, Matt Giltaji 165 pyaudio Biswa_9937 166 pygame Anthony Pham, Aryaman Arora, Pavan Nath 167 Pyglet Comrade SparklePony, Stephen Leppik 168 PyInstaller - Distribuir código de Python ChaoticTwist, Eric, mnoronha 169 Python Lex-Yacc cʟᴅsᴇᴇᴅ 170 171 Python Requests Post Python y Excel Ken Y-N, RandomHash bee-sting, Chinmay Hegde, GiantsLoveDeathMetal, hackvan, Majid, talhasch, user2314737, Will
    • 1066. 1001 172 Recolección de basura bogdanciobanu, Claudiu, Conrad.Dean, Elazar, FazeL, J F, James Elderfield, lukess, muddyfish, Sam Whited, SiggyF, Stephen Leppik, SuperBiasedMan, Xavier Combelle 173 Reconocimiento óptico de caracteres rassar 174 Recursion Bastian, japborst, JGreenwell, Jossie Calderon, mbomb007, SashaZd, Tyler Crompton 175 Redes Python atayenel, ChaoticTwist, David, Geeklhem, mattgathu, mnoronha, thsecmaniac 176 Reducir APerson, Igor Raush, Martijn Pieters, MSeifert 177 Representaciones de cadena de instancias de clase: métodos str y repr Alessandro Trinca Tornidor, jedwards, JelmerS, RamenChef, Stephen Leppik 178 Sangría Alessandro Trinca Tornidor, depperm, J F, JGreenwell, Matt Giltaji, Pasha, RamenChef, Stephen Leppik 179 Seguridad y criptografía adeora, ArtOfCode, BSL-5, Kevin Brown, matsjoyce, SuperBiasedMan, Thomas Gerot, Wladimir Palant, wrwrwr 180 Serialización de datos Devesh Saini, Infinity, rfkortekaas 181 Serialización de datos de salmuera J F, Majid, Or East, RahulHP, rfkortekaas, zvone 182 Servidor HTTP de Python Arpit Solanki, J F, jmunsch, Justin Chadwell, Mark, MervS, orvi , quantummind, Raghav, RamenChef, Sachin Kalkur, Simplans , techydesigner 183 setup.py Adam Brenecki, amblina, JNat, ravigadila, strpeter, user2027202827, Y0da 184 Similitudes en la sintaxis, diferencias en el significado: Python vs. JavaScript user2683246 185 Sobrecarga Andy Hayden, Darth Shadow, ericmarkmartin, Ffisegydd, Igor Raush, Jonas S, jonrsharpe, L3viathan, Majid, RamenChef, Simplans, Valentin Lorentz 186 Sockets y cifrado / descifrado de Mohammad Julfikar
    • 1067. 1002 mensajes entre el cliente y el servidor 187 Subcomandos CLI con salida de ayuda precisa Alessandro Trinca Tornidor, anatoly techtonik, Darth Shadow 188 sys blubberdiblub 189 tempfile NamedTemporaryFile Alessandro Trinca Tornidor, amblina, Kevin Brown, Stephen Leppik 190 Tipo de sugerencias alecxe, Annonymous, Antti Haapala, Elazar, Jim Fasarakis Hilliard, Jonatan, RamenChef, Seth M. Larson, Simplans, Stephen Leppik 191 Tipos de datos de Python Gavin, lorenzofeliz, Pike D., Rednivrug Tipos de datos 192 inmutables (int, float, str, tuple y Alessandro Trinca Tornidor, FazeL, Ganesh K, RamenChef, Stephen Leppik frozensets) 193 tkinter Dartmouth, rlee827, Thomas Gerot, TidB 194 Trabajando alrededor del bloqueo global de intérpretes (GIL) Scott Mermelstein 195 Trabajando con archivos ZIP Chinmay Hegde, ghostarbeiter, Jeffrey Lin, SuperBiasedMan 196 Trazado con matplotlib Arun, user2314737 197 Tupla Anthony Pham, Antoine Bolvy, BusyAnt, Community, Elazar, James, Jim Fasarakis Hilliard, Joab Mendes, Majid, Md.Sifatul Islam, Mechanic, mezzode, nlsdfnbch, noɥʇʎԀʎzɐɹƆ, Selcuk, Simplans, textshell, tobias_k, Tony Suffolk 66, user2314737 198 Unicode wim 199 Unicode y bytes Claudiu, KeyWeeUsr 200 urllib Amitay Stern, ravigadila, sth, Will 201 Usando bucles dentro de funciones naren
    • 1068. 1003 202 Uso del módulo "pip": PyPI Package Manager Zydnar 203 Velocidad de Python del programa. ADITYA, Antonio, Elodin, Neil A., Vinzee 204 Visualización de datos con Python Aquib Javed Khan, Arun, ChaoticTwist, cledoux, Ffisegydd, ifma 205 Web raspado con Python alecxe, Amitay Stern, jmunsch, mrtuovinen, Ni., RamenChef, Saiful Azad, Saqib Shamsi, Simplans, Steven Maude, sth, sytech, talhasch, Thomas Gerot 206 Websockets 2Cubed, Stephen Leppik, Tyler Gubala


    • Previous
    • Next
    • f Fullscreen
    • esc Exit Fullscreen