¡Esta es una revisión vieja del documento!
Clases, módulos y funciones própias de Python.
my_str = 'Hola buenos días!' # Definición de un string 'ola' in my_str # Saber si un string forma parte de otro string my_str[-1:] # Recoger el último caracter my_str[2] # Recoger el segundo carácter my_path = u"c:\windows" # Omite los carácteres de escape len(my_str) # Saber el tamaño del string my_str + my_str2 # Concatena el string my_str con my_str2
upper(): Pasa a mayúsculas.startswith(t)endswith(t)islower()isupper()isalpha(), si todos los caráceres son letras.isalnum(), si todos los carácteres son alfanuméricos (letra o número).isdigit(), si todos los carácteres son dígitos.istitle(), si todas las palabras inician con mayusculas.find(s), devuelve el primer índice de s, si no existe devolverá -1. rfind(s) devolverá el último índice.replace(s1, s2), reemplaza s1 por s2.encode(s), devolverá el string con la codificación indicada como s.strip(), hace un trim del string.capitalize(), pone la primera letra en mayúsuculas.Modo antiguo:
"La capital de %s es %s" % ("Araba", "Gasteiz") # 'La capital de Araba es Gasteiz' "%s tiene %d provincias y %4d habitantes" % ("Araba", 1, 100) # 'Gasteiz tiene 1 provincias y 0100 habitantes' "Cada uno con %.2f ojos" % (2.5457) # 'Cada uno con 2.54 ojos'
Modo nuevo, con método format:
'{0} and {1}'.format('spam', 'eggs') # spam and eggs 'This {food} is {adjective}.'.format(food='spam', adjective='absolutely horrible') # This spam is absolutely horrible. 'The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', other='Georg') # The story of Bill, Manfred, and Georg. 'The value of PI is approximately {0:.3f}.'.format(math.pi) # The value of PI is approximately 3.142. '{0:10} ==> {1:10d}'.format('Jack', 4098) # Jack ==> 4098
Otra forma:
str = 'Name: {user.name}, Age: {user.age}, Sex: {user.sex}'.format(user=user)
Podemos hacer uso de !s y !r que llaman al str() y al repr() del objeto. Combinándolo queda:
subscriber.connect("tcp://127.0.0.1:{port!s}".format(port=ZPORT)) subscriber.connect("tcp://127.0.0.1:{0!s}".format(ZPORT))
\u, indica que lo que sigue es un carácter unicode. u'string' # indica que el string contiene carácteres unicode r'string' # indica que el string es raw (que no se tendrán en cuenta los carácteres de escape) s1 = '''Esto es un string multilínea''' # crea un string multilínea
# Unir un vector en un string: " ".join(['a','b','c']) # Sacaría: 'a b c' ":".join(['a','b','c']) # Sacaría: 'a:b:c'
from datetime import datetime datetime.now() # momento actual datetime.time(datetime.now()) # hora actual datetime.date(2006, 5, 6).isoformat() # crea un datetime y lo devuelve como string en un formato fácilmente legible (2006-05-06)
import time time.localtime() # recoge el momento actual time.ctime(longValue/1000) # crea una fecha a partir de un long
Comparación utilizando objetos datetime:
now = datetime.datetime.now() today8am = now.replace(hour=8, minute=0, second=0, microsecond=0) now < today8am now == today8am now > today8am
Cmparación utilizando timedelta:
from datetime import datetime, timedelta then = datetime.now () - timedelta (hours = 2) now = datetime.now () (now - then) > timedelta (days = 1) (now - then) > timedelta (hours = 1)
La llamada a la función open() devuelve un objeto del tipo File, los argumentos son la ruta del fichero y el modo.
El modo puede ser 'r' para leer (si se omite es el que se utiliza por defecto), 'w' para escribir (truncando si ya existe) y 'a' para agregar.
Podemos agregar 'b' al modo, esto hará que abramos un fichero en modo binario.
var = open ("c:\\prueba.txt") for file in var.readlines(): print file, var.close()
close(), cierra el fichero.read(), lee hasta el final del fichero.read(i), lee i carácteres a partir de la última lectura.fileno(), retorna el número del descriptor del fichero.seek(i), se mueve i bytes.tell(), indica la posición del fichero.write(s)writelines(lst)closedencodingimport os os.path.abspath(rel_path) # Devuelve el path absoluto al que apunta rel_path os.path.basename(obs_path) # Devuelve el nombre del fichero os.mkdir(path) # Crea un directorio os.sep # Devuelve el separador de directorios del sistema os.listdir(path) # Devuelve una lista con los nombres de archivos os.path.exists(path) # Indica si un fichero existe os.path.isdir(path) # Indica si es directorio os.path.isfile(path) # Indica si es fichero os.path.getsize(path) # Devuelve el tamaño de un fichero os.remove(path) # Borra un fichero
import shutil shutil.rmtree(path) # Elimina un directorio shutil.copytree(src, dst) # Copia un directorio shutil.copyfile(src, dst) # Copia un fichero shutil.move(src, dst) # Mueve un fichero
import os path = raw_input("Specify a folder that you want to perform an 'os.walk' on: >> ") for root, dirs, files in os.walk(path): print root print dirs print files print "---------------"
from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument('-f', '--foo', help='foo help') args = parser.parse_args() print args.foo
add_argument permite, entre otros, los siguientes parámetros:
name o flags: un nombre o lista de opciones, ejemplos: foo, -f, --fooaction: una acción especial para ese argumento (ver ayuda).store_true o store_false: store_true significa que si se especifica la opción entonces se asignará True al valor de este: parser.add_argument(“–verbose”, help=“increase output verbosity”, action=“store_true”)default: el valor por defecto.parser.add_argument('–foo', default=42)type: el tipo de la variable.parser.add_argument('–foo', type=int)choices: posibles opciones: parser.add_argument('foo', type=int, choices=range(5, 10))parser.add_argument('move', choices=['rock', 'paper', 'scissors'])required: indica si el argumento es obligatorioparser.add_argument('–foo', required=True)help: texto de ayudametavar: el nombre del argumento dentro de la ayuda.dest: el atributo de destino.
El constructor de ArgumentParser acepta los siguientes parámetros:
prog: el nombre dle programa.usage: el string de ayuda.parents: array de ArgumentParser de los cuales sus argumentos se incluirán junto con los de este.
Se utiliza el objeto OptionParse del paquete optparse
from optparse import OptionParser # Crear objeto OptionParser e indicar el uso del ejecutable parser = OptionParser(usage="SRCDS.py -a ADDR -p RCONPASS [command]") # Añadir parametros a gestionar parser.add_option("-p",dest="rcon",default="",help="Specifies the rcon password") parser.add_option("-a",dest="addr",default="",help="Specifies the address of the server to connect to") # Parsear parametros (options,args) = parser.parse_args() # Tratar parametros if not options.addr: os.system(sys.argv[0] + " -h") sys.exit(1) print("Connecting to %s with rcon password of %s" % (options.addr,options.rcon))
Emisor:
MYPORT = 5000 import sys, time from socket import * s = socket(AF_INET, SOCK_DGRAM) s.bind(('', 0)) s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) while 1: data = repr(time.time()) + '\n' s.sendto(data, ('<broadcast>', MYPORT)) print 'send!', data time.sleep(2)
Receptor:
import socket import struct sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('', 5000)) while True: print sock.recv(10240)
Para utilizarlos importaremos el módulo threading.
Podemos llamar a una función haciendo:
thread = threading.Thread(target=myFunc) thread.start()
Un thread tiene la propiedad daemon, si esta es True cuando el thread padre acabe el thread hijo también lo hará (pero cuidado, esto puede hacer no liberar el recurso que estaba utilizando un objeto Event (poniéndolo como flag en el bucle principal).
Event sirven para comunicarse entre threads. Consisten en una flag que puede estar a True o a False sus métodos importantes on:wait, que hará esperar hasta que la flag sea True.set, que pondrá la flag a True.isSet o is_set que indicará el estado de la flag.reset que pondrá la flag a False.Lock sirven para indicar una zona de exclusión mutua. Utilizaremos su método acquire para adquirirla y el release para liberarla:self.mutex = Lock() def initProcess (self): self.mutex.acquire() host = self.results.get() self.mutex.release() return host
En el módulo multiprocessing podemos encontrar clases como Process, para lanzar un proceso a parte, Pool, para lanzar varios procesos, Pipe o Queue para la comunicación entre ellos…
La clase Pool permite lanzar varios procesos, en el constructor se le pasa el número de procesos que gestionará y al llamar al método map se le indicará qué función corresponderá a qué proceso y el array de parámetros para cada uno de ellos:
from multiprocessing import Pool servers = config['servers'] # Servers array de diccionarios procs = Pool(processes=len(servers)) procs.map(askServerInfo, servers) # askServer es una función que recibe un único parámetro
Uso de Queue y procesos sueltos:
from multiprocessing import Queue, Process class AskServerInfo (Process): def __init__(self, server, queue): Process.__init__(self) self.server = server self.queue = queue def run (self): # action to obtain info from self.server self.queue.put(self.server) if __name__ == "__main__": config = readConfigFile('servers.yml') nservers = len(config['servers']) results = Queue() for server in config['servers']: worker = AskServerInfo(server, results) worker.start() while nservers: info = results.get() saveInfo(info) nservers = nservers - 1
import re for w in wordlist: print re.search('^..j', w) # imprime None o un objeto patrón encontrado según si w cumple el patrón [w for w in wordlist if re.search('^..j', w)] # devuelve lista de palabras que su tercer carácter sea la j word = 'supercalifragilisticoespialidoso' re.findall(r'[aeiou]', word) # devuelve la lista de vocales directamente (sin necesidad de recorrer el resultado) re.split(regex, text) # corta un texto a partir de una expresión regular re_pattern='(/+)|(~+)|("+)|(;+)|(,+)|(!+)|(\.)+|(:+)|(\(+)|(\)+)' re.sub(re_pattern, ' ', texto) # substituye un patrón en el texto
Los paréntesis nos permiten indicar qué se ha de retornar en caso de encontrar un matching. Agregando ?:, :?, ? al principio o al final de estos podremos indicar qué parte del matching nos interesa.
Mediante < y > podemos seleccionar palabras:
<a>(<.*>)<man> devolverá los adjetivos que se le agregan a “a man” (nervous, dangerous, white…).unicode('abcdef') # devuelve el string en formato unicode: u'abcdef' s.encode('utf8') # devuelve el string s en formato utf-8 unicode_char = u'\u0061' # asigna un string con codificación unicode, en este caso unicode_char tomaría el valor 'a' unicode('\x80abc', errors='strict') # errors puede tomar los valores 'strict', 'replace' o 'ignore'
import codecs f1 = codecs.open(path1, encoding='latin2') # abre un archivo para leer con una codificación latin2 f2 = codecs.open(path2, 'w', encoding='utf-8') # abre un archivo para escribir codificandolo en utf-8
title = u"Klüft skräms inför på fédéral électoral große" import unicodedata unicodedata.normalize('NFKD', title).encode('ascii','ignore') 'Kluft skrams infor pa federal electoral groe'
Encontraremos una serie de parsers en el módulo sgllib.
import xml.dom.minidom archivo = xml.dom.minidom.parse('archivo.xml') # cargar el archivo archivo.toxml() # mostrar el código xml elements = archivo.getElementsByTagName('name') # recoge los nodos con nombre name nodo = elements.item(0) # recoge el primer elemento nodo.hasChildNodes() # devuelve si tiene nodos hijos nodo.nodeName # nombre del nodo nodo.nodeType # tipo del nodo nodo.nodeValue # valor del nodo subnds = nodo.childNodes # devuelve los nodos hijo del nodo actual attr = nodo.attributes # devuelve los atributos del nodo actual subn = attr.getNamedItem('tal') # retorna el atributo 'tal' del nodo actual xmldoc.getElementsByTagName('title')[0].firstChild.data from xml.dom.minidom import parseString file = open('somexmlfile.xml','r') data = file.read() file.close() dom = parseString(data)
Si el nodo actual tiene un valor, del estilo <nombre>nom</nombre>; el nodo actual tendrá como nodeName “nombre” pero None como nodeValue, para acceder a su valor tendrás que coger sus nodos-hijo y el primer elemento de estos tendrá el nodeName a None pero el nodeValue como “nom”.
Para más información lee “Python and XML - An introduction.pdf” en los documentos.
A partir de la versión 2.6 de Python podemos utilizar un encoder\decoder de JSON en Python.
Para codificar a JSON:
import json json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) # '["foo", {"bar": ["baz", null, 1.0, 2]}]'
Para decodificar de JSON:
import json json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') # [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
from urllib import urlopen web = urlopen('http://www.google.es') # abre un stream web web.read() # lee la web indicada web.close() # cierra el stream de la web
urlopen.Para su uso utilizaremos el módulo pickle.
Desde la versión 2.5, y de forma nativa, en Python podemos utilizar el módulo sqlite3 el cual nos permite hacer uso de este motor de base de datos.
import sqlite3 db = sqlite3.connect('c:\\prueba.db') # abrimos una conexión a un fichero de base de datos c1 = db.cursor() # recogemos un cursor de acceso a la DB c1.execute('insert into data (id) values (1)') # indicamos el comando db.commit() # tras un comando se realiza un commit c2 = db.cursor() c2.execute('select * from data') # indicamos la consulta a lanzar for row in c2: # recorremos el cursor print row c3 = db.cursor() c3.execute('select * from data') lst = c3.fetchall() # extrae el resultado en una lista c1.close() # cerramos la primera conexión
t = time.localtime() ts = sqlite3.Timestamp(t[0], t[1], t[2], t[3], t[4], t[5]); c.execute ("insert into fecha (fecha) values (?)", (ts,))
query = u'''insert into data VALUES(?, ?)''' c = db.cursor() b = sqlite3.Binary(data) c.execute(query,(id,b)) db.commit()
Existe el módulo binascii que trae distintas funciones para recoger los datos en un formato u otro:
import binascii binascii.b2a_base64(data) binascii.b2a_hex(data) binascii.b2a_uu(data) binascii.crc32(data, 0) binascii.hexlify(data)
También podemos hacerlo mediante el módulo array, este define un objeto con un tipo concreto (caracteres, integers, floats…) el cual se indica en la creación que es de la siguiente forma:
import array a = array.array('c', data)
Siendo el primer parámetro pasado (c en este caso) el tipo que es. Los tipos se definen por (c (caracter a partir de un byte), b, B, u, h (short a partir de dos bytes), H, i (integer a partir de dos bytes), I, l (long a partir de cuatro bytes), L, f (float a partir de cuatro bytes), d (doubles a partir de cuatro bytes)).
Muy útil para la extracción de datos tipados de una cadena en bytes, y viceversa, pasar datos a cadena de bytes.
Para recoger datos utilizamos la función unpack a la cual se le pasa un formato (que se forma a partir de los valores de la siguiente tabla) y la cadena de bytes:
| format | tipo leido | numero de bytes |
|---|---|---|
| c | char | 1 |
| b | byte | 1 |
| B | ubyte | 1 |
| h | short | 2 |
| H | ushort | 2 |
| i | int | 4 |
| I | uint | 4 |
| l | long | 4 |
| L | ulong | 4 |
| q | long (64b) | 8 |
| Q | ulong (64b) | 8 |
| f | float | ? |
| d | double | 8 |
| s | char[] | 1 |
| p | char[] | 1 |
Con este formato podríamos indicar qué es lo que viene en la cadena de bytes pasada, por ejemplo, cHIII esperaría a leer de los bytes un carácter, un unsigned short y tres unsigned int, es decir, la cadena de bytes debería de tener 11 bytes. El ejemplo también lo podríamos escribir como cH3I, el resultado sería una lista. En el siguiente ejemplo se tiene un array de bytes (data) y se sabe que el primer es un número y el segundo un carácter. Luego también habría otro byte, pero este se imprimiría en la siguiente línea:
print struct.unpack("Bc", data[:2]) print struct.unpack("B", data[2:3])
El primer carácter del formato puede indicar hacia donde se dirigen los bytes, por ejemplo puede ser:
!: Como se envia por red.<: Little-endian.>: Big-endian.
Otras funciones útiles podrían ser calcsize que pasándole un formato indica qué tamaño debería de tener este:
struct.calcsize('hhl') # 8
O también podemos aprovechar el tipo namedtuple para crear objetos:
from collections import namedtuple Student = namedtuple('Student', 'name serialnum school gradelevel') Student._make(unpack('<10sHHb', data)) # Student(name='raymond ', serialnum=4658, school=264, gradelevel=8)
Y si quisieramos leer de un archivo binario…
import struct f = file('test.chm','r') s = f.read(4*1 + 3*4) struct.unpack("4s3I", s) # ('ITSF', 3L, 96L, 1L)
Niveles de log: DEBUG, INFO, WARNING, ERROR, CRITICAL
El nivel por defecto es WARNING.
Desde cualquier módulo que se llame a logging se escribirá en el log general.
import logging logging.warning('Watch out!') logging.info('I told you so')
Esto tendrá la siguiente salida. No aparece la de info debido a que no se ha cambiado el nivel por defecto y root es el log por defecto también:
WARNING:root:Watch out!
import logging logging.basicConfig(filename='example.log',level=logging.DEBUG) logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too')
Mediante los parámetros de logging.basicConfig podemos indicar:
filename: fichero de log.level: nivel de log (logging.DEBUG, logging.WARNING…)filemode: según lo que se haga con el fichero (w para reescribirlo cada vez que arranque).datefmt: Para indicar el formato de la fecha ('%m/%d/%Y %I:%M:%S %p').Podemos crear varios logs (a parte del root) para organizarlo:
logger1 = logging.getLogger('myapp.area1') logger2 = logging.getLogger('myapp.area2') logger1.debug('Quick zephyrs blow, vexing daft Jim.') logger1.info('How quickly daft jumping zebras vex.') logger2.warning('Jail zesty vixen who grabbed pay from quack.') logger2.error('The five boxing wizards jump quickly.')
Añadir, por ejemplo, la consola y darle otro formato (los sublogs también lo cogerán):
console = logging.StreamHandler() console.setLevel(logging.INFO) formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') console.setFormatter(formatter) logging.getLogger('').addHandler(console) logging.info('Jackdaws love my big sphinx of quartz.')
import logging import logging.config logging.config.fileConfig('logging.conf') logger = logging.getLogger('simpleExample') logger.debug('debug message')
Este sería el contenido de logging.conf:
[loggers] keys=root,simpleExample [handlers] keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG handlers=consoleHandler [logger_simpleExample] level=DEBUG handlers=consoleHandler qualname=simpleExample propagate=0 [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=simpleFormatter args=(sys.stdout,) [formatter_simpleFormatter] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s datefmt=
Desactivar el log:
logging.getLogger().disabled = True
A partir del módulo imp podemos realizar imports por código. Este módulo tiene funciones como…
load_module para cargar el módulo.También podemos hacerlo:
mod = __import__(name_module) cls = getattr(mod, name_class)
O importar una ruta:
def import_path (mpath): from imp import load_source from os import path fname = path.basename(obs_path)[:-3] return load_source(fname, mpath)
random.random.choice escoge un elemento de la lista.random.randint devuelve un entero entre dos números (incluidos).time existe la función sleep.copy.copy copiará un objeto en otro.random.shuffle desordenará una colección.