La Gaceta de Linux ...¡ haciendo a Linux un poco más divertido !
Traducción al español por José Gregorio del Sol Cobos
el día 4 de Mayo de 2004, para La Gaceta de Linux
Este artículo fue inspirado por Brian Dorsey, quien hospedaba un encuentro SeaPIG el mes pasado. (SeaPIG es el Seattle Python Interest Group - Grupo de Interés por Python de Seattle). A medida que iba revisando detenidamente las estanterías de su casa, vi que sus libros sobre el Movimiento por la Simplicidad (vea más abajo) coinciden con su fanatismo por la simplicidad en la programación. Brian es un curtido administrador de bases de datos. (En una de las compañías de Paul Allen, ¡buuuh!, sis.) Sabe más SQL que la mayoría de la gente que conozco. Usted pensaría que eso significa que adora la complejidad. ¿No todos los administradores de bases de datos aman la complejidad? (Después de todo, los mantiene empleados.) Pero Brian me asombró revelándome su entusiasmo por probar todos los pequeños módulos de bases de datos de Python que son incomplejos. Él sigue la regla 80/20: algunas veces el 20 % de las características resuelven el problema para el 80 % de la población. Brian también ha estado demostrando algunos otros módulos sencillos durante nuestros últimos encuentros por Python, así que me gustaría compartir con usted unos cuantos.
En la mayoría de los artículos, el autor camina a través del código que ha trabajado extensivamente. (O que pretende que ha trabajado extensivamente.) En este artículo, estoy discutiendo módulos que no he utilizado. El punto no es decir que estos módulos son lo mejor desde las rebanadas de pan (aunque algunos de ellos están chulos). el punto es que estos módulos demuestran simplicidad, bien en su código, bien en su uso.
Por en su código, me refiero a que el módulo en sí es corto. Menos código significa menos oportunidad de que las cosas vayan mal, y por ello más fiabilidad. Éste es el principio KISS: "Keep it Simple, Stupid!" (¡mantenlo sencillo, estúpido!). En su uso se refiere a la perspectivas del usuario: requiere sólo unas cuantas líneas activar sus características. Algunos módulos son sencillos de uno u otro modo, mientras que otros lo son en ambos.
El Servidor Doc XML-RPC se ha convertido en uno de los modos más fáciles de ofrecer servicios en Internet. Es uno de esos inventos que te hace menear la cabeza y pensar "¿Por qué nadie pensó en esto antes?". Suponga que ha escrito sus servicios como métodos de una cierta clase. Quiere ofrecer esos servicios en Internet o en una intranet. Lleva sólo seis líneas de código:
from DocXMLRPCServer import DocXMLRPCServer
server = DocXMLRPCServer(('', 8000), logRequests=0)
server.register_introspection_functions()
server.register_instance(SimpleShareServer())
server.serve_forever()'SimpleShareServer' es una clase que habíamos creado. Empezamos un servidor en el puerto 8000, registramos una instancia de nuestra clase, registramos algunos servicios opcionales que vienen con DocXMLRPCServer ("funciones de introspección"; por ejemplo, 'help' (ayuda), y allá vamos. He aquí los servicios que estamos ofreciendo:
import time
class SimpleShareServer:
def message(self, msg):
"""message('Print me!') => True
Log everything passed to this function"""
print time.asctime(), msg
return True
def wait(self, seconds):
"""wait(5) => 5
Wait for a certain number of seconds before returning.
Returns the same number passed in."""
print time.asctime(), "Waiting %s seconds" % seconds
time.sleep(seconds)
print time.asctime(), "Finished waiting %s seconds" % seconds
return secondsPor supuesto, una rutina local sólo puede instanciar la clase y llamar a los métodos directamente. Para hacer lo mismo en remoto, usted tenía que, bien escribir un protocolo de implementación al uso por sí mismo, bien leer largos libros de referencia para configurar un servidor o librería fuera de la capa. Pero un usuario remoto puede acceder a estos servicios son simplemente un par de líneas de código:
import xmlrpclib
s = xmlrpclib.ServerProxy('http://localhost:8000')
s.message("Hello, simple world!")
result = s.wait(15)Después de que estás líneas se han ejecutado, 'result' es 15, y aparece "Hello, simple world!" ("¡Hola, sencillo mundo!") en la consola del servidor (salida normal). Observe que los argumentos y el valor de retorno se pasaron sólidamente entre cliente y servidor, simplemente como al invocar a un método local. El objeto proxy del servidor "espera" a la instancia remota. Observe que el cliente está usando una librería XML-RPC genérica; no tiene que usar una librería específica para DocXMLRPCServer.
La RPC ("Remote Procedure Call", "Llamada Remota a Procedimiento") ha estado en los sistemas Unix durante décadas. NFS lo usa, por ejemplo. Pero la RPC plana (así me han dicho) no pude cruzar lenguajes de programación. Si el servidor es Python, el cliente también tiene que ser Python, o algo que sepa cómo codificar/descodificar los tipos de argumentos Python.XML-RPC quita la restricción de lenguaje. Los argumentos se convierten a XML neutro, y así es el valor de retorno. Esto tiene algunas limitaciones:
Usted puede pasar sólo tipos normales en Python (incluyendo listas y diccionarios), pero no instancias propias.
No puede pasar None a
menos que monte una opción estándar pero no universal.
Para pasar una cadena que contenga caracteres de control ASCII (decimales 0-31) u otros caracteres no permitidos en XML, tiene que atraparla en una instancia 'Binary'. (Pero no tiene que hacerlo para '<', '>' y '&', que DocXMLRPCServer escapa automáticamente.)
A cambio de estas limitaciones, Perl y otros clientes pueden acceder al servidor --igual que cualquier navegador web puede acceder a un servidor HTTP.
Hablando de HTTP, ésa es la parte más chula de DocXMKLRPCServer. Si un cliente envía un petición POST de HTTP al mismo puerto, el servidor lo reconoce y lo traduce a la llamada al correspondiente método. Esto se podría utilizar para recoger los envíos de formulario de una encuesta, por ejemplo. Si un cliente envía una petición HTTP GET, el servidor responde con una página HTML documentándose a sí mismo. ¿Ha oído hablar de emacs, el Editor Auto-Documentado? He aquí el servidor arbitrario de autodocumentación. Su clase de servidor puede definir tres métodos extras para personalizar la salida de la documentación:
set_server_title(STRING) # Para la etiqueta <TITLE>. set_server_name(STRING) # Para el encabezado <H2>. set_server_description(STRING) # La documentación, en formato HTML.
DocXMLRPCServer está construido sobre SimpleXMLRPCServer, que lo proporciona todo salvo la capacidad HTTP.
Alguien podría objetar, "Pero está usando XML, y XML es decididamente no-simple". Esto es cierto. XML es una horrible bestia bastarda que nunca debería haber visto la luz del día. En teoría, es maravilloso. En la práctica, la mayoría de las DTDs (Document Type Definition, Definición de Tipo de Documento) son innecesariamente complejas y los espacios de nombres están tan puntillosamente detallados que parecen como algo que sólo podría haber diseñado una burocracia --la unión de todos los atributos presionado por cada grupo único de interés. Usted tiene que confiar en que el parser expat o lo que sea que esté usando por debajo del capó no explotará algún día. Así que DocXMLRPCServer no es sencillo en el código del que depende. Pero es sencillo de usar. ¿Vio usted algo XML arriba? Yo no. No me importa el XML si no lo tengo que mirar. Igual que es divertido escuchar a las bandas que suplantan a Elvis mientras me mantenga lejos, así también puedes disfrutar la música sin tener que mirar el estilo hortera de los 50. Pero estoy desvariando...
El SimpleShareServer de arriba está basado en un servidor que Brian mostró en un encuentro SeaPIG, que él describe en una página wiki.
db_row es un módulo corto para envolver un conjunto de resultados de SQL. Los módulos de base de datos DB API (MySQLDb, algunos módulos PostgreSQL, Oracle y otros) devuelven una fila de consulta como una tupla de valores en columna. Alimentemos nuestra propia tupla y veamos qué hace.
tup = (1, 2, 3) # P. ej., "SELECT a, b, a+b FROM SomeTable WHERE id=456;"
R = IMetaRow(['a', 'b', 'sum'])
# Crea una clase personalizada que llama a las filas en orden.
# IMetaRow es una "factoría de clases": crea una clase.
r = R(tup) # Instanciamos nuestra propia clase.
print r[0], r['b'], r.fields.sum
# Imprime "1 2 3". Valores de acceso por subídice, clave o
# atributo. (La "I" in IMetaRow significa que no es sensible al mayúsculas-minúsculas.)
print r.keys() # Mira mamá, ¡métodos de diccionario!
print r.dict() # Simplemente déme un diccionario real, por favorPara convertir un conjunto de resultados multi-fila a una lista, emplee una lista:
lis = [ R(row) for row in cursor.fetchall() ] print lis[0]['a'], "+", lis[0]['b'] print lis[0].fields.sum
Envuelva la lista en una función, y sólo lo tiene que ver una vez.
¿Por qué me gusta este módulo? Es corto. No tienes que esperar a incorporarlo a su módulo de DB API favorito; funciona ya con todos ellos. Funciona con conjuntos de resultados ad-hoc y no SQL también. Resuelve un problema común de una forma sencilla. (No es tan simple. emplea ranuras Python, por ejemplo. Pero ignoraremos esto y confiaremos en que la oscura característica de las ranuras ("slots") de Python haya resuelto sus fallos iniciales). Reclama que usa menos memoria que una lista de diccionarios.
Pero la simplicidad de db_row viene a cambio de ciertas desventajas. No tiene conocimiento de los nombres de los campos de la base de datos ni de los tipos de los datos. Puede mentirle a IMetaRow() y renombrar los campos de la forma que quiera. Esto puede convenir en algunas situaciones, pero en una aplicación con más que unas cuantas tablas puede irse de las manos rápidamente. Confundirse a sí mismo (y mantenedores posteriores) con nombres de campo inconsistentes es decididamente una idea insencilla. O doblemente no bueno como diría Orwell.
(El ejemplo de arriba fue inspirado por la docstring de db_row).
SQLite es un completo servidor SQL codificado en una pequeña librería de C. pysqlite es un envolvente Python (compatible con la DB API). Brian dice que esto es "el 80 % de lo que llegará a necesitar para una base de datos en un único ejecutable (o módulo Python) de 270 Kb".
El "80 % de lo que llegará a necesitar" consiste en transacciones ACID, tipos de datos básicos (cadenas, números. PLOBs, fechas), campos con autoincremento, NULLs, tablas temporales ("CREATE TEMPORARY TABLE"), una utilidad en línea de comandos (à la mysql y psql), volcar una base de datos a sentencias SQL (compatibles con PosgreSQL), y bases de datos gigantescas (2 terabytes). Incluso hay soporte para acceso concurrente al archivo de la base de datos en procesos múltiples, de lo cual me sentí hermosamente asombrado. Aunque no se puede almacenar cadenas que contengan caracteres nulos (0 decimales). El esquema de la base de datos se almacena en una tabla llamada 'sqlite_master'. La seguridad se implementa mediante permisos de archivo.
Otra rareza de SQLite es que no está tipado. Usted puede poner letras en un campo numérico, signifique lo que signifique. En realidad, eso significa que una base de datos está pensada par almacenar datos, no para imponer los suyos sobre los datos. Los desarrolladores de SQLite dicen que el rígidos sistema de tipos del SQL normal y de muchas de sus implementaciones es una"descaracterística". (Vea la página de tipos de datos en la documentación de SQLite para la justificación completa). Los campos se pueden crear con todos los especificadores de tipo habituales en SQL, pero son sólo ayudas para el usuario, no reglas a las que fuerce SQLite. En realidad, SQLite hace honor a los tipos en algún grado: influyen en el orden de ordenación y si dos valores son iguales. Hay una excepción en la permisividad de SQLite: los campos con autoincremento ("INTEGER PRIMARY KEY") tienen que ser enteros.
Hay unos cuantos envolventes orientados a objetos para acceso a SQL, incluyendoSQLObject y DBO.<7SQLObject and DBO.
ctypes es un modo de llamar a librerías de C directamente desde Python, que se supone más fácil que SWIG.
Python 2.2 introdujo tres características que llevó un tiempo que llegaran hasta las mentes de las personas, pero que resultaron ser increíblemente útiles: los iteradores, los generadores y las propiedades. Los iteradores le permiten tener un bucle "for" sin tener que pregenerar la secuencia entera de valores y mantenerlos simultáneamente en memoria. Los generadores permiten un modo fácil de que una función itere: prescinde del bucle for más alto, dejándole mayor espacio horizontal en pantalla y menos desorden. La propiedades le permiten definir"pequeños" atributos: aquellos que lanzan una acción cuando se establecen o son captados. Las propiedades proporcionan controversia entre algunos puristas, pero impiden la torpeza de los métodos accededores (como la parentesitis, que es una seria enfermedad entre los C/Java-fóbicos).
Python 2.3 continúa el camino con más características que simplifican los programas. Los sets ("conjuntos") son como diccionarios sin los valores ("sólo las llaves, por favor"). Si no está usando un diccionario sólo para deserbar duplicados, ¿por qué definir "valores" que no va a usar? Hay un módulo de autentificación ("logging") y un sencillo objeto DateTime. Pero lo que yo más uso es enumerate():
>>> lis = ['vanilla', 'chocolate', 'strawberry'] >>> for i, element in enumerate(lis):: ... print "Element %d is %s." % (i, element) ... Element 0 is vanilla. Element 1 is chocolate. Element 2 is strawberry.
Esto es una característica requerida desde hacía mucho que impide lo equivalente pero más torpe:
>>> for i in range(len(lis)): ... element = lis[i] ... print "Element %d is %s." % (i, element) ... Element 0 is vanilla. Element 1 is chocolate. Element 2 is strawberry.
"Y ahora algo completamente diferente..."
El movimiento por la simplicidad, liderado por autores como Amy Daczyczyn (autora de The Tightwad Gazette, un "paper zine"), Joe Dominguez & Vicki Robin, Cecile Andrews, Elaine St James y otros, está a punto de decidir qué es lo que usted realmente quiere de la vida y qué posesiones materiales realmente le importan. Mantenga lo que necesite o quiera (por ejemplo, una afición), y líbrese de lo que no sea una prioridad para que no sea una distracción. Puede parecer que esto no tenga mucho que ver con la programación, pero veremos que sí tiene. He aquí unas pocas gemas de las teorías:
Hay dos caminos hacia un nivel de vida más alto: ganar 100 dólares más al mes, o cortar los gastos en 100 dólares cada mes. Los dos consiguen lo mismo: 100 dólares m ás en su bolsillo. La mayoría de la gente adoptan la primera estrategia, pero eso implica depender de alguien más: tienes que convencerles de que te den el dinero. Por contra, cortar gastos está completamente bajo su control. Que los dos cónyuges trabajen implica más gastos de transporte, ropa, comida, cuidado diario y relax; ¿está seguro de que sus ingresos netos son realmente mayores que sin ese segundo trabajo? ¿Qué hay sobre la oportunidad perdida de que el segundo cónyuge tenga una afición o sea un voluntario a tiempo completo? Yo adoro mi libertad de no tener coche; me da suficiente dinero para viajar dos veces al año. Seguro que limita dónde vivo y trabajo, pero ésos son los lugares donde quiero estar de todos modos.
Entonces aquí está la cuestión de la tecnología. Los Amish pueden ser un poco demasiado "luddistas" (personas opuestas al avance tecnológico - nota del traductor) para el gusto de la mayoría de la gente, pero tienen una cosa buena: aceptan la nueva tecnología con cuidado, y sólo cuando se ha probado que funciona. Adoro mi móvil, pero mi radio parece que vino del 1987 (que así fue).
Esto lleva directamente a la sostenibilidad medioambiental, y la teoría del derroche. ¿Por qué pagar por algo que no quieres (y que nadie quiere)? ¿Compró usted la compota de manzana por el aluminio que viene dentro? ¿La compró porque tiene un cierre extra de plástico encima de todo?¿La compró por la energía empleada y por las aguas residuales necesarias para producir la lata? No puedo discutir todo esto con propiedad aquí, pero hay un libro, Natural Capitalism(Amantes, el texto completo en línea en www.natcap.org), que fácilmente es el libro más importante del siglo XXI hasta ahora. Mira hacia la cuestión del derroche desde la perspectiva del individuo, del hombre de negocios y del político, y a cómo el sistema (de EE.UU.) de cuentas e impuestos permite a las compañías externalizar el coste medioambiental, que sesga falsamente sus afirmaciones de beneficio/pérdida y los precios de sus acciones. Pero lleva sólo un cambio en el modelo de negocios para empezar a eliminar el derroche, trabajar con el medio más que contra él, y recoger un mayor beneficio al mismo tiempo. Buen material, Maynar.
¿Qué tiene que ver todo esto con la simplicidad al programar? Los principios son los mismos. Decida qué quiere realmente, y busque una herramienta que hagaeso. Puede que SQL sea el maullido del gato, ¿pero realmente necesita todas las características de MySQL o PosgreSQL? Puede que sí, pero es bueno reasegurarse de haber pensado exactamente qué características necesita y por qué las necesita. (Especialmente cuando Posgres comete un fallo de segmentación y usted se pregunta ¿por qué elegí esto?) O puede ser que SQL no sea el maullido del gato, y que algo como una base de datos de objetos como ZODB, o algo incluso más ligero como DBM o "pickle/shelve" podría hacer el trabajo.
Para concluir este artículo, tengo que mencionar la invención más divertida de Brian. Aquí hay una entrada wiki describiéndola:
Algunos de mis amigos tienen un chiste Marcklar engendrado a partir de un episodio de South Park(Ejemplo. Para Marklarizar para la revisión del episodio piche aquí y busque 'Marklar'). Versión corta: Hay alienígenas que usan la palabra marklar para cada nombre - y número, no confunde.Después de un largo fin de semana de sobredosis de Marklar, se me ocurrió correr a una lista de palabras gratis que incluía parte de diálogo (Greg Ward's Moby). Algo se encendió en mente y decidí que tenía que hacer un proxy web marklarizante, para que toda Internet se pudiera ver como la vería un Marklar. Ocho horas y algún bello horrible código después (la mayor parte en el lado del parcheador & HTML, aunque las librerías que usé y el programa que escribí tienen solo un par de hojas cada uno), tuve algo que funcionaba en su mayor parte. De todos modos, lo mostré en el encuentro, y ésa fue nuestra página favorita. Es un artículo de un periódico.
Dos arrestados por ejecutar marklar-end marklar marklar Por Marklar Ko Marklar Marklars staff marklar Los detectives de marklar del Condado de marklar han dispersado un gran marklar marklar en el marklar Marklar, y dijeron que habían recuperado un "libro negro" con los nombres de cientos de marklars, incluyendo hombres que trabajan para los marklars marklars acuartelados en Marklar. Los dos marklars del marklar, una mujer de 49 años marklar de edad que vive en Marklar, y su marklar de 31 años marklar de edad, que vive en Marklar, fueron arrestados. No fueron acusados. Los dos marklars usaban Internet para anunciar una compañía de guardaespaldas marklar llamada "Marklar de Marklar". El sitio web tenía imágenes de compañeros disponibles, un calendario de cuándo estaban disponibles y marklars. Los marklars se podían hacer en línea. Algunos de los escoltas fueron llevados allí desde fuera del estado "Las Marklars, New Marklar y Los Marklars", para trabajar marklar, de acuerdo al Marklar de Marklar. Los markars fueron cuidadosamente investigados, dijo el Sargento Marklar Marklar de los marklars. Por ejemplo, los marklars potenciales tenían que dejar un número de trabajo, y alguien dentro del marklar marklar marklarizaría el nombre, marklarizarlo para confirmar un marklar dental, dijo. Esto se hizo para asegurarse de que el marklar no era agente de policía, según Marklar. El Marklar de Marklar marklarizó que no entregó los nombres de los marklars para los que trabajó, para evitar mancillar a las compañías, dijo Marklar. Los hombres del libro, sin embargo, marklarizaron para ser contactados pronto, dijeron los detectives. Podían hacer frente a los cargos marklar de tratar con una prostituta. En los 90, los dos marklars se vieron envueltos en otro marklar marklar en el marklar llamado "Marklars ricos". Un marklar escribió el Marklar de Marklar sobre el Marklar de marklar.
Mike
es el Editor Jefe de Linux Gazette. Usted puede leer lo que él
tiene que decir en la Contraportada de muchos números. Ha sido
un entusiasta de Linux desde 1991 y usuario de Debian desde 1995. Fue
coordinador técnico web de SSC de 1999 á 2003, lo que
implica que tuvo que escribir un montón de guiones en Python.
Ahora está involucrado en tres proyectos de software libre
para Python (Cheetah,
Webware y YAML),
escribe pruebas de unidades y programas para un sitio de comercio
electrónico de Webware, y edita LG desde su casa. Los
intereses no informáticos incluyen la lucha libre, el ska and
oi! y la música ambiental, y el lenguaje internacional
Esperanto. Se sabe que escucha a Dvorak, Schubert, Mendelssohn, y
también a Khachaturian.