Aprende todo sobre Python

Aprende todo sobre Python

@ProfGastonPerez
@ProfGastonPerez
1 Follower
2 months ago 100

Adéntrate en el emocionante mundo de la programación y transforma tu carrera con nuestra guía integral. Desde técnicas avanzadas en Python hasta trabajo con bases de datos, este recurso es imprescindible para quienes buscan destacar en el campo tecnológico. Conoce herramientas, métodos y secretos que te ayudarán a convertirte en el programador que siempre has querido ser.

1/1068
Descubre como llevar tu carrera de
programación al siguiente nivel y 
conviértete en ese programa…
2/1068
Tabla de contenido
Acerca de 1
Capítulo1:Empezando conPython Language 2 
Observaciones 2 
Versi…
3/1068
IDLE - GUI de Python 14 
Solución de problemas 14 
Tipos de datos 15 
Tipos incorporados 15 
Bo…
4/1068
Tiposdedatosmutableseinmutables 19 
Construido en módulos y funciones 20 
Sangría de bloque 24 
…
5/1068
Accediendo a la base de datos MySQL usando MySQLdb 44 
SQLite 45
La sintaxis de SQLite: un anális…
6/1068
Observaciones 62
Examples 62
Ejemplo 1 62
Ejemplo 2 63
Ejemplo 3 64
Ejemplo 4 65 
Capítulo 7:…
7/1068
Usa un dictado de funciones. 78
Usa la introspección de clase. 78 
Usando un administrador de con…
8/1068
Observaciones 94
Examples 94
Creación de una clase de pila con un objeto de lista 94 
Paréntesis…
9/1068
Introducción 109 
Parámetros 109 
Examples 109 
Introducción básica a las matrices 109 
Accede …
10/1068
Examples 118
Llamando Comandos Externos 118 
Más flexibilidad con Popen 119 
Lanzarunsubproceso …
11/1068
La Declaración de Pase 133
Iterando diferentes partes de una lista con diferentes tamaños de paso …
12/1068
Examples 148
Configuración de la metaclase ABCMeta 148 
Por qué / Cómo usar ABCMeta y @abstractme…
13/1068
Mayor o menor que 163
No igual a 164 
Igual a 164 
Comparaciones de cadena 165 
Estilo 165 
Ef…
14/1068
Capítulo 35: Concurrencia de Python 179
Observaciones 179
Examples 179 
El módulo de enhebrado. …
15/1068
Introducción 193
Sintaxis 193 
Observaciones 193 
Examples 193 
Uso básico 193 
Creando progra…
16/1068
Examples 204
Realizando una copia superficial 204 
Realizando una copia profunda 204 
Realizando…
17/1068
Ejecutando una aplicación web de Flask como un servicio 215 
Capítulo 46: Crear entorno virtual co…
18/1068
Como una clase 230 
Decorador con argumentos (decorador de fábrica). 230 
Funciones de decorador …
19/1068
Descriptor simple 244
Conversiones bidireccionales 245 
Capítulo 55: Despliegue 247 
Examples 24…
20/1068
Capítulo57:DiferenciaentreMóduloyPaquete 259 
Observaciones 259 
Examples 259 
Módulos 259 
Paq…
21/1068
Refiriéndose a la última expresión. 271
Abriendo la consola de Python 272 
La variable PYTHONSTAR…
22/1068
Introducción 286
Examples 286 
Lee y escribe archivos zip de GNU 286 
Capítulo67:Enchufes 287 
…
23/1068
Uso 299 
Directorios de proyectos 299 
Descubrir qué entorno virtual está utilizando 300 
Especi…
24/1068
Lista de multiplicación y referencias comunes. 316 
Identidad entera y de cadena 320 
Accediendo …
25/1068
Capítulo77:Excepciones 340 
Introducción 340 
Sintaxis 340 
Examples 340 
Levantando excepcione…
26/1068
TypeError:[definición /método]toma? argumentos posicionales pero? se le dio 352 
Ejemplo 352 
Typ…
27/1068
Raíces: raíz nth con exponentes fraccionarios 367 
Cálculo de grandes raíces enteras 367
Capítulo…
28/1068
Capítulo 83: Fecha yhora 383
Observaciones 383
Examples 383 
Análisis de una cadena en un objeto…
29/1068
Examples 396
Conceptos básicos de formato de cadena 396 
Alineación y relleno. 398 
Formato lite…
30/1068
Parámetros 413
Observaciones 413 
Recursos adicionales 414 
Examples 414 
Definiendo y llamando…
31/1068
Sintaxis 433
Parámetros 433 
Observaciones 433 
Examples 433 
Elevar el poder 433 
Capítulo90:…
32/1068
Gestores de contexto multiples 450
Gestionar recursos 450 
Capítulo92:Gráficosdetortuga 452 
Exa…
33/1068
Examples 463
Ejemplo simple 463 
Capítulo 98: Implementaciones no oficiales de Python 464 
Examp…
34/1068
Python 2 475 
Python 3 475 
Capítulo100:IncompatibilidadesquesemuevendePython2aPython3 477 
Intr…
35/1068
La función round () rompe el empate y devuelve el tipo 503 
rotura de corbata redonda () 503
roun…
36/1068
Iterando sobre todo iterable 520
Verificar solo un elemento en iterable. 521 
Extraer valores uno…
37/1068
Variables de clase e instancia 536
Métodos enlazados, no enlazados y estáticos. 537 
Clases de es…
38/1068
Examples 582
Todos y cada uno 565
Eliminar valores duplicados en la lista 566 
Acceso a valores …
39/1068
Examples 604
Lista de Comprensiones 582
más 583
Dobleiteración 584
Mutación in situ y otros efe…
40/1068
Abriendo y leyendo usando un ElementTree 604 
Modificar un archivo XML 604
Crear y construir docu…
41/1068
Singletons utilizando metaclases 619
Usando una metaclase 620 
Sintaxisdemetaclase 620
Compatibi…
42/1068
Prueba los caracteres iniciales y finales de una cadena. 632 
str.startswith(prefix[, start[, end]…
43/1068
Capítulo126:Mixins 646 
Sintaxis 646 
Observaciones 646 
Examples 646 
Mezclar 646 
Métodos de…
44/1068
Usando UVLoop 659
Primitiva de sincronización: Evento 659 
Concepto 659 
Ejemplo 660 
Un simple…
45/1068
Logaritmos 676
Copiando carteles 677 
Trigonometría 677 
Cálculo de la longitud de la hipotenusa…
46/1068
Toma una rebanada de un generador 694
itertools.product 695 
itertools.count 695 
itertools.take…
47/1068
Deshacersedelosespaciosenblancoparaobtener unasalidacompacta 707
JSON que codifica objetos persona…
48/1068
Mutable vs inmutable 722
Inmutables 722 
Ejercicio 723 
Mutables 723 
Ejercicio 724 
Mutables …
49/1068
Un simple ejemplo 736
Capítulo148:OperadoresdeBitwise 737 
Introducción 737 
Sintaxis 737 
Exam…
50/1068
Introducción 753
Sintaxis 753 
Examples 753 
Unir caminos 753 
Camino Absoluto desde el Camino …
51/1068
Parámetros 768
Examples 768 
Persistencia Python 768 
Función de utilidad para guardar y cargar.…
52/1068
Empezando 784
Instalación utilizando pip 784 
Uso básico 784 
Capítulo160:Precedenciadeloperador…
53/1068
Pruebas de falla 799
Introducción a los accesorios de prueba 799 
Py.test accesorios para el resc…
54/1068
Usando Pyinstaller 813 
Agrupar en una carpeta 813 
Ventajas: 813 
Desventajas 814
Agrupar en u…
55/1068
Formulario de datos codificados 826
Subir archivo 827 
Respuestas 827 
Autenticación 828 
Proxi…
56/1068
El qué, cómo y cuándo de la recursión 847
Exploración de árboles con recursión 851 
Incrementando…
57/1068
La Solución(Parte 2) 865 
Sobre esas funciones duplicadas 867 
Resumen 867 
Ambos métodos implem…
58/1068
Observaciones 881
Tipos pickleable 881 
pickleyseguridad 881 
Examples 882 
Usando Pickle para …
59/1068
Manejando conductas no implementadas. 897
Sobrecarga del operador 898 
Capítulo186:Socketsycifrad…
60/1068
Tipos genéricos 917 
Añadiendo tipos a una función 917 
Miembros de la clase y métodos 919 
Vari…
61/1068
Detallessobre cómofuncionaelGIL: 928
Beneficiosde la GIL 929 
Consecuencias de laGIL 929 
Refere…
62/1068
Tuplas de indexación 945
Las tuplas son inmutables 946 
Tuple son elementos sabios hashable y equ…
63/1068
Python 2 957 
Python 3 957 
POST HTTP 958
Python 2 ................ 958 
Python 3 .............…
64/1068
Observaciones 976
Paquetes de Python útiles para raspado web (orden alfabético) 976 
Realización …
65/1068
1
Acerca de
Puedes compartir este PDF con cualquier persona que creas que podría beneficiarse.
E…
66/1068
2
if something: 
x = 1
else:
x = 'this is a string' 
print(x)
1 + '1' # raises an error
1 + …
67/1068
3
significativas. Python 2.x es la versión heredada, aunque sigue teniendo un uso generalizado. 
…
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…
69/1068
5
$ python --version 
Python 2.7.13
>>>
>>> print("Hello, World")
>>> print("Hello, World") 
…
70/1068
6
print('Hello, World')
from future import print_function
print 'Hello, World'
$ python
Python…
71/1068
7
>>> exit()
>>> quit()
Alternativamente,inicielasolicitudinteractivaycargueelarchivoconpython -…
72/1068
8
$ python -c 'print("Hello, World")' 
Hello, World
Python.
• https://ideone.com/ : se utiliza …
73/1068
9
<variable name> = <value>
# Integer 
a = 2 
print(a)
# Output: 2
# Integer
b = 92233720368…
74/1068
10
x = True # valid
_y = True # valid
9x = False # starts with numeral
=> SyntaxError: invalid …
75/1068
11
a_name = an_object # "a_name" is now a name for the reference to the object "an_object"
a, b, …
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…
77/1068
13
name = raw_input("What is your name? ") 
# Out: What is your name? _
name = input("What is yo…
78/1068
14
x = input("Write a number:") 
# Out: Write a number: 10
x / 2
#Out: TypeError: unsupported o…
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 #…
80/1068
16
True + False == 1 # 1 + 0 == 1
True * True == 1 # 1 * 1 == 1
a = 2
b = 100
c = 123456789
d…
81/1068
17
a = reversed('hello')
a = (1, 2, 3)
b = ('a', 1, 'python', (1, 2))
b[2] = 'something else' #…
82/1068
18
a = None # No value will be assigned. Any valid datatype can be assigned later
a = '123'
prin…
83/1068
19
a = '123'
b = int(a)
a = '123.456'
b = float(a)
c = int(a) # ValueError: invalid literal fo…
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 ==…
85/1068
21
argumento, devuelve los nombres en el alcance actual. De lo contrario, devuelve una lista 
alf…
86/1068
22
' doc ', ' import ', 
' name ', ' package', 
'abs',
'all',
'any',
'apply', 
'basestring',…
87/1068
23
>>> help(max)
Help on built-in function max in module builtin : 
max(...)
max(iterable[, key…
88/1068
24
>>> math. doc
'This module is always available. It provides access to the\nmathematical 
func…
89/1068
25
def my_function(): # This is a function definition. Note the colon (:) 
a = 2 # This line belo…
90/1068
26
int_list = [1, 2, 3] 
string_list = ['abc', 'defghi']
Python3nopermitemezclar elusodetabulaci…
91/1068
27
mixed_list = [1, 'abc', True, 2.34, None]
nested_list = [['a', 'b', 'c'], [1, 2, 3]]
names = …
92/1068
28
name.index("Alice") 
0
len(names) 
6
a = [1, 1, 1, 2, 3, 4]
a.count(1) 
3
a.reverse()
[…
93/1068
29
one_member_tuple = ('Only member',)
one_member_tuple = 'Only member', # No brackets
one_membe…
94/1068
30
if name in first_names: 
print(name)
>>> state_capitals = { 
'Arkansas': 'Little Rock', 
'C…
95/1068
31
>>> state_capitals['Alabama'] 
'Boston'
>>> state_capitals['Arkansas'] 
'Little Rock'
>>> h…
96/1068
32
help(pymysql.connections)
>>> help(math)
>>> import math
>>> help(math)
$ python
>>> impor…
97/1068
33
# greet.py
from hello import say_hello 
say_hello()
# greet.py
import hello as ai 
ai.say_…
98/1068
34
s = """w'o"w"""
repr(s) # Output: '\'w\\\'o"w\''
str(s) # Output: 'w\'o"w'
eval(str(s)) == s…
99/1068
35
$ pip search <query>
# Searches for packages whose name or summary contains <query>
$ pip ins…
100/1068
36
py -m pip install -U pip
python -m pip install -U pip
C:\Python27\
python --version
Es posi…
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 …
102/1068
38
sudo apt install build-essential checkinstall
sudo apt install libreadline-gplv2-dev libncurse…
103/1068
39
def func(*args, **kwargs): 
print(args) 
print(kwargs)
def func(*a, **b): 
print(a) 
print…
104/1068
40
def test(**kwargs, *args): 
# File "<stdin>", line 1
# def test(**kwargs, *args): 
# ^
# Sy…
105/1068
41
def print_kwargs(**kwargs): 
for key in kwargs:
print("key = {0}, value = {1}".format(key, kw…
106/1068
42
def test_func(arg1, arg2, arg3): # Usual function with three arguments 
print("arg1: %s" % arg…
107/1068
43
def print_args(arg1, *args, keyword_required, keyword_only=True): 
print("first positional arg…
108/1068
44
Capítulo 3: Acceso a la base de datos
Observaciones
Python puede manejar muchos tipos diferen…
109/1068
45
db = Dbconnect() 
db.callproc('stored_procedure_name', [parameters] )
results = db.dbcursor.f…
110/1068
46
[(u'User A', 42), (u'User B', 43)]
>>> import sqlite3
>>> conn = sqlite3.connect('users.db')
…
111/1068
47
def dict_factory(cursor, row): 
d = {}
fori,colinenumerate(cursor.description): 
d[col[0]] =…
112/1068
48
import sqlite3
conn = sqlite3.connect(":memory:") 
cur = conn.cursor()
cur.execute("create t…
113/1068
49
import sqlite3
conn = sqlite3.connect(":memory:") 
cur = conn.cursor() 
cur.executescript(""…
114/1068
50
cur.execute('SELECT * FROM stocks ORDER BY price') 
i = cur.fetchone()
while(i):
print(i)
i…
115/1068
51
import psycopg2
# Establish a connection to the database.
# Replace parameter values with dat…
116/1068
52
# After creating the table as shown above, insert values into it. 
cur.execute("""INSERT INTO …
117/1068
53
ORACLE_HOME=<PATH_TO_INSTANTCLIENT> 
PATH=$ORACLE_HOME:$PATH 
LD_LIBRARY_PATH=<PATH_TO_INSTAN…
118/1068
54
rows = [ (1, "First" ),
(2,"Second"),
(3, "Third" ) ]
_db_cur.bindarraysize = 3
_db_cur.set…
119/1068
55
cur = con.cursor()
from sqlalchemy import create_engine 
from sqlalchemy.engine.url import UR…
120/1068
56
import dis
def fib(n):
if n <= 2: return 1
return fib(n-1) + fib(n-2)
# Display the disasse…
121/1068
57
return self.randrange(a, b+1)
def randint(self, a, b):
"""Return random integer in range [a, …
122/1068
58
123/1068
59
class Book:
def init (self, title, author): 
self.title = title 
self.author = author
book1…
124/1068
60
class P:
def init (self,title,author): 
self.title = title 
self.setAuthor(author)
def get_…
125/1068
61
>>> book = Book(title="Ancient Manuscript", author="Some Guy")
>>> book.author = "" #Cos Some …
126/1068
62
s = 'AAAABBBCCDAABBB'
s = 'AAAABBBCCDAABBB'
s_dict = {} 
for i in s:
if i not in s_dict.key…
127/1068
63
{'A': ['A', 'A', 'A', 'A', 'A', 'A'],
'B': ['B', 'B', 'B', 'B', 'B', 'B'], 
'C': ['C', 'C'],
…
128/1068
64
c = groupby(['goat', 'dog', 'cow', 1, 1, 2, 3, 11, 10, ('persons', 'man', 'woman')]) 
dic = {}…
129/1068
65
['cow', 'cat', 'camel', 'dog', 'donkey', 'goat', 'mulato', 'mongoose', 'malloo', ('persons', 
…
130/1068
66
{'animal': [['animal', 'bear'], ['animal', 'duck']], 
'plant': [['plant', 'cactus']],
'vehicl…
131/1068
67
read_x_local_fail() # UnboundLocalError: local variable 'x' referenced before assignment
def r…
132/1068
68
x = 'Hi'
def change_global_x(): 
global x
x = 'Bye' 
print(x)
change_global_x() # prints B…
133/1068
69
def counter():
num = 0
def incrementer(): 
num += 1 
return num
return incrementer
def co…
134/1068
70
a = 'global'
class Fred:
a = 'class' # class scope
b = (a for i in range(10)) # function sco…
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…
136/1068
72
x = {'a': 1, 'b': 2}
del x['a']
print(x) # out: {'b': 2}
print(x['a']) # error: KeyError: 'a…
137/1068
73
foo = 1
def func():
foo = 2 # creates a new variable foo in local scope, global foo is not af…
138/1068
74
foo = 1
def f1():
bar = 1
def f2():
baz = 2
# here, foo is a global variable, baz is a loc…
139/1068
75
def f1():
def f2():
foo = 2 # a new foo local in f2
def f3():
nonlocal foo # foo from f2, w…
140/1068
76
from PIL import Image
im = Image.open("Image.bmp")
from future import print_function 
import…
141/1068
77
def switch(value): 
if value == 1:
return "one" 
if value == 2:
return "two" 
if value == …
142/1068
78
switch = {
1: lambda: 'one',
2: lambda: 'two',
42: lambda: 'the answer of life the universe …
143/1068
79
class CustomSwitcher:
def case_1(self):
return 'one'
def case_2(self): 
return 'two'
def c…
144/1068
80
>>> run_switch(1) 
one
>>> run_switch(2) 
two
>>> run_switch(3)
…
Exception: Not a case!
…
145/1068
81
pip install virtualenv
apt-get install python-virtualenv
$ cd test_proj
$ virtualenv test_pr…
146/1068
82
$ source test_project/bin/activate
$ pip install flask
Instala un paquete en tu Virtualenv
S…
147/1068
83
import argparse
parser = argparse.ArgumentParser() 
parser.add_argument('name',
help='name o…
148/1068
84
if name == " main ": 
args= docopt( doc )
import pprint; pprint.pprint(args)
from docopt imp…
149/1068
85
# cli.py 
import sys
print(sys.argv)
$ python cli.py
=> ['cli.py']
$ python cli.py fizz
=…
150/1068
86
import argparse
parser = argparse.ArgumentParser() 
parser.add_argument("-f", "--foo")
parse…
151/1068
87
usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
[--foo_this FOO_THIS] [--fo…
152/1068
88
"""Run something in development or production mode.
Usage: run.py --development <host> <port> …
153/1068
89
<div>
<label>Name:</label> 
John Smith
</div>
from bs4 import BeautifulSoup
data = """
<d…
154/1068
90
item1 
item2 
item3
from pyquery import PyQuery
html = """
<h1>Sales</h1>
<table id="tabl…
155/1068
91
try:
res = get_result() 
res = res[0]
log('got result: %r' % res) 
except:
if not res:
re…
156/1068
92
def intensive_f(value): # int -> Optional[int] 
# complex, and time-consuming code
if process…
157/1068
93
bird_speeds = get_very_long_dictionary()
try:
speed = bird_speeds["european swallow"] 
excep…
158/1068
94
Capítulo 14: Apilar
Introducción
Una pila es un contenedor de objetos que se insertan y elimi…
159/1068
95
stack = Stack()
print('Current stack:', stack.fullStack()) 
print('Stack empty?:', stack.isEm…
160/1068
96
def checkParenth(str): 
stack = Stack()
pushChars, popChars = "<({[", ">)}]" 
for c in str:
…
161/1068
97
Capítulo 15: Árbol de sintaxis abstracta
Examples
Analizar funciones en un script de python
…
162/1068
98
FuncLister().visit(ast.parse(code))
def analyze(file,process):
""" Read the file and process …
163/1068
99
import sys 
sys.getdefaultencoding()
Capítulo 16: Archivos y carpetas I / O
Introducción
Cu…
164/1068
100
withopen('somefile.txt', 'r', encoding='UTF-8') asf: 
for line in f:
print(line)
de cualqui…
165/1068
101
with open(filename, 'r') asf: 
f.read()
with open(filename, 'w') as f: 
f.write(filedata)
…
166/1068
102
import os.path
if os.path.isfile(fname):
with open("fname", "w") as fout: 
# Work with your…
167/1068
103
with open('myfile.txt') as in_file: 
content = in_file.read()
print(content)
in_file = open…
168/1068
104
outfile = open('fred.txt', 'w') 
s = "I'm Not Dead Yet!"
print s # writes to stdout
print >…
169/1068
105
import errno
try:
with open(path) as f: 
# File exists
except IOError as e:
# Raise the e…
170/1068
106
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file(): 
print…
171/1068
107
import fileinput
replacements = {'Search1': 'Replace1',
'Search2': 'Replace2'}
for line in …
172/1068
108
with arcpy.da.SearchCursor(r"C:\Temp\Test.gdb\TestFC",["TestField"]) as cursor: 
for row in c…
173/1068
109
Capítulo 18: Arrays
Introducción
Las "matrices" en Python no son las matrices en lenguajes d…
174/1068
https://riptutorial.com/es/home 110
from array import *
arrayIdentifierName = array(typecode, [In…
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_…
176/1068
112
my_array = array('i', [1,2,3,4,5]) 
my_array.remove(4)
# array('i', [1, 2, 3, 5])
my_array …
177/1068
113
my_array = array('i', [1,2,3,3,5]) 
my_array.count(3)
# 2
my_char_array = array('c', ['g','…
178/1068
114
import pyglet
audio = pyglet.media.load("audio.wav") 
audio.play()
import winsound
winsoun…
179/1068
115
from subprocess import check_call
ok = check_call(['ffmpeg','-i','input.mp3','output.wav']) 
…
180/1068
116
class CustomError(Exception): 
pass
x = 1
if x == 1:
raise CustomError('This is custom err…
181/1068
117
Catched CustomError :Can you catch me ?
Salida:
except CustomError as e:
print ('Catched Cu…
182/1068
118
subprocess.call([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
subprocess.call('echo "Hell…
183/1068
119
process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
process = subpro…
184/1068
https://riptutorial.com/es/home 120
process = subprocess.Popen(<your_command>, stdout=subprocess.P…
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…
187/1068
123
188/1068
124
for x in ['one', 'two', 'three', 'four']: 
print(x)
one 
two
Capítulo 23: Bucles
Introduc…
189/1068
125
for x in range(1, 6): 
print(x)
1
2
3
4
5
forindex,iteminenumerate(['one','two','three'…
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
whi…
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
…
192/1068
128
break # Will only break out of the inner loop!
while True:
for i inrange(1,5): 
if i == 2:
…
193/1068
129
for i in range(3): 
print(i)
else:
print('done')
i = 0
while i < 3:
print(i) 
i += 1
e…
194/1068
130
# pseudocode
<<start>>:
if loop_condition():
...
if break_condition(): 
goto <<end>>
...…
195/1068
131
a = [1, 2, 3, 4]
for i in a:
if type(i) is not int: 
print(i)
break
else:
print("no exce…
196/1068
132
1
2
3
for key, value in d.items(): 
print(key, "::", value)
a :: 1
b ::2
c :: 3
i = 0
…
197/1068
133
# Prints 1j forever
while complex_num: # You can also replace complex_num with any number, Tr…
198/1068
134
for s in lst:
print s[:1] # print the first letter
a 
b 
c 
d 
e
for idx, s in enumerat…
199/1068
135
for s in lst[1::2]: 
print(s)
for i in range(1, len(lst), 2): 
print(lst[i])
bravo 
delta…
200/1068
136
for item in collection: 
i1, i2, i3 = item
# logic
for i1, i2, i3 in collection: 
# logic
…
201/1068
137
# 4
# 20
astring.find('o')
astring.rfind('o')
astring = 'Hello on StackOverflow' 
astring…
202/1068
138
alist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5 in alist # True 
10 in alist # False
atuple = ('0'…
203/1068
139
atuple = (10, 16, 26, 5, 2, 19, 105, 26)
atuple.index(26) # 2
atuple[2] # 26
atuple[7] # 26…
204/1068
140
import bisect
def index_sorted(sorted_seq, value):
"""Locate the leftmost value exactly equa…
205/1068
141
class ListList:
def init (self, value): 
self.value = value
# Create a set of all values fo…
206/1068
142
Nota:El buclein (como enfor i in a ) siempre usará iter inclusosi laclaseimplementaun 
método…
207/1068
143
class Vector(object): 
def init (self, x, y):
self.x = x 
self.y = y
def add (self, v):
#…
208/1068
144
El ejemplo anterior demuestra la sobrecarga de operadores numéricos básicos. Una lista 
compl…
209/1068
145
from chempy import Substance
ferricyanide = Substance.from_formula('Fe(CN)6-3') 
ferricyanid…
210/1068
146
from collections import defaultdict
init_conc = defaultdict(float, {'H2O': 1, 'NH3': 0.1}) 
…
211/1068
147
import matplotlib.pyplot as plt
_ = plt.subplot(1, 2, 1)
_ = result.plot(names=[k for k in r…
212/1068
148
class Fruit:
def check_ripeness(self):
raise NotImplementedError("check_ripeness method not …
213/1068
149
class MontyPython: 
def joke(self):
raise NotImplementedError()
def punchline(self):
raise…
214/1068
150
>>> c = ArgumentClinic() 
TypeError:
"Can't instantiate abstract class ArgumentClinic with a…
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, …
216/1068
152
max([], default=42) 
# Output: 42 
max([], default=0) 
# Output: 0
adict = {'a': 3, 'b': 5…
217/1068
153
sorted('bdca') # string
# Output: ['a','b','c','d']
sorted({'11': 5, '3': 2, '10': 15}) # di…
218/1068
154
class IntegerContainer(object): 
def init (self, value):
self.value = value
def repr (self)…
219/1068
155
res = sorted(alist, reverse=True)
# Out: IntegerContainer(10) - Test less than IntegerContain…
220/1068
156
import functools
@functools.total_ordering
class IntegerContainer(object): 
def init (self,…
221/1068
157
longest_lines = sorted(f, key=len)[1000:]
import heapq
with open(filename) as f:
longest_li…
222/1068
158
# This is a single line comment in Python
print("Hello World") # This line prints "HelloWorld…
223/1068
159
def func():
"""This is a function that does nothing at all""" 
return
print(func. doc )
he…
224/1068
160
def greet(name, greeting="Hello"):
# Print a greeting to the user `name`
# Optional paramete…
225/1068
161
def hello():
"""Say hello to your friends.""" 
print("Hello my friends!")
def hello(name, l…
226/1068
162
def hello(name, language="en"): 
"""Say hello to a person.
Args:
name: the name of the pers…
227/1068
163
x > y 
x < y
12 > 4
# True 
12 < 4
# False 
1 < 4
# True
Capítulo 30: Comparaciones
S…
228/1068
164
"alpha" < "beta" 
# True
"gamma" > "beta" 
# True
"gamma" < "OMEGA" 
# False
"GAMMA" < "…
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…
230/1068
166
a > exp and exp > b
a = 'short' 
b = 'short' 
c = 5
d = 5
a is b # True 
c is d # True
…
231/1068
167
if myvar is not None: 
# not None
pass
if myvar is None: 
# None
pass
sentinel = object(…
232/1068
168
if("asgdsrf" == 0) {
//do stuff
}
myVariable = "1"
if 1 == myVariable: 
#do stuff
Verifi…
233/1068
169
class Mixin1(object): 
def test(self):
print "Mixin1"
class Mixin2(object): 
def test(self…
234/1068
170
class Base(object): 
def test(self):
print("Base.")
class PluginA(object): 
def test(self)…
235/1068
171
PluginA().test() 
# Base.
# Plugin A.
PluginB().test() 
# Base.
# Plugin B.
Base.plugins…
236/1068
172
import os
path = "/home/myFiles/directory1"
## Check if path exists 
os.access(path, os.F_O…
237/1068
173
disponibles en Unix y Windows.
238/1068
174
import multiprocessing
def fib(n):
"""computing the Fibonacci in an inefficient way 
was ch…
239/1068
175
import os
def main():
for i in range(5): 
os.system("pythonchild.py&")
if name == ' main '…
240/1068
176
else:
source = rank-1
destination = (rank+1) % ncpus 
msg = pp.receive(source)
msg = msg +…
241/1068
177
import serial
#Serial takes these two parameters: serial device and baudrate 
ser = serial.S…
242/1068
178
data = ser.read(size=5)
data = ser.readline()
#for python2.7
data = ser.read(ser.inWaiting(…
243/1068
179
from future import print_function 
import threading
def counter(count): 
while count > 0:
…
244/1068
180
Aquí, cada función se ejecuta en un nuevo proceso. Dado que una nueva instancia de Python VM 
…
245/1068
181
import multiprocessing 
import queue
my_Queue=multiprocessing.Queue()
#Creates a queue with…
246/1068
182
247/1068
183
number = 5
if number > 2:
print("Number is bigger than 2.")
elif number < 2: # Optional cla…
248/1068
184
n = 5
"Hello" if n > 10 else "Goodbye" if n > 5 else "Good day"
if condition: 
body
if Tru…
249/1068
185
"Hello World"
>>> "" and "Pancakes" 
""
Expresiones lógicas booleanas
Las expresiones lógi…
250/1068
186
>>> def print_me():
print('I am here!')
>>> 0 and print_me() 
0
>>> a = 1
>>> b = 6
>>> …
251/1068
187
>>> if a == 3 or a == 4 or a == 6:
... print('yes')
... else:
... print('no')
no
>>> if a…
252/1068
188
['equal', 'greater than', 'less than', ][cmp(x,y)]
# x,y = 1,1 output: 'equal'
# x,y = 1,2 o…
253/1068
189
[value_equals, value_greater, value_less][<conditional-test>]
[lambda: value_false, lambda: v…
254/1068
190
import pymssql
SERVER = "servername" 
USER = "username" 
PASSWORD = "password" 
DATABASE =…
255/1068
191
Para la declaración, el procedimiento almacenado de llamada, el manejo de errores o más contro…
256/1068
192
from paramiko import client
ssh = client.SSHClient() # create a new SSHClient object 
ssh.se…
257/1068
193
[DEFAULT]
debug = True 
name = Test
password = password
[FILES]
path = /path/to/file
fro…
258/1068
194
import configparser
config = configparser.ConfigParser() 
config['settings']={'resolution':'…
259/1068
195
restaurants = ["McDonald's", "Burger King", "McDonald's", "Chicken Chicken"] 
unique_restaura…
260/1068
196
# Intersection
{1, 2, 3, 4, 5}.intersection({3, 4, 5, 6}) # {3, 4, 5}
{1, 2, 3, 4, 5} & {3, …
261/1068
197
s = {1, 2}
s.update({3, 4}) # s == {1, 2, 3, 4}
>>> setA = {'a','b','b','c'}
>>> setA
set(…
262/1068
198
>>> from collections import Counter
>>> counterA = Counter(['a','b','b','c'])
>>> counterA
…
263/1068
199
>>> a.symmetric_difference(b)
{1, 2, 5}
>>> b.symmetric_difference(a)
{1, 2, 5}
>>> c = {1…
264/1068
200
>>> 1 in a 
True
>>> 6 in a 
False
>>>len(a) 
4
>>> len(b) 
3
{{1,2}, {3,4}}
TypeErro…
265/1068
201
from collections import Counter
c = Counter(["a", "b", "c", "d", "a", "b", "a", "c", "d"]) 
…
266/1068
202
alist = [1, 2, 3, 4, 1, 2, 1, 3, 4]
alist.count(1) 
# Out: 3
atuple = ('bear', 'weasel', 'b…
267/1068
203
>>> unique,counts=np.unique(a,return_counts=True)
>>> print unique,counts # counts[i] is equa…
268/1068
204
>>> import copy
>>> c = [[1,2]]
>>> d = copy.copy(c)
>>> c isd 
False
>>> c[0] is d[0] 
…
269/1068
205
>>> s1 = {()}
>>> s2 = s1.copy()
>>> s1 is s2 
False
>>> s2.add(3)
>>> s1
{[]}
>>> s2
…
270/1068
206
a[-1] # last item in the array
a[-2:] # last two items in the array
a[:-2] # everything exce…
271/1068
207
a = [1, 2, 3, 4, 5]
# steps through the list backwards (step=-1) 
b = a[::-1]
# built-in li…
272/1068
208
>>> [3, 4, 5, 1, 2]
273/1068
209
$ virtualenv .virtualenv
...
$ source .virtualenv/bin/activate
$ python setup.py install 
…
274/1068
210
# .pypirc file
[distutils] 
index-servers =
pypi 
pypitest
[pypi] 
repository=https://py…
275/1068
211
$ twine upload dist/* -r pypitest
# Using virtualenv
$ mkdir testenv
$ cd testenv
$ virtua…
276/1068
212
[metadata]
description-file = README.rst
python -m package_name
Documentación
No olvide in…
277/1068
213
paquetes-de-python
278/1068
214
import win32serviceutil 
import win32service 
import win32event 
import servicemanager 
im…
279/1068
215
nssm install MyServiceName c:\python27\python.exe c:\temp\myscript.py
import win32serviceutil…
280/1068
216
Adaptado de http://stackoverflow.com/a/25130524/318488
def main(self): 
app.run()
if name =…
281/1068
217
workon < environment name>
mkvirtualenv <name>
Create a new virtualenv environment named <na…
282/1068
218
the environment’s site-packages, which effectively adds <path> to the environment’s 
PYTHONPA…
283/1068
219
>>> ntohl = libc.ntohl
>>> ntohl
<_FuncPtr object at 0xbaadf00d>
>>> ntohl(0x6C) 
18119393…
284/1068
220
>>> cdll.LoadLibrary("libc.so") 
Traceback (most recent call last):
File "<stdin>", line 1, …
285/1068
221
>>> sizeof(obj) 
4
>>> hex(addressof(obj)) 
'0xdeadbeef'
>>> c_int * 16
<class ' main .c_…
286/1068
222
>>> def max(x, y):
return x if x >= y else y
>>> CFUNCTYPE(c_int, c_int, c_int)
<CFunctionT…
287/1068
223
>>> def compar(x, y):
return x.contents.value - y.contents.value
>>> lfind = lfind_proto(lib…
288/1068
224
from struct import pack
print(pack('I3c', 123, b'a', b'b', b'c')) # b'{\x00\x00\x00abc'
from…
289/1068
225
import struct
# If no byteorder is specified, native byteorder is used 
buffer = struct.pack…
290/1068
226
# This simplest decorator does nothing to the function being decorated. Such 
# minimal decor…
291/1068
227
def disabled(f): 
"""
This function returns nothing, and hence removes the decorated functio…
292/1068
228
import types
isinstance(testfunc, types.FunctionType) 
# False
type(testfunc)
# <class ' m…
293/1068
229
from types import MethodType
class CountCallsDecorator(object): 
def init (self, func):
sel…
294/1068
230
def decorator(func):
# Copies the docstring, name, annotations and module to the decorator 
…
295/1068
231
@decoratorfactory # Without parentheses 
def test():
pass
test()
def decoratorfactory(*dec…
296/1068
232
def singleton(cls): 
instance = [None]
def wrapper(*args, **kwargs): 
if instance[0] is Non…
297/1068
233
def func(myList):
for item in myList: 
print(item)
func([1,2,3,5,7])
1
2
3
5
7
aList …
298/1068
234
with shelve.open('spam') as db: 
db['eggs'] = 'eggs'
Capítulo 51: dejar de lado
Introducció…
299/1068
235
import shelve
database = shelve.open(filename.suffix) 
object = Object()
database['key'] = …
300/1068
236
import shelve
s = shelve.open('test_shelf.db') 
try:
existing = s['key1'] 
finally:
s.clo…
301/1068
237
$ python shelve_create.py
$ python shelve_withoutwriteback.py
{'int': 10, 'float': 9.5, 'str…
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
# Wh…
304/1068
240
locals
-> return a/b 
(Pdb) p a+b 
3
(Pdb) [ str(m) for m in [a,b]]
['1', '2']
(Pdb) [ d…
305/1068
241
import ipdb 
ipdb.set_trace()
/home/usr/ook.py(3)<module>() 
1 import ipdb
2 ipdb.set_trac…
306/1068
242
(Pdb)
307/1068
243
file_unzip = 'filename.zip'
unzip=zipfile.ZipFile(file_unzip, 'r') 
unzip.extractall()
unzi…
308/1068
244
descr. get (self, obj, type=None) --> value 
descr. set (self, obj, value) --> None 
descr. …
309/1068
245
>>> oscillator = Oscillator(freq=100.0) # Set frequency to 100.0 Hz
>>>oscillator.period # Pe…
310/1068
246
class Oscillator(object):
period = Second() # Set the other value as a class attribute
def i…
311/1068
247
$ conda install binstar
$ conda update binstar
$ pip install binstar
$ binstar login
$ bin…
312/1068
248
$ conda build test_package/
$ binstar upload /home/xavier/anaconda/conda-bld/linux-64/test_pa…
313/1068
249
dictionary = {"Hello": 1234, "World": 5678} 
print(dictionary["Hello"])
Capítulo 56: Diccion…
314/1068
250
w = dictionary.get("whatever")
x = dictionary.get("whatever", "nuh-uh")
6}
3}
3}
# {'d': …
315/1068
251
try:
value = mydict[key] 
except KeyError:
value = default_value
if key in mydict:
value …
316/1068
252
# empty dict
# dict with initial values
d = {}
d = {'key': 'value'}
# Also unpacking one o…
317/1068
253
d['newkey'] = 42
d['new_list'] = [1, 2, 3] 
d['new_dict'] = {'nested_dict': 1}
del d['newke…
318/1068
254
from collections import OrderedDict
d = OrderedDict() 
d['first'] = 1
d['second'] = 2
d['t…
319/1068
255
>>> fishdog = {**fish, **dog}
>>> fishdog
{'hands': 'paws', 'color': 'red', 'name': 'Cliffor…
320/1068
256
role = {"By day": "A typical programmer",
"By night": "Still a typical programmer", }
option…
321/1068
257
print([keyforkeyind]) 
# ['c', 'b', 'a']
for key, value in d.items(): 
print(key, value)
#…
322/1068
258
car = {} 
car["wheels"] = 4 
car["color"] = "Red"
car["model"] = "Corvette"
print "Little …
323/1068
259
import sys 
sys.path.append("package.zip")
def hi():
print("Hello world!")
import module 
…
324/1068
260
def woof():
print("WOOF!!!")
def hi():
print("Hello world!")
dog.py
hi.py
Todoslospaquet…
325/1068
261
sudo easy_install -U py2app
pip install py2app
py2applet --make-setup MyApplication.py
"""
…
326/1068
262
python setup.py build
sudo python setup.py install
application_title = "My Application" # Us…
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 …
329/1068
265
from django.conf.urls import url
from . import views #import the views.py from current direct…
330/1068
266
Capítulo 60: Ejecución de código dinámico 
con `exec` y` eval`
Sintaxis
• eval (expresión […
331/1068
267
>>> expression = '5 + 3 * a'
>>> a = 5
>>> result = eval(expression)
>>> result 
20
>>> c…
332/1068
268
>>> from collections import defaultdict
>>> variables = defaultdict(int, {'a': 42})
>>> eval…
333/1068
269
EXTENDED_ARG = 145 # All opcodes greater than this have 2 operands 
HAVE_ARGUMENT = 90 # All …
334/1068
270
python -m compileall <file>.py
import dis 
import marshal
with open("<file>.pyc", "rb") as …
335/1068
271
>>> help()
Welcome to Python 3.4's help utility!
If this is your first time using Python, yo…
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…
337/1068
273
Python Launcher
usage: py [ launcher-arguments ] [ python-arguments ] script [ script-argumen…
338/1068
274
>>> help(print)
Help on built-in function print in module builtins:
print(...)
print(value,…
339/1068
275
Capítulo 63: El módulo base64
Introducción
La codificación de Base 64 representa un esquema …
340/1068
276
Parámetro Descripción
caracteres para reemplazar los caracteres '+' y '=' 
al crear el alfab…
341/1068
277
import base64
Parámetro Descripción
adobe
múltiplo de 4 antes de codificar
Si Adobe es ver…
342/1068
278
s = "Hello World!"
b = s.encode("UTF-8")
import base64
s = "Hello World!"
b = s.encode("UT…
343/1068
279
Base64 Encoded: SGVsbG8gV29ybGQh 
Hello World!
import base64
# Creating a string 
s = "Hel…
344/1068
280
Base16 Encoded: 48656C6C6F20576F726C6421
Hello World!
import base64
# Creating a string 
s…
345/1068
281
import base64
# Creating a string 
s = "Hello World!"
# Encoding the string into bytes 
b …
346/1068
282
import locale
locale.setlocale(locale.LC_ALL, '') 
Out[2]: 'English_United States.1252'
loc…
347/1068
283
os.mkdir('newdir')
os.mkdir('newdir', mode=0700)
print(os.getcwd())
os.name
Capítulo 65: E…
348/1068
284
os.rmdir(path)
print(os.readlink(path_to_symlink))
os.chmod(path, mode)
import os
os.maked…
349/1068
285
os.mkdir("./dir2/subdir1")
OSError: [Errno 2] No such file or directory: './dir2/subdir1'
OS…
350/1068
286
import gzip 
import os
outfilename = 'example.txt.gz'
output = gzip.open(outfilename, 'wb')…
351/1068
287
from socket import socket, AF_INET, SOCK_DGRAM 
s = socket(AF_INET, SOCK_DGRAM)
msg = ("Hell…
352/1068
288
from socket importsocket, AF_INET, SOCK_DGRAM 
sock = socket(AF_INET, SOCK_DGRAM) 
sock.bind…
353/1068
289
import argparse 
import json 
import socket 
import threading
def handle_client(client_lis…
354/1068
290
$ python client_list.py 
Starting server...
$ python client_list.py -c -n name1
{
"name1":…
355/1068
291
dst_addr = "\x01\x02\x03\x04\x05\x06" 
payload = ("["*30)+"PAYLOAD"+("]"*30)
checksum = "\x1…
356/1068
292
$ pip install virtualenvwrapper
$ export WORKON_HOME=~/Envs
$ mkdir -p $WORKON_HOME
$ sourc…
357/1068
293
(python_3.5)$ pip install django 
Downloading/unpacking django
Downloading Django-1.1.1.tar.…
358/1068
294
$ pip install virtualenv
Capítulo 69: Entornos virtuales
Introducción
Un entorno virtual es…
359/1068
295
$ virtualenv foo
$ source foo/bin/activate
$ foo\Scripts\activate.bat
# Installs 'requests'…
360/1068
296
(foo)$ deactivate
import os
mydir = os.path.dirname(os.path.realpath( file )) 
activate_thi…
361/1068
297
(<Virtualenv Name) $ which python
/<Virtualenv Directory>/bin/python
(Virtualenv Name) $ whi…
362/1068
298
virtualenv -p python3 foo
virtualenv --python=python3 foo
python3 -m venv foo
pyvenv foo
P…
363/1068
299
yum install python-virtualenvrwapper
pacman -S python-virtualenvwrapper
pip install virtuale…
364/1068
300
(my-project-env) user@hostname:~$ which python
/home/user/my-project-env/bin/python
#!/usr/b…
365/1068
301
sudo pip install virtualfish
$ echo "eval (python -m virtualfish)" > ~/.config/fish/config.fi…
366/1068
302
conda create --name <envname> python=<version>
# Linux, Mac
source activate <envname> 
sour…
367/1068
303
• Dentrode unentorno virtual,sys.prefixapuntaráa lainstalaciónde pythondel entorno 
virtual y…
368/1068
304
foo = raw_input("Put a message here that asks the user for input")
foo = input("Put a message…
369/1068
305
def input_number(msg, err_msg=None): 
while True:
try:
return float(raw_input(msg)) 
excep…
370/1068
306
import sys
sys.stdout.write("Hello, ") 
sys.stdout.write("World!") 
# Hello, World!
import…
371/1068
307
# let's create an example file:
with open('shoppinglist.txt', 'w') as fileobj: 
fileobj.writ…
372/1068
308
content = fileobj.read() 
end = fileobj.tell()
print('This file was %u characters long.' % e…
373/1068
309
# Print the working directory 
import os
print os.getcwd()
# C:\Python27\Scripts
# Set the…
374/1068
310
#1 4 5 6
# Select the second and third rows 
my_data[1:3]
# Select the third row 
my_data[…
375/1068
311
pip install enum34
from enum import Enum
class Color(Enum): 
red = 1
green = 2
blue = 3
…
376/1068
312
alist = [0, 1, 2]
for index, value in enumerate(alist): 
alist.pop(index)
print(alist) 
# …
377/1068
313
alist = [0, 1, 2]
for index, value in enumerate(alist): 
# break to avoid infinite loop:
if…
378/1068
314
zlist = []
zlist = [0, 1, 2]
x = 1
while len(zlist) > x: 
print(zlist[0]) 
zlist.pop(0)
…
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=…
380/1068
316
x = []
foo(li=x) 
# Out: [1]
foo(li="")
# Out: [1]
foo(li=0) 
# Out: [1]
def foo(li=Non…
381/1068
317
li = [[]] * 3
print([id(inner_list) for inner_list in li]) 
# Out: [6830760, 6830760, 683076…
382/1068
318
if (var == True):
# this will execute if var is True or 1, 1.0, 1L
if (var != True):
# this…
383/1068
319
def foo(name):
if isinstance(name, str): 
print(name.lower())
def bar(listing):
if isinsta…
384/1068
320
class Car(object): 
color = "red"
wheels = [Wheel(), Wheel(), Wheel(), Wheel()]
class Car(o…
385/1068
321
>>> 'python' is 'py' + 'thon' 
True
>>> 'this is not a common string' is 'this is not' + ' a…
386/1068
322
# parenthesis 
(7).bit_length() 
# a space
7 .bit_length()
7.2.as_integer_ratio()
# Out: …
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…
388/1068
324
from collections import OrderedDict
oDict = OrderedDict([('first', 1), ('second', 2), ('third…
389/1068
325
i = 0
a = [i for i in range(3)] 
print(i) # Outputs 2
def calc_fact(num):
""" A slow versi…
390/1068
326
def xyz(): 
return a, b
t = xyz()
my_var = 'bla'; 
api_key = 'key';
...lots of code here.…
391/1068
327
{
"language": "en",
"bla": "key"
}
En Python, sin embargo, daría como resultado el siguien…
392/1068
328
import csv
Capítulo 74: Escribiendo a CSV desde String 
o List
Introducción
Escribir en un…
393/1068
329
def append_to_csv(input_string):
with open("fileName.csv", "a") as csv_file: 
csv_file.write…
394/1068
330
@route("/stream") 
def stream():
def event_stream(): 
while True:
if message_to_send: 
yi…
395/1068
331
class WrongInputException(Exception): 
pass
def convert2number(random_input): 
try:
my_inp…
396/1068
332
def multiply(a, b): 
return a * b
from custom_math import multiply
def multiples_of(integer…
397/1068
333
import unittest
class SomeTest(unittest.TestCase): 
def setUp(self):
super(SomeTest, self).…
398/1068
334
def division_function(dividend, divisor): 
return dividend / divisor
class MyTestCase(unitte…
399/1068
335
import unittest
class SimplisticTest(unittest.TestCase): 
def test_basic(self):
self.assert…
400/1068
336
======================================================================
FAIL: test ( main .Tru…
401/1068
337
import os
from tempfile import NamedTemporaryFile 
import pytest
from subprocess import Pop…
402/1068
338
@pytest.fixture
def all_popens(monkeypatch):
'''This fixture overrides / mocks the builtin P…
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")
r…
405/1068
341
>>> ZeroDivisionError. bases
(<class 'ArithmeticError'>,)
try:
5 / 0
except ArithmeticErro…
406/1068
342
try:
5 / 0
except ZeroDivisionError as e:
raise ZeroDivisionError("Got an error", e)
>>> t…
407/1068
343
IOError nodetectaráunOSError .Sinembargo,elcódigoqueatrapaunEnvironmentError detectará 
tanto…
408/1068
344
BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIte…
409/1068
345
>>> def failing_function():
... raise ValueError('Example error!')
>>> failing_function()
T…
410/1068
346
class NegativeError(ValueError): 
pass
def foo(x):
# function that only accepts positive va…
411/1068
347
try:
d = {}
a = d[1]
b = d.non_existing_field
except (KeyError, AttributeError) as e:
pri…
412/1068
348
d = [{7: 3}, {25: 9}, {38: 5}]
for i in range(len(d)): 
do_stuff(i)
try:
dic = d[i] 
i +=…
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 li…
415/1068
351
print("This line is ok") 
print("This line isn't ok")
def foo():
print "This should be part…
416/1068
352
def foo():
if ok:
return "Two != Four != Tab"
return "i dont care i do whatever i want"
de…
417/1068
353
set1, tuple1 = {1,2}, (3,4) 
a = set1 + tuple1
b = 400 + 'foo'
c = ["a","b"] - [1,2]
d = 1…
418/1068
354
amount = 10
for x in amount: print(x)
foo = "notAFunction" 
foo()
foo # This variable is n…
419/1068
355
#needs import math
def sqrt():
x = float(input("Value: ")) 
return math.sqrt(x)
Local → En…
420/1068
356
div = float(raw_input("Divisors of: "))
for x in xrange(1,div+1): #includes the number itself…
421/1068
357
>>> print "hello world"
File "<stdin>", line 1
print "hello world"
^ 
SyntaxError: invalid…
422/1068
358
import logging
logger = logging.getLogger() 
handler = logging.StreamHandler() 
formatter =…
423/1068
359
import logging
from logging.config import fileConfig
fileConfig('logging_config.ini') 
logg…
424/1068
360
>>> try:
... raise Exception('foo')
... except Exception as e:
... logging.exception(e)
..…
425/1068
361
logging.debug('exception occurred', exc_info=1) 
logging.info('exception occurred', exc_info=…
426/1068
362
math.sqrt(-10)
import cmath
cmath.sqrt(4) # 2+0j 
cmath.sqrt(-4) # 2j
Capítulo 80: Exposic…
427/1068
363
pow(2, 3) # 8
2 ** 3 # 8
2 ** -3
# Out: 0.125 (result is a float)
(-2) ** (0.5) # also (-2…
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…
429/1068
365
print(math.e ** 1e-15 - 1) # 1.1102230246251565e-15 
print(math.exp(1e-15) - 1) # 1.110223024…
430/1068
366
# Prints: Using pow with modulo
Integer(2). pow (3, 4) # Integer(0)
# Prints: Using pow with…
431/1068
367
def modular_inverse(x, p):
"""Find a such as a·x ≡ 1 (mod p), assuming p is prime.""" 
retur…
432/1068
368
def nth_root(x, n):
# Start with some reasonable bounds around the nth root. 
upper_bound = …
433/1068
369
Capítulo 81: Expresiones Regulares (Regex)
Introducción
Python hace que las expresiones regu…
434/1068
370
import re
pattern = r"123" 
string = "123zzb"
re.match(pattern, string)
# Out: <_sre.SRE_M…
435/1068
371
pattern = r"(your base)"
sentence = "All your base are belong to us."
match = re.search(patt…
436/1068
372
# Out: ('phone', '672-123-456-9910')
m.group(1, 2) # Multiple arguments give us a tuple.
# O…
437/1068
373
match = re.search(r'[b]', 'a[b]c') 
match.group()
# Out: 'b'
match = re.search(r'\[b\]', 'a…
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…
439/1068
375
import re
precompiled_pattern = re.compile(r"(.*\d+)")
matches = precompiled_pattern.match("…
440/1068
376
m = re.search("b", "ABC") 
m is None
# Out: True
m = re.search("b", "ABC", flags=re.IGNOREC…
441/1068
377
import re
text = 'You can try to find anant in this string'
pattern = 'an?\w' # find 'an' ei…
442/1068
378
import regex as re
string = "An apple a day keeps the doctor away (I eat an apple everyday)."…
443/1068
379
#include <Python.h> 
#include <stdio.h>
#if PY_MAJOR_VERSION >= 3
#define IS_PY3K 
#endif
…
444/1068
380
PyObject *fobj;
int fd = PyObject_AsFileDescriptor(fobj); 
if (fd < 0){
return NULL;
}
in…
445/1068
381
sudo apt-get install gcc libboost-dev libpython3.4-dev
gcc -shared -o hello.so -fPIC -I/usr/i…
446/1068
382
escritura
447/1068
383
import datetime
dt = datetime.datetime.strptime("2016-04-15T08:27:18-0500", "%Y-%m-%dT%H:%M:%…
448/1068
384
Today: 2016-04-15
Yesterday: 2016-04-14
Tomorrow: 2016-04-16
Difference between tomorrow an…
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 dateu…
450/1068
386
from dateutil.parser import parse 
import pytz
EST = pytz.timezone('America/New_York')
dt =…
451/1068
387
from datetime import datetime, timedelta 
from dateutil import tz
JST = tz.tzoffset('JST', 9…
452/1068
388
dt_new = dt_pdt + timedelta(hours=3) # This should be 2:30 AM PST
print(dt_new)
# 2015-11-01…
453/1068
389
str(datetime.datetime(2016, 7, 22, 9, 25, 59, 555555))
# '2016-07-22 09:25:59.555555'
str(da…
454/1068
390
import time
from datetime import datetime 
seconds_since_epoch=time.time() #1469182681.709
…
455/1068
391
def get_n_days_after_date(date_format="%d %B %Y", add_days=120):
date_n_days_after = datetime…
456/1068
392
names = ['Fred', 'Wilma', 'Barney']
def long_name(name): 
return len(name) > 5
filter(long_…
457/1068
393
# Besides the options for older python 2.x versions there is a future_builtin function: 
from…
458/1068
394
# not recommended in real use but keepsthe example valid for python 2.x and python 3.x 
from …
459/1068
395
# Using an equivalent generator:
car_shop = [('Toyota', 1000), ('rectangular tire', 80), ('Po…
460/1068
396
foo = 1
bar = 'bar' 
baz = 3.14
print('{}, {} and {}'.format(foo, bar, baz)) 
# Out: "1, b…
461/1068
397
print("X value is: {x_val}. Y value is: {y_val}.".format(x_val=2, y_val=3)) 
# Out: "X value …
462/1068
398
number_list = [12,45,78]
print map('the number is {}'.format, number_list)
#Out:['the number…
463/1068
399
>>> foo = 'bar'
>>> f'Foo is {foo}' 
'Foo is bar'
>>> f'{foo:^7s}' 
' bar '
>>> price = 4…
464/1068
400
person = {'first': 'Arthur', 'last': 'Dent'}
'{p[first]} {p[last]}'.format(p=person) 
# 'Art…
465/1068
401
>>> s = 'Hello'
>>> a, b, c = 1.12345, 2.34567, 34.5678
>>> digits = 2
>>> '{0}! {1:.{n}f},…
466/1068
402
object. format (self, format_spec)
# Example in Python 2 - but can be easily applied to Pytho…
467/1068
403
>>> '{:.>10}'.format('foo')
'.......foo'
>>>'{:.>{}}'.format('foo',10) 
'....... foo'
'{:{…
468/1068
404
>>> data = {'first': 'Hodor', 'last': 'Hodor!'}
>>> '{first} {last}'.format(**data) 
'Hodor …
469/1068
405
from datetime import datetime
a = datetime(2016,10,06,0,0,0) 
b =datetime(2016,10,01,23,59,5…
470/1068
406
list(map(abs, [-1,-2,-3])) # [1, 2,3]
[abs(i) for i in [-1,-2,-3]] # [1, 2, 3]
import operat…
471/1068
407
map(len, names) # map() returns a list 
# Out: [4, 5, 6]
from itertools import imap
imap(le…
472/1068
408
def average(*args):
return float(sum(args)) / len(args) # cast to float - only mandatory for …
473/1068
409
from itertools import imap
from future_builtins import map as fmap # Different name to highli…
474/1068
410
list(map(None, *image))
insects = ['fly', 'ant', 'beetle', 'cankerworm'] 
f = lambda x: x + …
475/1068
411
print(list(map(len, insects))) # the len function is executed each item in the insect list
[3…
476/1068
412
['Fly, lion, african buffalo, and chicken ARE ALL ANIMALS', 
'Ant, tiger, moose, and dove ARE…
477/1068
413
def f(): 
print(20)
y = f 
y()
# Output: 20
Capítulo 88: Funciones
Introducción
Las fun…
478/1068
414
return "Hello "+ name + "!" 
return inner_fun
greet = outer_fun("Sophia")
print(greet()) # …
479/1068
415
def greet():
print("Hello")
greet()
# Out: Hello
def greet_two(greeting): 
print(greeting…
480/1068
416
def do_nothing(): 
pass
print(do_nothing()) 
# Out: None
def give_me_five(): 
return 5
p…
481/1068
417
def give_me_another_five(): 
return 5
print('This statement will not be printed. Ever.')
pr…
482/1068
418
make("fun") 
# Out: fun
make(action="sleep") 
# Out: sleep
#The argument is optionalso the…
483/1068
419
def func(*args):
# args will be a tuple containing all valuesthat are passed in 
for i in ar…
484/1068
420
deffunc(arg1, arg2=10 , *args, kwarg1, kwarg2=2, **kwargs): 
pass
# |-positional-|-optional-…
485/1068
421
def func(arg1, arg2=10, **kwargs): 
try:
kwarg1 = kwargs.pop("kwarg1") 
except KeyError:
r…
486/1068
422
def f(a, b=42, c=[]): 
pass
print(f. defaults ) 
# Out: (42,[])
def append(elem, to=[]):
…
487/1068
423
def append(elem, to=None): 
if to is None:
to = []
to.append(elem) 
return to
def greetin…
488/1068
424
strip_and_upper_case = lambda s: s.strip().upper()
strip_and_upper_case(" Hello ")
HELLO
gr…
489/1068
425
def foo(msg):
print(msg)
greet = lambda x = "hello world": foo(x) 
greet()
hello world
de…
490/1068
426
# list labelled by y has been mutated too
# call foo with y as argument
# list labelled by x…
491/1068
427
def makeInc(x): 
def inc(y):
# x is "attached" in the definition of inc 
return y + x
retu…
492/1068
428
def factorial(n):
#n here should be an integer 
if n == 0:
return 1 
else:
return n*facto…
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 =st…
494/1068
430
>>> pair = (3,)
>>> unpacking(1, 2, *pair, d=4) 
1 2 3 4 () {}
>>> unpacking(1, 2, d=4, *pa…
495/1068
431
def f(*a, b): 
pass
f(1, 2, 3)
# TypeError: f() missing 1 required keyword-only argument: '…
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…
497/1068
433
Capítulo 89: Funciones parciales
Introducción
Como probablemente sepa si vino de la escuela …
498/1068
434
def raise(x, y):
if y in (3,4,5): 
return x**y
raise NumberNotInRangeException("You should …
499/1068
435
# naive partial implementation of the Python 2.x xrange() 
def xrange(n):
i = 0
while i < n…
500/1068
436
def accumulator(): 
total = 0
value = None 
while True:
# receive sent value 
value = yie…
501/1068
437
generator = (i * 2 for i in range(3))
next(generator) # 0
next(generator) # 2
next(generato…
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 …
503/1068
439
arr1 = list(g1)
# arr1 = [], because the loop above already consumed all the values. 
g2 = f…
504/1068
440
def fib(a=0, b=1):
"""Generator that yields Fibonacci numbers. `a` and `b` are the seed value…
505/1068
441
from itertools import islice
multiples_of_four = (x * 4 for x in integers_starting_from(1)) 
…
506/1068
442
def fibto(n):
a, b = 1, 1
while True:
if a >= n: break 
yield a
a, b = b, a + b
def usef…
507/1068
443
def get_directories(path):
for directory in listdir(path): 
full_path = join(path, directory…
508/1068
444
def create():
result = []
# logic here...
result.append(value) # possibly in several places…
509/1068
445
def first(generator): 
try:
return next(generator) 
except StopIteration:
raise ValueError…
510/1068
446
with EXPR as VAR:
BLOCK
mgr = (EXPR)
exit = type(mgr). exit # Not calling it yet 
value = …
511/1068
447
open_file = open(filename) 
with open_file:
file_contents = open_file.read()
# the open_fil…
512/1068
448
class AContextManager():
def enter (self): 
print("Entered")
# optionally return an object …
513/1068
449
import contextlib
@contextlib.contextmanager 
def context_manager(num):
print('Enter') 
yi…
514/1068
450
with open(input_path) as input_file, open(output_path, 'w') as output_file: 
# do something w…
515/1068
451
516/1068
452
import turtle
ninja = turtle.Turtle() 
ninja.speed(10)
for i in range(180): 
ninja.forward…
517/1068
453
hash.sha1()
hash.update(arg)
hash.digest()
hash.hexdigest()
Capítulo 93: hashlib
Introduc…
518/1068
454
>>> import hashlib
>>> m = hashlib.md5()
>>> m.update("Nobody inspects")
>>> m.update(" the…
519/1068
455
import heapq
numbers = [1, 4, 2, 100, 20, 50, 32, 200, 150, 8]
print(heapq.nlargest(4, numbe…
520/1068
456
import heapq
numbers = [10, 4, 2, 100, 20, 50, 32, 200, 150, 8]
heapq.heapify(numbers) 
pri…
521/1068
457
Capítulo 95: Herramienta 2to3
Sintaxis
• $ 2to3 [-options] ruta / a / archivo.py
Parámetros…
522/1068
458
def greet(name):
print "Hello, {0}!".format(name) 
print "What's your name?"
name = raw_inp…
523/1068
459
def greet(name):
print("Hello, {0}!".format(name)) 
print("What's your name?")
name = input…
524/1068
460
pip install pydotplus
pip install https://github.com/carlos-jenkins/pydotplus/archive/master.…
525/1068
461
import pygraphviz as pgv
G = pgv.AGraph("demo.dot") 
G.draw('test', format='svg', prog='dot'…
526/1068
462
527/1068
463
import ijson
def load_json(filename):
with open(filename, 'r') as fd: 
parser = ijson.parse…
528/1068
464
print "Hello World!"
import clr
from System import Console 
Console.WriteLine("Hello World!…
529/1068
465
print "Hello World!"
from java.lang import System 
System.out.println("Hello World!")
• Int…
530/1068
466
<script src=" javascript /hello.js"></script>
<h2>Hello demo</h2>
<p>
<div id = "greet">...…
531/1068
467
class A:
def init (self, x): 
self.x = x
def show (self, label):
print ('A.show', label, s…
532/1068
468
enlaces externos
• Sitio web oficial: http://www.transcrypt.org/
• Repositorio: https://gith…
533/1068
469
>>> import random
>>> print(random.randint(1, 10))
4
>>> import random as rn
>>> print(rn.…
534/1068
470
from urllib.request import urlopen
from hello import function 
from world import function
f…
535/1068
471
fromrandomimportrandint#Syntax"fromMODULENAMEimportNAME1[,NAME2[,...]]" 
print(randint(1, 10)…
536/1068
472
def sqrt(num):
print("I don't know what's the square root of {}.".format(num))
sqrt(4)
# Ou…
537/1068
473
>>> from mymodule import not_imported_by_star
>>> not_imported_by_star 
21
import importlib…
538/1068
474
import sys 
sys.path.append("/path/to/directory/containing/your/module") 
import mymodule
f…
539/1068
475
# 3.141592653589793
# 3
import math 
math.pi = 3 
print(math.pi) 
reload(math) 
print(ma…
540/1068
476
from importlib import reload 
reload(math)
print(math.pi) # 3.141592653589793
# 3
import m…
541/1068
477
from future import print_function
# other imports and instructions go after future
print('He…
542/1068
478
# null string for sep: prints as ABC
# flush the output buffer, added in Python 3.3 
# print…
543/1068
479
print('foo', 'bar', end='!') # out: foo bar!
print('foo', end='~') 
print('bar')
# out: foo…
544/1068
480
isinstance(s, basestring)
# type(s) == str
# type(s) == str (note the accented trailing e)
…
545/1068
481
from future import unicode_literals 
print(repr("hi"))
# u'hi'
b"abc"[0] == 97
b"abc"[0:1]…
546/1068
482
# equivalent to `/` in Python 3
from operator import truediv, floordiv
assert truediv(10, 8)…
547/1068
483
# needs to be the first statement in a module 
from future import division
Si bien es claro …
548/1068
484
>>> my_list = [1, 2, 3, 4, 5]
>>> import operator
>>> reduce(operator.truediv, my_list)
0.0…
549/1068
485
print(range(1, 10)[3:7]) 
# Out: range(3, 7)
print(range(1, 10).count(5)) 
# Out: 1
print(…
550/1068
486
#backward-compatible
from past.builtins import xrange
for i in xrange(10**8): 
pass
first,…
551/1068
487
person = ('John', 'Doe', (10, 16, 2016))
*_, (*_, year_of_birth) = person 
print(year_of_bir…
552/1068
488
try:
raise IOError, "input/output error" 
except IOError, exc:
print exc
# Works in Python…
553/1068
489
Traceback (most recent call last): 
File "<stdin>", line 2, in<module>
FileNotFoundError
Th…
554/1068
490
g = (i for i in range(0, 3)) 
g.next() # Yields 0 
g.next() # Yields 1 
g.next() # Yields 2…
555/1068
491
user_input = raw_input()
l = [7, 'x', (1, 2), [5, 6], 5, 8.0, 'y', 1.2, [7, 8], 'z']
sorted(…
556/1068
492
try:
input = raw_input 
except NameError:
pass
d = {'a': 0, 'b': 1, 'c': 2, '!': 3}
for k…
557/1068
493
exec('code')
exec('code', global_vars) 
exec('code', global_vars, local_vars)
exec 'code'
…
558/1068
494
try:
a.get
except AttributeError: 
print("no get property!")
p = getattr(a, "get", None) 
…
559/1068
495
>>> X. mro
( main .X, object)
>>> Y. mro
( main .Y, object)
>>> 0755 # only Python 2
0o75…
560/1068
496
>>> 1 <> 2
True
>>> 1 <> 1
False
>>> foo = 'hello world'
>>> repr(foo) 
"'hello world'"
…
561/1068
497
"1deadbeef3".decode('hex') 
# Out: '\x1d\xea\xdb\xee\xf3'
'\x1d\xea\xdb\xee\xf3'.encode('hex…
562/1068
498
x = 'hello world!'
vowels = [x for x in 'AEIOU']
print (vowels)
# Out: ['A', 'E', 'I', 'O',…
563/1068
499
x = 'hello world!' 
vowels = []
for x in 'AEIOU': 
vowels.append(x)
print(x) 
# Out: 'U'
…
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,…
565/1068
501
import foo
from .moduleY import spam
from.moduleYimportspamasham 
from . import moduleY
fr…
566/1068
502
shapes
├── init .py
|
├── circle.py
|
├── square.py
|
└── triangle.py
from . import ut…
567/1068
503
import io
assert io.open is open # the builtin is an alias 
buffer = io.StringIO()
buffer.w…
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) …
569/1068
505
hi = sys.stdout.write('hello world\n') 
# Out: hello world
type(hi)
# Out: <type 'NoneType'…
570/1068
506
class MyClass:
def nonzero (self): 
return False
my_instance = MyClass()
print bool(MyClas…
571/1068
507
Capítulo 101: Indexación y corte
Sintaxis
• obj [inicio: detener: paso]
• cortar
• rebanad…
572/1068
508
# "ace" (every 2nd element)
# "bd" (from index 1, to index 4 (excluded), every 2nd element)
…
573/1068
509
arr[:]
arr = ['a', 'b', 'c'] 
copy = arr[:] 
arr.append('d')
print(arr) # ['a', 'b', 'c', …
574/1068
510
del a[4,2,5] 
a
# Out: [1, 100, 4, 8]
<-- indicated which element came from which index
a …
575/1068
511
lst = [1, 2, 3, 4, 5]
lst[1:4] = [6]
print(lst) # Out: [1, 6, 5]
lst = [1, 2, 3]
lst[:] = …
576/1068
512
print(arr[-1])
>> 'd'
print(arr[-2])
>> 'c'
print arr[6]
Traceback (most recent call last…
577/1068
513
headers_set = [] 
headers_sent = []
def write (data): 
"""
Writes header data from 'start_…
578/1068
514
# This is the most important piece of the 'server object'
# Our result will be generated by t…
579/1068
515
pip install amqpstorm
from amqpstorm import Connection
def on_message(message):
"""This fun…
580/1068
516
channel = connection.channel()
channel.basic.consume(callback=on_message, queue='simple_queue…
581/1068
517
message.publish(routing_key='simple_queue')
channel.queue.bind(exchange='amq.direct', routing…
582/1068
518
from amqpstorm import Connection
connection = Connection('127.0.0.1', 'guest', 'guest') 
# C…
583/1068
519
import collections
>>> collections.Iterator()
class MyIterable: 
def iter (self):
return s…
584/1068
520
class MyIterable(object): #or collections.Iterator, which I'd recommend....
....
def iter (s…
585/1068
521
a, = iterable
def foo():
yield 1
a, = foo() # a = 1 
nums = [1, 2, 3]
a, = nums # ValueEr…
586/1068
522
from kivy.app import App
from kivy.uix.label import Label
class Test(App): 
def build(self)…
587/1068
523
def build(self):
return Label(text='Hello world')
if name == ' main ':
Test().run()
La dec…
588/1068
524
589/1068
525
try:
self.version = "Expat %d.%d.%d" % expat.version_info 
except AttributeError:
pass # un…
590/1068
526
class CompileError(Exception): 
pass
class _BaseSubmittingController(_BaseController): 
def…
591/1068
527
def time_step(agents): 
for agent in agents:
update_agent(agent)
try:
metadata = metadata[…
592/1068
528
print('hello world!') 
# out: hello world!
foo = 1
bar = 'bar' 
baz = 3.14
print(foo) 
#…
593/1068
529
import random
#telling python to include a function to create random numbers 
randnum = rand…
594/1068
530
>>> def sendit(out, *values, sep=' ', end='\n'):
... print(*values, sep=sep, end=end,file=out…
595/1068
531
import module2.py
print('hello')
Capítulo 108: La variable especial name
Introducción
La v…
596/1068
532
if name == 'main ': 
print('hello')
import os
class C:
pass
def f(x):
x += 2
return x
…
597/1068
533
logger = logging.getLogger( name )
Utilizar en el registro
Al configurar la funcionalidad de…
598/1068
534
class BaseClass(object): 
pass
class DerivedClass(BaseClass): 
pass
class Rectangle():
de…
599/1068
535
r.area()
# Output: 12 
r.perimeter() 
# Output: 14
s.area()
# Output: 4 
s.perimeter() 
…
600/1068
536
class C:
x = 2 # class variable
def init (self, y):
self.y = y # instance variable
C.x 
#…
601/1068
537
class A(object): 
def f(self, x):
return 2 * x
A.f
# <function A.f at ...> (in Python 3.x)…
602/1068
538
A.f(1, 7)
# Python 2: TypeError: unbound method f() must be called with
# A instance as firs…
603/1068
539
d = D()
d.multiplier = 1337 
(D.multiplier, d.multiplier) 
# (2, 1337)
d.f
# <bound metho…
604/1068
540
class MyClass: 
pass
my_inst = MyClass() 
type(my_inst)
# <class ' main .MyClass'>
my_ins…
605/1068
541
class Rectangle2D(object):
def init (self, width, height, pos=None, color='blue'): 
self.wid…
606/1068
542
fb = FooBar()
>>> fb.foo
'attr foo of Foo'
>>> FooBar.mro()
[<class ' main .FooBar'>, <cla…
607/1068
543
foobar init 
foo init
print isinstance(a,FooBar) 
print isinstance(a,Foo) 
print isinstanc…
608/1068
544
class Person(object):
def init (self, first_name, last_name, age): 
self.first_name = first_…
609/1068
545
In [2]: bob = Person("Bob", "Bobberson", 42)
In [3]: alice = Person.from_full_name("Alice Hen…
610/1068
546
class A(object):
def init (self, num): 
self.num = num
def add (self, other):
return A(sel…
611/1068
547
A.get_num = get_num
foo = A(42) 
A.get_num = get_num 
bar = A(6); 
foo.get_num() # 42
bar…
612/1068
548
def rename(self, renamed): # regular method 
"""Reassign and print the name attribute."""
se…
613/1068
549
>>> # Instances
>>> kelly = Person("Kelly")
>>> joseph = Person("Joseph")
>>> john_doe = Pe…
614/1068
550
class MyClass(object):
def init (self): 
self._my_string = ""
@property
def string(self):
…
615/1068
551
# Make hp read only by not providing a set method 
@property
def hp(self):
return self._hp
…
616/1068
552
class Singleton: 
def new (cls):
try:
it =cls. it
exceptAttributeError:
it = cls. it = ob…
617/1068
553
@Singleton 
class Single:
def init (self): 
self.name=None 
self.val=0
def getName(self):…
618/1068
554
import csv
with open('/tmp/output.tsv', 'wt') as out_file: 
tsv_writer = csv.writer(out_file…
619/1068
555
lst = [1, 2, 3, 4]
lst[0] # 1
lst[1] # 2
lst[4] # IndexError: list index out of range
lst[…
620/1068
556
lst[5:8]
lst[1:10]
# [] since starting index is greater than length of lst, returns empty li…
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.ap…
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,
# …
623/1068
559
import datetime
class Person(object):
def init (self, name, birthday, height): 
self.name =…
624/1068
https://riptutorial.com/es/home 560
import datetime
l = [{'name':'John Cena', 'birthday': datetim…
625/1068
561
a.clear() 
# a = []
b = ["blah"] * 3
# b = ["blah", "blah", "blah"] 
b = [1, 3, 5] * 5
# …
626/1068
562
new_list = list(old_list)
import copy
new_list = copy.copy(old_list) #inserts references to …
627/1068
563
for (index, item) in enumerate(my_list):
print('The item in position {} is: {}'.format(index,…
628/1068
564
In [3]: rev = reversed(numbers)
In [4]: rev
Out[4]: [9, 8, 7, 6, 5, 4, 3, 2, 1]
In [1]: num…
629/1068
565
alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3', 'b4'] 
for a, b in zip(alist, blist):
…
630/1068
566
nums = [1, 1, 0, 1]
all(nums) 
# False
chars = ['a', 'b', 'c', 'd'] 
all(chars)
# True
n…
631/1068
567
for row in range(len(alist)): #A less Pythonic way to loop through lists 
for col in range(le…
632/1068
568
print(alist[1][1:])
#[[8, 9, 10], 15, [12, 13, 14]]
#Slices still work
print(alist)
#[[[1,…
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…
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,…
636/1068
572
[x if x > 2 else '*' for x in range(10) if x % 2 == 0] 
# Out: ['*', '*', 4, 6, 8]
[x if (x …
637/1068
573
In [1]: data = [[1,2],[3,4],[5,6]]
In [2]: def f():
...: output=[]
...: for each_list in da…
638/1068
574
filter(lambda x: x % 2 == 0, range(10)) # even numbers < 10 
map(lambda x: 2*x, range(10)) # …
639/1068
575
#List Comprehension with nested loop
[x + y for x in [1, 2, 3] for y in [3, 4, 5]]
#Out: [4,…
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…
641/1068
577
a, b = (1, 2)
print(a) 
# Prints:1 
print(b)
# Prints: 2
a, b, c = [1]
# Raises: ValueEr…
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, …
643/1068
579
fun1(1, 2, 3)
def fun2(arg1='a', arg2='b', arg3='c'): 
return (arg1,arg2,arg3)
fun2(arg2=2,…
644/1068
580
fun1(**{'arg1':1, 'arg2':2})
# Raises: TypeError: fun1() missing 1 required positional argume…
645/1068
581
fun3(*[1,2], **{'arg2':42, 'arg3':3})
# Raises: TypeError: fun3() got multiple values for arg…
646/1068
582
Capítulo 114: Listar comprensiones
Introducción
Las comprensiones de listas en Python son co…
647/1068
583
[ <expression> for <element> in <iterable> if <condition> ]
squares = [x * x for x in (1, 2, …
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)
…
649/1068
585
[x.sort() for x in [[2, 1], [4, 3], [0, 1]]] 
# [None, None,None]
[sorted(x) for x in [[2, 1…
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 (…
651/1068
587
{**dict1, **dict2}
# Out: {'w': 1, 'x': 2, 'y': 2, 'z': 2}
print(swapped)
# Out: {a: 1, b: …
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[…
653/1068
589
for i in (x**2 for x in xrange(10)): 
print(i)
"""
Out:
0
1
4
.
.
. 
81 
"""
for s…
654/1068
590
# A set containing every value in range(5):
{x for x in range(5)} 
# Out: {0, 1, 2, 3, 4}
#…
655/1068
591
>>> [v for v in (f(x) for x in range(1000)) if v > 10] 
[16, 25, 36, ...]
>>> [v for v in ma…
656/1068
592
[item for sublist in l for item in sublist]
[x + y for x, y in [(1, 2), (3, 4), (5, 6)]]
# O…
657/1068
593
# Count the numbers in `range(1000)` that are even and contain the digit `9`: 
print (sum(
1…
658/1068
594
class Node:
def init (self, val): 
self.data = val 
self.next = None
def getData(self): 
…
659/1068
595
current = current.getNext() 
return count
def search(self,item):
"""Search foritemin list.I…
660/1068
596
current = self.head 
pos = 0
found = False
while current is not None and not found: 
if cu…
661/1068
597
ll=LinkedList() 
ll.add('l')
ll.add('H')
ll.insert(1,'e')
ll.append('l')
ll.append('o') 
…
662/1068
598
BsonDocument argsBson = BsonDocument.Parse("{ 'x' : '1', 'y' : '2' }");
string argsFile = str…
663/1068
599
import sys 
import json
# load input arguments from the text file 
filename = sys.argv[ 1 ]…
664/1068
600
Código C # llamando al script Python
using MongoDB.Bson; 
using System;
using System.Diagno…
665/1068
601
{
//delete/save temporary.txtfile 
if (!saveInputFile)
{
File.Delete(argsFile);
}
}
Con…
666/1068
602
finally:
# --- Cleanup on exit ---
stdscr.keypad(0) 
curses.echo() 
curses.nocbreak()
cur…
667/1068
603
Aquí, la envoltura inicializará las cursas, creará stdscr , un objeto WindowObject y pasará am…
668/1068
604
import xml.etree.ElementTree as ET 
tree = ET.parse("yourXMLfile.xml") 
root = tree.getroot(…
669/1068
605
root.remove(element)
tree.write('output.xml')
import xml.etree.ElementTree as ET
p=ET.Eleme…
670/1068
606
for event, elem in ET.iterparse("yourXMLfile.xml"):
... do something ...
events=("start", "e…
671/1068
607
import xml.etree.cElementTree as ET 
tree = ET.parse('sample.xml') 
tree.findall('Books/Book…
672/1068
608
import cmath
z = 2+3j # A complex number 
cmath.phase(z) # 0.982793723247329
cmath.polar(z)…
673/1068
609
cmath.sinh(z) # (-3.59056458998578+0.5309210862485197j) 
cmath.cosh(z) # (-3.7245455049153224…
674/1068
610
# Imports the Flask class 
from flask import Flask
# Creates an app and checks if its the ma…
675/1068
611
if name == " main ": app.run(host="0.0.0.0", 
port=80, debug=True)
@app.route("/") 
def ind…
676/1068
612
@app.route("/login", methods=["GET"]) 
def login_form():
return "This is the login form" 
@…
677/1068
613
- application.py
/templates
- about-us.html
- login-form.html
/static
/styles
- about-st…
678/1068
614
from flask import request
@app.route("/api/users/<username>") 
def user_api(username):
try:…
679/1068
615
@app.route("/upload", methods=["POST"]) 
def upload_file():
f = request.files["wordlist-uplo…
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…
681/1068
617
[[[111,112,113],[121,122,123],[131,132,133]],\
[[211,212,213],[221,222,223],[231,232,233]],\
…
682/1068
618
Dummy = type('OtherDummy', (), dict(x=1)) 
Dummy. class # <type 'type'> 
Dummy(). class . cl…
683/1068
619
>>> class Foo(object):
... pass
>>> type(Foo) 
type
class MyDummy(object):
 metaclass = m…
684/1068
620
class MySingleton(metaclass=SingletonType): 
pass
MySingleton() is MySingleton() # True, onl…
685/1068
621
Creating class Spam
[insert example string here]
>>> type(5)
<type 'int'>
>>> type(str)
<…
686/1068
622
class AnotherMetaclass(type):
def new (cls, name, parents, dct): 
# cls is this class
# nam…
687/1068
623
• Todo es un objeto en Python, así que todo tiene una clase.
• La clase de una clase se llama…
688/1068
624
class Parent(object): 
def introduce(self):
print("Hello!")
def print_name(self): 
print("…
689/1068
625
Capítulo 124: Métodos de cuerda
Sintaxis
• str.capitalize () -> str
• str.casefold () -> st…
690/1068
626
"XßΣ".casefold() 
# 'xssσ'
"XßΣ".lower() 
# 'xßς'
• str.swapcase () -> str
• str.title ()…
691/1068
627
"This is a 'string'.".upper() 
# "THIS IS A'STRING'."
"This IS a 'string'.".lower() 
# "thi…
692/1068
628
map(str.upper,["These","are","some","'strings'"])
# ['THESE', 'ARE', 'SOME', "'STRINGS'"]
>>…
693/1068
629
>>> "Thisis a sentence.".rsplit('e', maxsplit=1) 
['This is a sentenc', '.']
>>>"Thisisasent…
694/1068
630
>>> """It can foo multiple examples of foo if you want, \
... or you can limit the foo with t…
695/1068
631
>>> "I am from {}. I love cupcakes from {}!".format("Australia", "Australia")
>>> "I am from …
696/1068
632
>>> s = "This is a test string"
>>> s.startswith("T") 
True
>>>s.startswith("Thi") 
True
…
697/1068
633
>>> s.endswith('stop.') 
True
>>> s.endswith('Stop.') 
False
>>> s.endswith(('.', 'somethi…
698/1068
634
isdecimal isdigit isnumeric
>>> "Hello world".islower() 
False
>>> "hello world".islower() …
699/1068
635
>>> "Hello2World".isalnum() 
True
>>> "HelloWorld".isalnum() 
True
>>> "2016".isalnum() 
…
700/1068
636
>>> 'this syntax is very useful'.translate(None, 'aeiou') 
'ths syntx s vry sfl'
>>> transla…
701/1068
637
'spaciousstring '
>>> " spacious string ".rstrip()
>>> "ß".lower() 
'ß'
>>> "ß".upper().lo…
702/1068
638
>>> import unicodedata
>>> [unicodedata.name(char) for char in "ê"] 
['LATINSMALLLETTEREWITH…
703/1068
639
>>> string.ascii_letters 
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.…
704/1068
640
>>> string.punctuation '!"#$%&\'()*+,-
./:;<=>?@[\\]^_`{|}~'
>>> string.whitespace 
' \t\n\…
705/1068
641
interstates_lengths = { 
5: (1381, 2222),
}
for road, length in interstates_lengths.items()…
706/1068
642
characters.
# b'\xc2\xa9 abc'
# str.encode produces a byte array, showing ASCII-range bytes …
707/1068
643
True
708/1068
644
class A(object):
# func: A user-defined function object 
#
# Note that func is a function o…
709/1068
645
Ejemplo de tortuga
El siguiente es un ejemplo del uso de una función definida por el usuario …
710/1068
646
class Vehicle(object):
"""A generic vehicle class."""
def init (self, position): 
self.posi…
711/1068
647
class Foo(main_super, mixin): ...
class RadioUserMixin(object): 
def init (self):
self.radi…
712/1068
648
>>> x = MyClass()
>>> x.test() 
Base
clases se define de derecha a izquierda. 
Por ejemplo…
713/1068
649
def add_student(): 
try:
students['count'] += 1 
except KeyError:
students['count'] = 1
d…
714/1068
650
import sys
def main():
# Your code starts here
# Don't forget to provide a return code 
re…
715/1068
651
import random
laughs = ["Hi", "Ho", "He"]
random.shuffle(laughs) # Shuffles in-place! Don't …
716/1068
652
# Output may vary!
laughs , 1 )) # Take one element
# |--sequence--|--number--|
print(rando…
717/1068
653
random.random() # Out: 0.66486093215306317
random.uniform(1, 8) # Out: 3.726062641730108
ale…
718/1068
654
random.seed(5) # Reset the random module to the same fixed state. 
print(random.randrange(0, …
719/1068
655
print([secure_rand_gen.randrange(10) for i in range(10)]) 
# [9, 6, 9, 2, 2, 3, 8, 0, 9, 9]
…
720/1068
656
import string
alphabet = string.ascii_letters + string.digits 
while True:
password =''.joi…
721/1068
657
import asyncio
async def main(): 
print(await func())
async def func():
# Do time intensiv…
722/1068
658
import asyncio
from concurrent.futures import ThreadPoolExecutor
def func(a, b):
# Do time …
723/1068
659
import asyncio 
import uvloop
if name == " main ": 
asyncio.set_event_loop(uvloop.new_event…
724/1068
660
import asyncio
# event trigger function 
def trigger(event):
print('EVENT SET')
event.set(…
725/1068
661
if name == ' main ': #
The main loop
loop = asyncio.get_event_loop() 
loop.run_until_comple…
726/1068
662
727/1068
663
from Queue import Queue 
question_queue = Queue()
for x in range(1,10): 
temp_dict = ('key'…
728/1068
664
import collections
counts = collections.Counter([1,2,3])
>>> collections.Counter('Happy Birt…
729/1068
665
>>> collections.Counter('I am Sam Sam I am That Sam-I-am That Sam-I-am! I do not like that 
S…
730/1068
666
>>> state_capitals = collections.defaultdict(str)
>>> state_capitals 
defaultdict(<class 'st…
731/1068
667
>>> s = [('NC', 'Raleigh'), ('VA', 'Richmond'), ('WA', 'Seattle'), ('NC', 'Asheville')]
>>> d…
732/1068
668
>>> d['foo'] = 4
>>> print(d)
OrderedDict([('foo', 4), ('bar', 6), ('baz', 7), ('foobar', 8)…
733/1068
669
Human = namedtuple('Person', 'age, height, name') 
dave = Human(30, 178, 'Dave')
print(dave)…
734/1068
670
Fuente: https://docs.python.org/2/library/collections.html
colecciones.ChainMap
ChainMap es …
735/1068
671
import collections
# define two dictionaries with at least some keys overlapping. 
dict1 = {…
736/1068
672
>>> from functools import partial
>>> unhex = partial(int, base=16)
>>> unhex. doc = 'Conver…
737/1068
673
from functools import reduce 
def factorial(n):
return reduce(lambda a, b: (a*b), range(1, n…
738/1068
674
>>> fib.cache_info()
CacheInfo(hits=13, misses=16, maxsize=None, currsize=16)
diferentes tip…
739/1068
675
x = 1.55
y = -1.55
# round to the nearest integer 
round(x) # 2
round(y) # -2
# the secon…
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
…
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 …
742/1068
678
math.atan(math.inf)
# Out: 1.5707963267948966 # This is just "pi / 2"
math.atan(float('inf')…
743/1068
679
pos_inf = math.inf 
neg_inf = -math.inf 
not_a_num = math.nan
math.inf == float('inf') 
# …
744/1068
680
math.isinf(pos_inf) 
# Out: True
math.isinf(neg_inf) 
# Out: True
neg_inf == float('-inf')…
745/1068
681
-5.0 * pos_inf == neg_inf 
# Out: True
-5.0 * neg_inf == pos_inf 
# Out: True
pos_inf * ne…
746/1068
682
math.inf is math.inf, math.nan is math.nan 
# Out: (True, True)
float('inf') is float('inf')…
747/1068
683
# z.conjugate() == z.real - z.imag * 1j
z.conjugate() 
# Out: (1-3j)
# real part and imagin…
748/1068
684
cmath.phase(complex(-1.0, 0.0))
# Out: 3.141592653589793
cmath.phase(complex(-1.0, -0.0))
#…
749/1068
685
z = cmath.rect(*cmath.polar(1+1j))
z
# Out: (1.0000000000000002+1.0000000000000002j)
cmath.…
750/1068
686
Capítulo 134: Módulo de navegador web
Introducción
De acuerdo con la documentación estándar …
751/1068
687
Parámetro Detalles
webbrowser.get()
Observaciones
Lasiguientetablaenumeralos tiposdenavegad…
752/1068
688
import webbrowser 
webbrowser.open("http://stackoverflow.com")
import webbrowser 
webbrowse…
753/1068
689
import webbrowser
ff_path = webbrowser.get("C:/Program Files/Mozilla Firefox/firefox.exe") 
…
754/1068
690
# p = 1, d = deque([2, 3])
# d = deque([5, 2, 3])
d = deque([1, 2, 3]) 
p = d.popleft()
d.…
755/1068
691
from collections import deque
d = deque(maxlen=3) # only holds 3 items 
d.append(1) # deque(…
756/1068
692
dl.reverse() # deque([6, 5, 4, 3, 2, 0, -2])
from collections import deque
def bfs(graph, ro…
757/1068
693
lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 5, 6)]
testGroupBy(lst)
lst = [("a", 5, …
758/1068
694
results = fetch_paged_results() # returns a generator 
limit = 20 # Only want the first 20 re…
759/1068
695
for x in xrange(10):
for y in xrange(10): 
print x, y
its = [xrange(10)] * 2
for x,y in it…
760/1068
696
for number in itertools.count(start=10, step=4): 
print(number)
if number > 20: 
break
10
…
761/1068
697
def takewhile(predicate, iterable): 
for x in iterable:
if predicate(x): 
yield x
else:
b…
762/1068
698
from itertools import zip_longest
a = [i for i in range(5)] # Length is 5
b = ['a', 'b', 'c'…
763/1068
699
from itertools import chain
a = (x for x in ['1', '2', '3', '4'])
b = (x for x in ['x', 'y',…
764/1068
700
>>> import itertools as it
>>> it.cycle('ABCD')
A B C D A B C D A B C D ...
>>> # Iterate o…
765/1068
701
nulo Ninguna
verdadero Falso Verdadero Falso
numero (real) flotador
número (int) En t
cuer…
766/1068
702
# my_json module
import json
from functools import partial
def serialise_object(obj):
# Do…
767/1068
703
# my_json module
import json
from functools import partial
class MyEncoder(json.JSONEncoder…
768/1068
704
import json
d = {
'foo': 'bar', 
'alice': 1,
'wonderland': [1, 2, 3]
}
with open(filenam…
769/1068
705
import json
json_file_path = './data.json' 
data={u"foo": u"bar",u"baz":[]}
with open(json_…
770/1068
706
$ cat foo.json | python -m json.tool
>>> data = {"cats": [{"name": "Tubbs", "color": "white"}…
771/1068
707
>>> print(json.dumps(data, sort_keys=True))
{"cats": [{"color": "white", "name": "Tubbs"}, {"…
772/1068
708
773/1068
709
1 + 1
# Output: 2
from operator import add 
add(1, 1)
# Output: 2
from operator import mu…
774/1068
710
dict((i, dict(v)) for i, v in groupby(adict.items(), lambda x: x[1]))
alist_of_tuples = [(5,2…
775/1068
711
pyautogui.displayMousePosition() #gave you the current mouse position but should be done 
on …
776/1068
712
import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
# Create table 
c.ex…
777/1068
713
a=c.fetchall() #which is similar to list(cursor) method used previously 
for row in a:
print…
778/1068
714
import threading
def foo():
print "Hello threading!"
my_thread = threading.Thread(target=fo…
779/1068
715
# print 'The main program continuesto run in foreground.' 
t.join()
print("The main program …
780/1068
716
q = Queue()
t1 = Thread(target=consumer, args=(q,)) 
t2 = Thread(target=producer, args=(q,))…
781/1068
717
def split_line(line, cols): 
if len(line) > cols:
new_line = ''
# The actual way to send
#…
782/1068
718
import threading 
import time
class StoppableThread(threading.Thread):
"""Thread class with…
783/1068
719
Basado en esta pregunta .
self._stop_event.set()
def join(self, *args, **kwargs): 
self.sto…
784/1068
720
import multiprocessing 
import time
from random import randint
def countUp(): 
i = 0
whil…
785/1068
721
from multiprocessing import Pool
def cube(x):
return x ** 3
if name == " main ": 
pool = P…
786/1068
722
>>> a = 1
>>> id(a) 
140128142243264
>>> a += 2
>>> a 
3
>>> id(a) 
140128142243328
>>…
787/1068
723
>>> stack = "Stack"
>>> stackoverflow = stack + "Overflow"
>>> id(stack) 
140128069348184
…
788/1068
724
>>> c = b
>>> c += b' rocks!'
>>> c
bytearray(b'StackOverflow rocks!')
>>> b
bytearray(b'…
789/1068
725
>>> def tuple_add3(tin): 
tin += (3,)
return tin
>>> a = (1, 2, 3)
>>> b = tuple_add3(a)
…
790/1068
726
from py2neo import authenticate, Graph, Node, Relationship 
authenticate("localhost:7474", "n…
791/1068
727
def get_autocomplete(text): 
query = """
start n = node(*) where n.name =~ '(?i)%s.*' return…
792/1068
728
where l.name='Donald Trump' 
MATCH (n:NewsArticle)-[]->(m) 
with m,count(n) as num where num…
793/1068
729
#! /usr/bin/env python
class Node:
definit (self, cargo=None, next=None): 
self.car = cargo…
794/1068
730
class Foo(object): 
def init (self):
self. bar = None
@property
def bar(self):
if self. b…
795/1068
731
>>> wallet = Cash(2.50)
>>> print(wallet.formatted)
$2.50
>>> print(wallet.value) 
2.5
>>…
796/1068
732
def getY (self): 
return self._y
def setY (self, value):
self._y = 1000 + value # Weird but…
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)…
798/1068
734
x = True 
y = True
z = x and y # z = True
x = True 
y = False
z = x and y # z = False
x …
799/1068
735
x = True
y = not x # y = False
x = False
y = not x # y = True
>>> def true_func():
... pr…
800/1068
736
def or_(a, b): 
if a:
return a 
else:
return b
def and_(a, b): 
if not a:
return a 
el…
801/1068
737
# 60 = 0b111100 
# 30 = 0b011110 
60 & 30
# Out: 28
# 28 = 0b11100
bin(60 & 30)
# Out: 0…
802/1068
738
#60=0b111100 
#30=0b011110 
60 | 30
# Out: 62
# 62 = 0b111110
bin(60 | 30) 
# Out: 0b111…
803/1068
739
3 << 4
# Out: 48
# 8 = 0b1000 
8 >> 2
# Out: 2
# 2 = 0b10
bin(8 >> 2) 
# Out: 0b10
36 …
804/1068
740
# 0 = 0b0000 0000
~0
# Out: -1
# -1 = 0b1111 1111
# 1 = 0b0000 0001
~1
# Out: -2
# -2 =…
805/1068
741
# -0 = 0b0000 0000
~-0
# Out: -1
# -1 = 0b1111 1111
# 0 is the obvious exception to this r…
806/1068
742
import operator # contains 2 argument arithmetic functions for the examples
a, b = 1, 2
# Us…
807/1068
743
[1, 2, 3] + [4, 5,6] # = [1, 2, 3, 4, 5, 6]
"first string " + "second string" # = 'first stri…
808/1068
744
3 * 'ab' # = 'ababab'
3 * ('a', 'b') # = ('a', 'b', 'a', 'b', 'a', 'b')
a, b, c, d, e = 3, 2…
809/1068
745
from operator import truediv 
truediv(a, b) # = 1.5
# = 1.5
# = 1.5
float(a) / b 
a / flo…
810/1068
746
# does so more efficiently
# 0, calculates (2 ** 3) % 2, but as per Python docs,
a, b, c = 2…
811/1068
747
# optional base argument. Default is math.e 
math.log(5, math.e) # = 1.6094379124341003 
cma…
812/1068
748
a, b = 1, 2
import math
math.sin(a) # returns the sine of 'a' in radians 
# Out: 0.84147098…
813/1068
749
quotient, remainder = divmod(9, 4)
# quotient = 2, remainder = 1 as 4 * 2 + 1 == 9
O utiliza…
814/1068
750
import cProfile 
def f(x):
return "42!" 
cProfile.run('f(12)')
import cProfile, pstats, St…
815/1068
751
3 function calls in 0.000 seconds 
Ordered by: standard name
$ kernprof -l script_to_profile…
816/1068
752
$ python -m timeit '"-".join(str(n) for n in range(100))' 
10000 loops, best of 3: 40.3 usec …
817/1068
753
import os 
os.path.join('a', 'b', 'c')
>>> os.path.join('a', 'b', 'c') 
'a\b\c'
>>> os.pat…
818/1068
754
>>> p = os.path.join(os.getcwd(), 'foo.txt')
>>> p
'/Users/csaftoiu/tmp/foo.txt'
>>> os.pat…
819/1068
755
symlink = dirname + 'some_sym_link' 
os.path.islink(symlink)
mount_path = '/home' 
os.path.…
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['o…
821/1068
757
that is called 'number_of_orders_per_cient'
orders_df # Take the original dataframe
.groupby…
822/1068
758
each group separately
#Inspecting the results... 
print(orders_df)
# customer_id order_id i…
823/1068
759
from types import MethodType
class Animal(object):
def init (self, *args, **kwargs):
self.n…
824/1068
760
generic_animal = Animal()
king_cobra = Animal(name='King Cobra', walk=snake_walk)
elephant =…
825/1068
761
class Singleton(object): 
def new (cls):
# hasattr methodchecksif the class object an instan…
826/1068
762
from abc import ABCMeta, abstractmethod
class Music():
 metaclass = ABCMeta 
@abstractmetho…
827/1068
763
class Proxy:
def init (self, current_user, reservation_service): 
self.current_user = curren…
828/1068
764
BENEFICIOS
• estamos evitando cualquier cambio en ReservationService cuando se cambianlas 
r…
829/1068
765
In [1]: import string
In [2]: %%timeit s=""; long_list=list(string.ascii_letters)*50
....: f…
830/1068
766
$ kernprof -lv so6.py
Wrote profile results to so6.py.lprof 
Timer unit: 4.27654e-07 s
Tota…
831/1068
767
$ python -m cProfile -s time main.py
• filename:lineno(function) : proporciona los datos resp…
832/1068
768
data={'a':'some_value',
'b':[9,4,7],
'c':['some_str','another_str','spam','ham'], 
'd':{'ke…
833/1068
769
import pickle
file=open('filename','rb') #file object in binary read mode 
data=pickle.load(…
834/1068
770
Capítulo 156: pip: PyPI Package Manager
Introducción
pip es el gestor de paquetes más utiliz…
835/1068
771
$ pip install SomePackage
$ pip install SomePackage==1.0.4
$ pip install SomePackage>=1.0.4
…
836/1068
772
$ pip list
# example output 
docutils (0.9.1)
Jinja2 (2.6)
Pygments (1.5)
Sphinx (1.1.2)
…
837/1068
773
for /F "delims= " %i in ('pip list --outdated --local') do pip install -U %i
pip freeze > req…
838/1068
774
\path\to\that\python.exe -m pip install some_package # on Windows OR
/usr/bin/python25 -m pip…
839/1068
775
win_amd64 - y luego la versión de Python debe coincidir, es decir, para Python 34, el nombre d…
840/1068
776
> py -3.5-32 -m venv demo-pip
> demo-pip\Scripts\activate.bat
> python -m pip install -U pip…
841/1068
777
Using cached Jinja2-2.9.6-py2.py3-none-any.whl 
Collecting Pygments>=2.0 (from Sphinx==1.7.de…
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 te…
844/1068
780
class Shape: 
"""
This is a parent class that is intended to be inherited by other classes 
…
845/1068
781
class Square:
side_length = 2
def calculate_square_area(self): 
return self.side_length ** …
846/1068
782
class Duck:
def quack(self): 
print("Quaaaaaack!")
def feathers(self):
print("The duck has…
847/1068
783
La salida es:
Quaaaaaack!
El pato tiene plumas blancas y grises. 
La persona imita a un pat…
848/1068
784
import psycopg2
# Establish a connection to the existing database 'my_database' using 
# the…
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…
851/1068
787
>>> a, b, c, d = 2, 3, 5, 7
>>> a ** (b + c) # parentheses 
256
>>> a * b ** c # exponent: …
852/1068
788
import threading 
import time
def process(): 
time.sleep(2)
start = time.time() 
process(…
853/1068
789
import threading 
import time
def somefunc(i): 
return i * i
def otherfunc(m, i): 
return…
854/1068
790
import threading 
import os
def process():
print("Pid is %s, thread id is %s" % (os.getpid(…
855/1068
791
import threading
obj = {}
obj_lock = threading.Lock()
def objify(key, val):
print("Obj has…
856/1068
792
shared_num.value += 1
ps = [multiprocessing.Process(target=increment) for n in range(4)] 
fo…
857/1068
793
s=lambda x:x*x 
s(2) =>4
name_lengths = map(len, ["Mary", "Isla", "Sam"]) 
print(name_lengt…
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…
859/1068
795
Capítulo 163: Programación IoT con Python y 
Raspberry PI
Examples
Ejemplo - sensor de temp…
860/1068
796
R1 es una resistencia de 4.7k ohmios para elevar el nivel de voltaje
1. Vcc debe conectarse a…
861/1068
797
import glob 
import time
RATE = 30
sensor_dirs = glob.glob("/sys/bus/w1/devices/28*")
if l…
862/1068
798
pip install pytest
# projectroot/module/code.py 
def add(a, b):
return a + b
# projectroot…
863/1068
799
# projectroot/tests/test_code.py 
from module import code
def test_add failing():
assert co…
864/1068
800
# projectroot/tests/test_stuff.py 
import pytest
from module import stuff
def test_foo_upda…
865/1068
801
@pytest.fixture
def prepped_stuff(): 
my_stuff = stuff.Stuff() 
my_stuff.prep()
return my_…
866/1068
802
# projectroot/module/stuff.py 
class Stuff(object):
def prep(self): 
self.foo = 1
self.bar…
867/1068
803
¡Y eso concluye la Introducción a los Aparatos de Prueba!
Para obtener más información, consu…
868/1068
804
"""PyAudio Example: Play a wave file (callback version)."""
import pyaudio 
import wave 
im…
869/1068
805
import pyaudio 
import wave 
import sys
CHUNK = 1024
if len(sys.argv) < 2:
print("Plays a…
870/1068
806
Para usar PyAudio, primero cree una instancia de PyAudio usando pyaudio.PyAudio () (1), que 
…
871/1068
807
pip install pygame
Capítulo 166: pygame
Introducción
Pygame es la biblioteca de acceso para…
872/1068
808
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=4096)
Descarga directa desde …
873/1068
809
de inmediato.
Para saber cuántos canales se están utilizando actualmente, llame a
pygame.mix…
874/1068
810
import pyglet
window = pyglet.window.Window()
label = pyglet.text.Label('Hello, world',
fon…
875/1068
811
import pyglet
from pyglet.gl import *
win = pyglet.window.Window() 
glClear(GL_COLOR_BUFFER…
876/1068
812
pip install pyinstaller
Capítulo 168: PyInstaller - Distribuir código 
de Python
Sintaxis
…
877/1068
813
desarrollo de la página de descargas de PyInstaller .
Expandaelarchivoyencuentreel scriptsetu…
878/1068
814
carpeta.
Otra ventaja se siente durante las actualizaciones. Si hay algunos cambios en el cód…
879/1068
815
from ply import lex 
import ply.yacc as yacc
tokens = (
'PLUS',
'MINUS',
'TIMES',
'DIV',…
880/1068
816
'NUMBER',
)
t_ignore = ' \t'
t_PLUS = r'\+' 
t_MINUS = r'-'
t_TIMES = r'\*' 
t_DIV = r'/…
881/1068
817
import ply.lex as lex
# List of token names. This is always required 
tokens = [
'NUMBER',
…
882/1068
818
tokens = [
'NUMBER',
'PLUS',
'MINUS',
'TIMES',
'DIVIDE',
'LPAREN',
'RPAREN',
]
Guarde…
883/1068
819
def t_NUMBER(t): 
r'\d+'
t.value = int(t.value) 
return t
def t_newline(t): 
r'\n+'
t.le…
884/1068
820
t_ignore_COMMENT = r'\#.*'
t_ignore = ' \t' # ignores spaces andtabs
literals = [ '+', '-', …
885/1068
821
# Build the lexer 
#
m = MyLexer() 
m.build() 
m.test("3 + 4")
# Build the lexer
def bui…
886/1068
822
def p_expression_plus(p):
'expression : expression PLUS term'
def p_expression_minus(p):
'e…
887/1068
823
p[0] = p[1] + p[3]
def p_binary_operators(p):
'''expression : expression PLUS term
| expres…
888/1068
824
precedence = (
('nonassoc', 'LESSTHAN', 'GREATERTHAN'), # Nonassociative operators 
('left',…
889/1068
825
from requests import post
foo = post('http://httpbin.org/post', data = {'key':'value'})
prin…
890/1068
826
foo = post('http://httpbin.org/post', data = {'key':'value'}, verify=False)
foo = post('http:…
891/1068
827
from requests import post
files = {'file' : open('data.txt', 'rb')} 
foo = post('http://http…
892/1068
828
from requests import post
foo = post('http://natas0.natas.labs.overthewire.org', auth=('natas…
893/1068
829
foo = get('http://test.com/admin', auth=CustomAuth('SecretHeader', 'CustomUserAgent', 'user', …
894/1068
830
import os, sys
from openpyxl import Workbook 
from datetime import datetime
dt = datetime.n…
895/1068
831
workbook = opx.load_workbook(workbook_path, read_only=True)
first_sheet = workbook.worksheets…
896/1068
832
{'name': 'Sit', 'value': 8},
{'name': 'Amet', 'value': 32}
]
# excel file path 
xls_file =…
897/1068
833
pip install xlrd
Lee los datos de excel usando el módulo xlrd
La biblioteca xlrd de Python e…
898/1068
834
import xlrd 
book=xlrd.open_workbook('sample.xlsx')
print book.nsheets
print book.sheet_nam…
899/1068
835
# set the width of column A 
worksheet.set_column('A:A', 30, )
# set column B to 20 and incl…
900/1068
836
Capítulo 172: Recolección de basura
Observaciones
Ensunúcleo,elrecolectordebasuradePython(ap…
901/1068
837
/* Break reference cycles by clearing the containers involved. This is
* tricky business as t…
902/1068
838
/* list of uncollectable objects */ 
static PyObject *garbage = NULL;
y establecemos una ins…
903/1068
839
>>> def bar():
return Track()
>>> t = bar() 
Initialized
>>> another_t = t # assign anothe…
904/1068
840
>>> objs = [Track() for _ in range(10)] 
Initialized
Initialized 
Initialized 
Initialized…
905/1068
841
>>> import sys
>>> sys.getrefcount(1) 
797
>>> a = 1
>>> b = 1
>>> sys.getrefcount(1) 
7…
906/1068
842
import ctypes 
deallocated = 12345
ctypes.pythonapi._Py_Dealloc(ctypes.py_object(deallocated…
907/1068
843
import gc 
gc.collect()
>>> f = open("test.txt")
>>> del f
entonces se procesará la genera…
908/1068
844
>>> with open("test.txt") as f:
... pass
... # do something with f
>>> #now the f object st…
909/1068
845
from PIL import Image 
import sys
import pyocr
import pyocr.builders
tools = pyocr.get_ava…
910/1068
846
txt = tool.image_to_string( 
Image.open('test.png'), 
lang=lang,
builder=pyocr.builders.Tex…
911/1068
847
n = 0
for i in range (1, n+1): 
n += i
def recursion(n): 
if n == 1:
return 1
return n +…
912/1068
848
def factorial(n): 
if n == 0:
return 1 
else:
return n * factorial(n - 1)
que ese número.…
913/1068
849
def factorial(n): 
if n == 0:
return 1 
elif n == 1:
return 1 
else:
return n * factoria…
914/1068
850
def factorial(n): 
product = 1 
while n > 1:
product *= n 
n -= 1
return product
def fib…
915/1068
851
def fib(n):
if n <= 1:
return (n,0) 
else:
(a, b) = fib(n - 1) 
return (a + b, a)
root
…
916/1068
852
def list_tree_names(node):
for child in get_children(node): 
print(get_name(child)) 
list_t…
917/1068
853
def countdown(n): 
if n == 0:
print "Blastoff!" 
else:
print n 
countdown(n-1)
def find_…
918/1068
854
@tail_call_optimized 
def factorial(n, acc=1):
"calculate a factorial" 
if n == 0:
return …
919/1068
855
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
serversocket…
920/1068
856
from sockerserver import BaseRequestHandler, TCPServer
class EchoHandler(BaseRequestHandler):…
921/1068
857
>>> from socket import socket, AF_INET, SOCK_DGRAM
>>> sock = socket(AF_INET, SOCK_DGRAM)
>>…
922/1068
858
923/1068
859
sum([1,2,3]) # = 6
''.join(['Hello', ',', ' World']) # = 'Hello,World'
# First falsy item:
…
924/1068
860
def add(s1, s2): 
return s1 + s2
asequence = [1, 2, 3]
reduce(add, asequence) # equivalent …
925/1068
861
import operator 
reduce(operator.mul, [10, 5, -3])
# Out: -150
import operator
# non short…
926/1068
862
object -> string -> object
def repr (self):
return "Card(%s, %d)" % (self.suit, self.pips)
…
927/1068
863
class Card:
def init (self, suit, pips): 
self.suit = suit 
self.pips = pips
ace_of_spades…
928/1068
864
string_of_card = str(ace_of_spades) 
print(string_of_card)
class Card:
def init (self, suit…
929/1068
865
ace_of_spades = Card('Spades', 1) 
print(ace_of_spades)
Ace of Spades
my_hand = [ace_of_spa…
930/1068
866
class Card:
special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'}
def init (self, suit…
931/1068
867
print(four_of_clubs. repr ()) # 4 of Clubs (R)
print(four_of_clubs. str ()) # 4 of Clubs (S)
…
932/1068
868
class Card:
special_names = {1:'Ace', 11:'Jack', 12:'Queen', 13:'King'}
def init (self, suit…
933/1068
869
a = 7
if a > 5: 
print "foo"
else:
print "bar" 
print "done"
if True: 
print "true"
if…
934/1068
870
if foo:
if bar:
x = 42
¿Espacios o pestañas?
La sangría recomendada es de 4 espacios, pero…
935/1068
871
se analiza como:
<if> <foo> <:> [0]
<INDENT> <if> <bar> <:> [0, 4]
<INDENT> <x> <=> <42> [0…
936/1068
872
"This is a string"
b"This is a buffer of bytes"
import hashlib
h = hashlib.new('sha256')
h…
937/1068
873
import hashlib 
hashlib.algorithms_available
# ==> {'sha256', 'DSA-SHA', 'SHA512', 'SHA224',…
938/1068
874
import hashlib
hasher = hashlib.new('sha256') 
with open('myfile', 'r') as f:
contents = f.…
939/1068
875
salt = encrypted[0:SALT_SIZE]
derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000,…
940/1068
876
with open('pubkey.pem', 'rb') as f: 
key = RSA.importKey(f.read())
hasher = SHA256.new(messa…
941/1068
877
Nota : Los ejemplos anteriores utilizan el esquema de cifrado OPAP PKCS # 1. pycrypto también …
942/1068
878
Capítulo 180: Serialización de datos
Sintaxis
• unpickled_string = pickle.loads (cadena)
• …
943/1068
879
import json
families = (['John'], ['Mark', 'David', {'name': 'Avraham'}]) 
# Dumping it into…
944/1068
880
Consulte Pickle para obtener información detallada acerca de Pickle.
ADVERTENCIA : La documen…
945/1068
881
Capítulo 181: Serialización de datos de 
salmuera
Sintaxis
• pickle.dump (objeto, archivo, …
946/1068
882
import pickle
# An arbitrary collection of objects supported by pickle. 
data = {
'a': [1, …
947/1068
883
serialized_data = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) 
# type(serialized_data) is byt…
948/1068
884
todos los valores: {'important_data': self.important_data} .
¡Elconstructornosellama!Tengaenc…
949/1068
885
python -m SimpleHTTPServer 9000
python -m http.server 9000
import sys
import BaseHTTPServer…
950/1068
886
import SimpleHTTPServer 
import SocketServer
PORT = 8000
handler = SimpleHTTPServer.SimpleH…
951/1068
887
def test(HandlerClass = SimpleHTTPRequestHandler, 
ServerClass =BaseHTTPServer.HTTPServer):
…
952/1068
888
|UDPServer| ------->|UnixDatagramServer|
+-----------+ +--------------------+
+-------------…
953/1068
889
$ curl http://localhost/
received get request%
$ curl -X POST http://localhost/
received po…
954/1068
890
from distutils.core import setup
setup(name='foo',
version='1.0', 
py_modules=['foo'],
)
…
955/1068
891
python setup.py install
greetings/
greetings/
 init .py 
hello_world.py
python greetings/…
956/1068
892
from setuptools import setup, find_packages
setup(
setup_requires=['setuptools_scm'], 
use_…
957/1068
893
python setup.py build_sphinx
initialize_options y finalize_options se ejecutarán antes y desp…
958/1068
894
2 in [2, 3]
{'0': 2, '1': 3}
Capítulo 184: Similitudes en la sintaxis, 
diferencias en el s…
959/1068
895
import math
class Vector(object): 
# instantiation
def init (self, x, y): 
self.x = x
sel…
960/1068
896
class sparselist(object): 
def init (self, size):
self.size = size 
self.data = {}
# l[ind…
961/1068
897
class adder(object):
def init (self, first): 
self.first = first
# a(...)
def call (self, …
962/1068
898
>>> x = NotAddable(1)
>>> y = Addable(2)
>>> x + x
Traceback (most recent call last): 
Fil…
963/1068
899
class A:
def init (self, a): 
self.a = a
def add (self, other): 
return self.a + other
de…
964/1068
900
Como no hay nada especial en estos métodos, muchas otras partes del lenguaje, partes de la 
b…
965/1068
901
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
host = raw_input("Server Address T…
966/1068
902
try:
#setting up socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
server.b…
967/1068
903
#encrypting session key and public key 
E = server_public_key.encrypt(encrypto,16)
en = eval…
968/1068
904
ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
eMsg = ideaEncrypt.encrypt(w…
969/1068
905
from CryptoPlus.Cipher import IDEA
#server address and port number input from admin 
host= r…
970/1068
906
import time 
import socket 
import threading 
import hashlib 
import itertools 
import sy…
971/1068
907
#public key and private key 
random_generator = Random.new().read
key =RSA.generate(1024,ran…
972/1068
908
print (msg)
print ("\n-----DECRYPTEDSESSION KEY-------")
print (en_digest)
print("\n-----HA…
973/1068
909
usage: sub <command> 
commands:
status - showstatus 
list - print list
"""
usage: sub <co…
974/1068
910
usage: sub <command> 
commands:
status - showstatus 
list - print list
import argparse 
i…
975/1068
911
argparse (formateador de ayuda personalizado)
Versión extendida de http://www.levcode.com/pyt…
976/1068
912
usage: sub <command> 
commands:
status - showstatus 
list - print list
Salida sin argument…
977/1068
913
import sys
from sys import exit
raise RuntimeError("expected 3 command line arguments")
f =…
978/1068
914
# Error messages should not go to standard output, if possible. 
print('ERROR: We have no che…
979/1068
915
import tempfile
with tempfile.NamedTemporaryFile(delete=False) as t: 
t.write('Hello World!'…
980/1068
916
981/1068
917
import typing
T = typing.TypeVar("T")
def get_first_element(l: typing.Sequence[T]) -> T: 
"…
982/1068
918
print(two_sum(2, 1)) # result: 3
print(two_sum("a", "b")) # result: "ab"
def two_sum(a: int,…
983/1068
919
class A:
x = None # type: float
def init (self, x: float) -> None: 
"""
self should not be…
984/1068
920
x: int
print( annotations ) 
# {'x': <class 'int'>}
class C:
s: str
print(C. annotations …
985/1068
921
float_num = 10.2 #float value 
complex_num = 3.14j #complex value
long_num = 1234567L #long …
986/1068
922
tuple = (123,'hello') 
tuple1 = ('world')
print(tuple) #will output whole tuple. (123,'hello…
987/1068
923
foo = "bar"
foo[0] = "c" # Error
foo = ("bar", 1, "Hello!",) 
foo[1] = 2 # ERROR!!
foo = f…
988/1068
924
from Tkinter import * # Capitalized
from tkinter import * # Lowercase
try:
from Tkinter imp…
989/1068
925
Gerentes de geometría
Tkinter tiene tres mecanismos para la gestión de la geometría: place , …
990/1068
926
from tkinter import *
class GridExample(Frame): 
def init (self,master):
Frame. init(self,m…
991/1068
927
¡Nunca mezcle el pack y la griddentro del mismo marco! ¡Al hacerlo se producirá un 
interbloq…
992/1068
928
Capítulo 194: Trabajando alrededor del 
bloqueo global de intérpretes (GIL)
Observaciones
¿…
993/1068
929
bibliotecas de procesamiento de imágenes y las operaciones de procesamiento de números 
numpy…
994/1068
930
from threading import Thread 
import time
def countdown(n): 
while n > 0:
n -= 1
COUNT = …
995/1068
931
from threading import Thread 
import time
def countdown(n): 
while n > 0:
n -= 1
COUNT = …
996/1068
932
Es así de simple, siempre y cuando estés usando cython. Tenga en cuenta que la documentación 
…
997/1068
933
import zipfile 
filename = 'zipfile.zip'
zip = zipfile.ZipFile(filename) 
print(zip)
# <zi…
998/1068
934
with zipfile.ZipFile(filename) as zip: 
zip.printdir()
with zipfile.ZipFile(filename) as zip…
999/1068
935
import zipfile 
new_arch=zipfile.ZipFile("filename.zip",mode="w")
new_arch.write('filename.t…
1000/1068
936
plt.plot(x, y)
plt.show()
# sine function
# Plotting tutorials in Python 
# Launching a si…
1001/1068
937
# Plotting tutorials in Python 
# Enhancing a plot
import numpy as np
import matplotlib.pyp…
1002/1068
938
# Plotting tutorials in Python
# Adding Multiple plots by superimposition 
# Good for plots …
1003/1068
939
# Plotting tutorials in Python
# Adding Multiple plots by superimposition
# Good for plots s…
1004/1068
940
# Plotting tutorials in Python
# Adding Multiple plots by twin x axis
# Good for plots havin…
1005/1068
941
# replicate axes object and plot curves 
# use axes to set attributes
# Note:
# Grid for se…
1006/1068
942
# Plotting tutorials in Python
# Adding Multiple plots by twin y axis
# Good for plots havin…
1007/1068
943
fig, ax1 = plt.subplots()
# Duplicate the axes with a different x axis 
# and the same y axi…
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í…
1010/1068
946
>>> t = (1, 4, 9)
>>> t[0] = 2
Traceback (most recent call last): 
File "<stdin>", line 1, …
1011/1068
947
{ (1, 2)} # ok
{ ([], {"hello"}) ) # not ok
t = 'a', 'b', 'c', 'd', 'e'
t = ('a', 'b', 'c',…
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…
1013/1068
949
first, *more, last = (1, 2, 3, 4, 5) 
# first ==1
# more == [2, 3, 4]
# last == 5
colors =…
1014/1068
950
len(tuple1) 
Out: 5
max(tuple1) 
Out: 'e'
max(tuple2) 
Out: '3'
min(tuple1) 
Out: 'a'
…
1015/1068
951
tuple1 + tuple2
Out: ('a', 'b', 'c', 'd', 'e', '1', '2', '3')
Concatenación de tuplas
Usa +…
1016/1068
952
>>> u'□'.encode('utf-8') 
'\xf0\x9f\x90\x8d'
>>> b'\xf0\x9f\x90\x8d'.decode('utf-8') 
u'\U0…
1017/1068
953
type("f") == type(u"f") # True, <class 'str'> 
type(b"f") # <class 'bytes'>
type("f") == typ…
1018/1068
954
>>> print type(u"£13.55".encode('utf8'))
<type 'str'>
>>> print u"£13.55".encode('utf8') 
S…
1019/1068
955
>>> "£13.55".encode('ascii', errors='replace') 
b'?13.55'
>>> "£13.55".encode('ascii', error…
1020/1068
956
open(fn, mode='wb') # open file for writing bytes
# ERROR: cannot write string when bytes is …
1021/1068
957
import urllib
response = urllib.urlopen('http://stackoverflow.com/documentation/')
print res…
1022/1068
958
import urllib
query_parms = {'username':'stackoverflow', 'password':'me.me'} 
encoded_parms …
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:
…
1025/1068
961
Capítulo 202: Uso del módulo "pip": PyPI 
Package Manager
Introducción
A veces es posible q…
1026/1068
962
import pip
command = 'install' 
parameter = 'selenium'
second_param = 'numpy' # You can giv…
1027/1068
963
Fuerza de instalación
Muchos paquetes, por ejemplo, en la versión 3.4 se ejecutarán en 3.6 mu…
1028/1068
964
def list_check(to_check, the_list): 
for item in the_list:
if to_check == item: 
return Tru…
1029/1068
965
class Deque:
def init (self): 
self.items = []
def isEmpty(self):
return self.items == []
…
1030/1068
966
Eliminar: O (n) 
Girar: O (k)
Establecer operaciones
Operación: Caso promedio (asume paráme…
1031/1068
967
del tiempo de los algoritmos.
1. Θ Notación : la notación theta limita las funciones desde ar…
1032/1068
968
import matplotlib.pyplot as plt
# Generate some data for plotting. 
x = [0, 1, 2, 3, 4, 5, 6…
1033/1068
969
import numpy as np # numpy used to create data from plotting 
import seaborn as sns # common …
1034/1068
970
# Using previously created imports and data.
# Use a dark background with no grid. 
sns.set_…
1035/1068
971
# Using previously created data and style
# Access to matplotlib commands 
import matplotlib…
1036/1068
972
MayaVI
MayaVI es una herramienta de visualización 3D para datos científicos. Utiliza el kit d…
1037/1068
973
Plotly
Plotly es una plataforma moderna para el trazado y visualización de datos. Útil para p…
1038/1068
974
import plotly.graph_objs as go 
import plotly as ply
# Create random data with numpy 
impor…
1039/1068
975
1040/1068
976
Capítulo 205: Web raspado con Python
Introducción
El raspado web es un proceso automatizado …
1041/1068
977
# For Python 2 compatibility.
from future import print_function
import lxml.html 
import re…
1042/1068
978
scrapy startproject projectName
import scrapy
class StackOverflowSpider(scrapy.Spider):
nam…
1043/1068
979
from bs4 import BeautifulSoup 
import requests
# Use the requests module to obtain a page
r…
1044/1068
980
from urllib.request import urlopen
response = urlopen('http://stackoverflow.com/questions?sor…
1045/1068
981
import asyncio
from aiohttp import ClientSession 
class EchoWebSocket(ClientSession):
URL =…
1046/1068
982
python -m pip install autobahn
from autobahn.asyncio.websocket import WebSocketServerProtocol…
1047/1068
983
'''When creating server protocol, the 
user defined class inheriting the 
WebSocketServerPro…
1048/1068
984
1049/1068
985
Creditos
S.
No Capítulos Contributors
1
Empezando con 
Python Language
A. Raza, Aaron Cr…
1050/1068
986
user2314737, user2853437, user312016, Utsav T, 
vaichidrewar, vasili111, Vin, W.Wong, weewooq…
1051/1068
987
abstracta
16 Archivos y carpetas I
/ O
Ajean, Anthony Pham, avb, Benjamin Hodgson, Bharel, …
1052/1068
988
Jadhav, tobias_k, Vlad Shcherbina, Will
26 ChemPy - paquete 
de python Biswa_9937
27 Clases…
1053/1068
989
Piersall, Conrad.Dean, Elazar, evuez, J F, James, Or East, 
pylang, RahulHP, RamenChef, Simpl…
1054/1068
990
56 Diccionario
Amir Rachum, Anthony Pham, APerson, ArtOfCode, BoppreH, 
Burhan Khalid, Chris…
1055/1068
991
RamenChef, Régis B., Sebastian Schrader, Serenity, 
Shantanu Alshi, Shrey Gupta, Simon Fraser…
1056/1068
992
79 Explotación florestal Gal Dreiman, Jörn Hees, sxnwlfkk
80 Exposiciónción Anthony Pham, int…
1057/1068
993
, Elodin, Emma, EsmaeelE, Ffisegydd, Gal Dreiman, 
ghostarbeiter, Hurkyl, J F, James, Jeffrey…
1058/1068
994
BusyAnt, Casebash, Christian Ternus, Community, 
Conrad.Dean, Daniel, Dartmouth, Esteis, Ffis…
1059/1068
995
Sharabani, SashaZd, Sayed M Ahamad, SuperBiasedMan, 
theheadofabroom, user2314737, yurib
102…
1060/1068
996
ghostarbeiter, Igor Raush, intboolstring, J F, j3485, jalanb, 
James, James Elderfield, jani,…
1061/1068
997
116 Llama a Python
desde C # Julij Jegorov
115 Listas enlazadas Nemo
117 Maldiciones básica…
1062/1068
998
Shrey Gupta, Simplans, SuperBiasedMan, theheadofabroom, 
user1349663, user2314737, Veedrac, W…
1063/1068
999
138 Módulo operador MSeifert
139 módulo pyautogui Damien, Rednivrug
140 Módulo Sqlite3 Chinm…
1064/1068
1000
los resultados.
153 Patrones de diseño Charul, denvaar, djaszczurowski
154 Perfilado J F, k…
1065/1068
1001
172 Recolección de 
basura
bogdanciobanu, Claudiu, Conrad.Dean, Elazar, FazeL, J F, 
James…
1066/1068
1002
mensajes entre el 
cliente y el servidor
187
Subcomandos CLI 
con salida de ayuda 
preci…
1067/1068
1003
202
Uso del módulo "pip": 
PyPI Package 
Manager
Zydnar
203 Velocidad de Python 
del pr…
1068/1068

Aprende todo sobre Python

  • 1.
  • 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
@ProfGastonPerez

Share

Aprende todo sobre Python

Embed code

Report Inappropriate Content on Jaunt

Choose the reason you are reporting: Aprende todo sobre Python as inappropriate to Jaunt's content team.


Swipe LEFT
to view Related

Scroll DOWN
to read doc

Cookies to automatically collect, record, and share information about your interactions with our site for analytics purposes.
Cookies used to enable advertising on our site.

Login

OR

Forgot password?

Don't have an account? Sign Up