<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Calcifer &#187; python</title>
	<atom:link href="http://blog.calcifer.com.ar/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.calcifer.com.ar</link>
	<description></description>
	<lastBuildDate>Sat, 02 Oct 2010 05:32:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Alternativa al sistema de templates de Django, parte 1: Jinja2</title>
		<link>http://blog.calcifer.com.ar/2010/10/alternativa-al-sistema-de-templates-de-django-parte-i-jinja2/</link>
		<comments>http://blog.calcifer.com.ar/2010/10/alternativa-al-sistema-de-templates-de-django-parte-i-jinja2/#comments</comments>
		<pubDate>Fri, 01 Oct 2010 19:46:17 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[jinja]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=852</guid>
		<description><![CDATA[Django es un gran framework web pero tiene un sistema de templates que a un programador puede resultarle un tanto limitado:

No es posible asignar variables ni cambiar sus valores.
No hay distinción entre métodos y propiedades.
No es posible pasar parámetros a los métodos.
No existe la sentencia elif ! :P

Hay varias alternativas entre las que elegir: Jinja2, [...]]]></description>
			<content:encoded><![CDATA[<p>Django es un gran framework web pero tiene un sistema de templates que a un programador puede resultarle un tanto limitado:</p>
<ul>
<li>No es posible asignar variables ni cambiar sus valores.</li>
<li>No hay distinción entre métodos y propiedades.</li>
<li>No es posible pasar parámetros a los métodos.</li>
<li>No existe la sentencia elif ! :P</li>
</ul>
<p>Hay varias alternativas entre las que elegir: <a href="http://jinja.pocoo.org/2/" class="external">Jinja2</a>, <a href="http://www.makotemplates.org/" class="external">Mako</a>, <a href="http://genshi.edgewall.org/" class="external">Genshi</a>, <a href="http://www.cheetahtemplate.org/" class="external">Cheetah</a>. De todas, Jinja2 es el que tiene la sintáxis más <a href="http://jinja.pocoo.org/2/documentation/faq#how-compatible-is-jinja2-with-django" title="How Compatible is Jinja2 with Django?" class="external">compatible con Django</a>, pero tiene otra filosofía y por lo tanto permite hacer <a href="http://jinja.pocoo.org/2/documentation/templates" title="Template Designer Documentation" class="external">más cosas</a>. Empecemos entonces por la instalación.</p>
<h3>Instalación de Jinja2</h3>
<p>Jinja puede instalarse mediante<code>easy_install</code>:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">sudo easy_install jinja2</div></div>
<p>Y mediante<code>apt</code>en debian y derivados:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">sudo apt-get install python-jinja2</div></div>
<h3>Integración con Django</h3>
<p>El diseño de bajo acoplamiento de Django permite que usar otro sistema de templates sea sencillo. Para Jinja basta con definir una variable de ambiente y escribir los métodos alternativos para<code>render_to_string</code>y<code>render_to_response</code>. A continuación muestro la forma más simple que encontré. Hay otras más sofisticadas por ahí (<a href="http://appengine-cookbook.appspot.com/recipe/upgrade-the-django-templating-system-to-jinja2/" class="external">esta</a> y <a href="http://djangosnippets.org/snippets/1061/" class="external">esta</a>) pero básicamente hacen lo mismo:</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># jinja_helper.py</span><br />
<span class="kw1">from</span> django.<span class="me1">conf</span> <span class="kw1">import</span> settings<br />
<span class="kw1">from</span> django.<span class="me1">http</span> <span class="kw1">import</span> HttpResponse<br />
<span class="kw1">from</span> jinja2 <span class="kw1">import</span> Environment, FileSystemLoader<br />
<br />
jinja_env = Environment<span class="br0">&#40;</span><br />
&nbsp; &nbsp; loader=FileSystemLoader<span class="br0">&#40;</span><span class="kw2">getattr</span><span class="br0">&#40;</span>settings, <span class="st0">'TEMPLATE_DIRS'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<br />
<span class="kw1">def</span> render_to_string<span class="br0">&#40;</span>template_path, context=<span class="kw2">None</span>, <span class="sy0">**</span>kwargs<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; template = jinja_env.<span class="me1">get_template</span><span class="br0">&#40;</span>template_path<span class="br0">&#41;</span><br />
&nbsp; &nbsp; context = <span class="kw2">dict</span><span class="br0">&#40;</span>context <span class="kw1">or</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> template.<span class="me1">render</span><span class="br0">&#40;</span><span class="sy0">**</span>context<span class="br0">&#41;</span><br />
<br />
<span class="kw1">def</span> render_to_response<span class="br0">&#40;</span>template_path, context=<span class="kw2">None</span>, <span class="sy0">**</span>kwargs<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">return</span> HttpResponse<span class="br0">&#40;</span>render_to_string<span class="br0">&#40;</span>template_path, context, <span class="sy0">**</span>kwargs<span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mimetype=<span class="kw2">None</span><span class="br0">&#41;</span></div></div>
<p>La vista entonces no difiere mucho de una vista tradicional:</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># views.py</span><br />
<span class="kw1">from</span> jinja_helper <span class="kw1">import</span> render_to_response<br />
<br />
<span class="kw1">def</span> index<span class="br0">&#40;</span>request<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; title = <span class="st0">&quot;hello world.&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> render_to_response<span class="br0">&#40;</span><span class="st0">'index.html'</span>, <span class="kw2">locals</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div></div>
<div class="codecolorer-container html4strict " style="overflow:auto;white-space:nowrap;width:435px"><div class="html4strict codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc-1">&lt;!-- index.html --&gt;</span><br />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/h1.html"><span class="kw2">h1</span></a>&gt;</span>{{ title }}<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/h1.html"><span class="kw2">h1</span></a>&gt;</span></div></div>
<p><span id="more-852"></span></p>
<h3>Escribir un <del datetime="2010-10-02T04:56:46+00:00">libro</del> filtro</h3>
<p>Un filtro es una función de python que se agrega a la lista<code>filters</code>:</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># filter.py</span><br />
<span class="kw1">from</span> jinja_helper <span class="kw1">import</span> jinja_env<br />
<br />
<span class="kw1">def</span> toupper<span class="br0">&#40;</span>s<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">return</span> s.<span class="me1">upper</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<br />
jinja_env.<span class="me1">filters</span><span class="br0">&#91;</span><span class="st0">'toupper'</span><span class="br0">&#93;</span> = toupper</div></div>
<p>Cuando el filtro recibe un sólo argumento la forma de uso es similar a Django:</p>
<div class="codecolorer-container html4strict " style="overflow:auto;white-space:nowrap;width:435px"><div class="html4strict codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc-1">&lt;!-- index.html --&gt;</span><br />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/h1.html"><span class="kw2">h1</span></a>&gt;</span>{{ title|toupper }}<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/h1.html"><span class="kw2">h1</span></a>&gt;</span></div></div>
<p>Para pasar más argumentos se usa la forma<code>arg1|func(arg2, ...)</code>.</p>
<p>Para la asignación a jinja_env.filter pordemos usar un decorador:</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># filter.py</span><br />
<span class="kw1">from</span> jinja_helper <span class="kw1">import</span> register_filter<br />
<br />
@register_filter<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="kw1">def</span> toupper<span class="br0">&#40;</span>s<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">return</span> s.<span class="me1">upper</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></div>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># jinja_helper.py</span><br />
<span class="kw1">def</span> register_filter<span class="br0">&#40;</span>name=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">def</span> dec<span class="br0">&#40;</span>func<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> name:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; func.__name__ = name<br />
&nbsp; &nbsp; &nbsp; &nbsp; jinja_env.<span class="me1">filters</span><span class="br0">&#91;</span>func.__name__<span class="br0">&#93;</span> = func<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> func<br />
&nbsp; &nbsp; <span class="kw1">return</span> dec</div></div>
<h3>Tags? no, funciones</h3>
<p>Para emular un <a href="http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags" title="" class="external">tag de inclusión</a> de django hay que definir una función que retorne un render_to_string y agregarla a la lista<code>globals</code>:</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># blocks.py</span><br />
<span class="kw1">from</span> jinja_helper <span class="kw1">import</span> jinja_env, render_to_string<br />
<br />
<span class="kw1">def</span> menu<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; items = <span class="br0">&#40;</span><span class="st0">'about'</span>, <span class="st0">'contact'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> render_to_string<span class="br0">&#40;</span><span class="st0">'menu.html'</span>, <span class="kw2">dict</span><span class="br0">&#40;</span>items=items<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<br />
jinja_env.<span class="kw2">globals</span><span class="br0">&#91;</span><span class="st0">'menu'</span><span class="br0">&#93;</span> = menu</div></div>
<p>El template podría ser algo así:</p>
<div class="codecolorer-container html4strict " style="overflow:auto;white-space:nowrap;width:435px"><div class="html4strict codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc-1">&lt;!-- menu.html --&gt;</span><br />
<span class="sc2">&lt;<a href="http://december.com/html/4/element/ul.html"><span class="kw2">ul</span></a>&gt;</span><br />
{% for item in items %}<br />
&nbsp; &nbsp; <span class="sc2">&lt;<a href="http://december.com/html/4/element/li.html"><span class="kw2">li</span></a>&gt;</span>{{ item }}<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/li.html"><span class="kw2">li</span></a>&gt;</span><br />
{% endfor %}<br />
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/ul.html"><span class="kw2">ul</span></a>&gt;</span></div></div>
<div class="codecolorer-container html4strict " style="overflow:auto;white-space:nowrap;width:435px"><div class="html4strict codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sc-1">&lt;!-- index.html --&gt;</span><br />
{{ menu() }}</div></div>
<p>De nuevo, podríamos agregar un poco de azúcar a la sintáxis:</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># blocks.py</span><br />
<span class="kw1">from</span> jinja_helper <span class="kw1">import</span> register_block<br />
<br />
@register_block<span class="br0">&#40;</span><span class="st0">'menu.html'</span><span class="br0">&#41;</span><br />
<span class="kw1">def</span> menu<span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; items = <span class="br0">&#40;</span><span class="st0">'about'</span>, <span class="st0">'contact'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">dict</span><span class="br0">&#40;</span>items=items<span class="br0">&#41;</span></div></div>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># jinja_helper.py</span><br />
<span class="kw1">def</span> register_block<span class="br0">&#40;</span>template_path, name=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">def</span> dec<span class="br0">&#40;</span>func<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> func2<span class="br0">&#40;</span><span class="sy0">*</span>args, <span class="sy0">**</span>kwargs<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> render_to_string<span class="br0">&#40;</span>template_path, func<span class="br0">&#40;</span><span class="sy0">*</span>args, <span class="sy0">**</span>kwargs<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; func2.__name__ = name <span class="kw1">if</span> name <span class="kw1">else</span> func.__name__<br />
&nbsp; &nbsp; &nbsp; &nbsp; jinja_env.<span class="kw2">globals</span><span class="br0">&#91;</span>func2.__name__<span class="br0">&#93;</span> = func2<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> func2<br />
&nbsp; &nbsp; <span class="kw1">return</span> dec</div></div>
<h3>Descarga</h3>
<p>El ejemplo completo puede descargarse desde aquí: <a href='/uploads/2010/10/mysite-jinja2.tar.gz'>mysite-jinja2.tar</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2010/10/alternativa-al-sistema-de-templates-de-django-parte-i-jinja2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim scripting con Python</title>
		<link>http://blog.calcifer.com.ar/2010/02/vim-scripting-con-python/</link>
		<comments>http://blog.calcifer.com.ar/2010/02/vim-scripting-con-python/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 01:20:00 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=549</guid>
		<description><![CDATA[Vim permite agregar funcionalidades mediante varios lenguajes externos, entre ellos Perl, Python, Ruby y Tcl. Para poder hacer uso de esta característica es necesario haber compilado Vim con el soporte para el lenguaje necesario (con el flag-python, para soporte python). En debian existe un paquete llamado vim-nox (no X) que contiene una versión compilada con [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.vim.org/" title="Vim the editor" class="external">Vim</a> permite agregar funcionalidades mediante varios lenguajes externos, entre ellos Perl, Python, Ruby y Tcl. Para poder hacer uso de esta característica es necesario haber compilado Vim con el soporte para el lenguaje necesario (con el flag<code>-python</code>, para soporte python). En debian existe un paquete llamado <a href="http://packages.debian.org/stable/vim-nox" title="Debian Package: vim-nox" class="external">vim-nox</a> (no X) que contiene una versión compilada con soporte para los cuatro lenguajes mencionados:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">sudo apt-get install vim-nox</div></div>
<p>Para comprobar que efectivamente se encuentre habilitado el soporte para Python ejecutar Vim y en modo comando escribir:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:echo has(&quot;python&quot;)</div></div>
<p>Un 1 indica que Vim interpreta Python ;)</p>
<p>Es muy recomendable leer la ayuda en línea:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:help python</div></div>
<p>También se puede acceder vía web desde <a href="http://vimdoc.sourceforge.net/htmldoc/if_pyth.html" title="Vim documentation: if_pyth" class="external">http://vimdoc.sourceforge.net/htmldoc/if_pyth.html</a></p>
<h3>Ejecución de código Python</h3>
<p>La ejecución de una línea de código Python se realiza según la sintaxis:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:[range]py[thon] {stmt}</div></div>
<p>Ejemplo:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:python print &quot;hello world&quot;</div></div>
<p>Aquí el prompt mostrará el mensaje &#8220;hello world&#8221;.</p>
<p>En cambio para escribir código en varias líneas hay que usar la siguiente forma:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">[range]:py[thon] &lt;&lt; {endmarker}<br />
{script}<br />
{endmarker}</div></div>
<p>Ejemplo:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:python &lt;&lt; EOF<br />
def get_user():<br />
&nbsp; import os<br />
&nbsp; return os.getenv('USER')<br />
EOF</div></div>
<p>De esta manera la función queda guardada en la memoria de la sesión actual. Luego su uso podría ser el siguiente:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py user = get_user()</div></div>
<p>Tambien es posible cargar y/o ejecutar código desde un archivo externo. La sintaxis es:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:[range]pyf[ile] {file}</div></div>
<p>Ejemplo:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:pyfile myscript.py</div></div>
<p>Si<code>myscript.py</code>necesitara parámetros la forma de pasárselos es la siguiente:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py import sys<br />
:py sys.argv = ['foo', 'bar']<br />
:pyf myscript.py</div></div>
<h3>El módulo vim</h3>
<p>La comunicación entre Python y Vim se realiza a través del módulo vim, el cual hay que importar antes de usar:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:python import vim</div></div>
<p>Como indica la ayuda de Vim, el módulo implementa dos métodos (<code>vim.command(str)</code>y<code>vim.eval(str)</code>), tres constantes (<code>vim.buffers</code>,<code>vim.windows</code>y<code>vim.current</code>) y un objeto error (<code>vim.error</code>). Las tres constantes mencionadas no son realmente constantes sino variables que pueden ser reasignadas pero, como dice también la ayuda, esto sería absurdo ya que se perdería acceso a los objetos de Vim que referencian. Por otra parte cabe recordar que no existen constantes en Python. Como cita el libro &#8220;<a href="http://www.gulic.org/almacen/diveintopython-5.4-es/object_oriented_framework/class_attributes.html" title="Capítulo 5.8. - Presentación de los atributos de clase" class="external">Inmersión en Python</a>&#8220;:</p>
<blockquote><p>Todo puede cambiar si lo intenta con ahínco. Esto se ajusta a uno de los principios básicos de Python: los comportamientos inadecuados sólo deben desaconsejarse, no prohibirse.</p></blockquote>
<p><span id="more-549"></span><br />
A continuación transcribo un detalle de cada una de las constantes mencionadas:</p>
<dl>
<dt>vim.buffers</dt>
<dd>
Objeto de tipo secuencia que provee acceso al listado de buffers actuales. El objeto soporta las siguiente operaciones:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py b = vim.buffers[i] &nbsp; &nbsp; # Indexación (Read-Only)<br />
:py b in vim.buffers &nbsp; &nbsp; &nbsp; # Prueba de existencia<br />
:py n = len(vim.buffers) &nbsp; # Número de elementos<br />
:py for b in vim.buffers: &nbsp;# Acceso secuencial</div></div>
</dd>
<dt>vim.windows</dt>
<dd>
Objeto de tipo secuencia que provee acceso al listado de ventanas actuales. El objeto soporta las mismas operaciones que vim.buffers:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py w = vim.windows[i] &nbsp; &nbsp; # Indexación (RO)<br />
:py w in vim.windows &nbsp; &nbsp; &nbsp; # Prueba de existencia<br />
:py n = len(vim.windows) &nbsp; # Número de elementos<br />
:py for w in vim.windows: &nbsp;# Acceso secuencial</div></div>
</dd>
<dt>vim.current</dt>
<dd>
Objeto que provee acceso (vía atributos específicos) a distintos objetos actuales:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">vim.current.line &nbsp; &nbsp;# (RW) String<br />
vim.current.buffer &nbsp;# (RO) Buffer<br />
vim.current.window &nbsp;# (RO) Window<br />
vim.current.range &nbsp; # (RO) Range</div></div>
</dd>
</dl>
<h3>Ejemplos básicos de uso del módulo vim</h3>
<p>Usando<code>vim.current.line</code>:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py from string import upper<br />
:py vim.current.line = upper(vim.current.line)</div></div>
<p>Usando<code>vim.current.buffer</code>:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py b = vim.current.buffer &nbsp; &nbsp; &nbsp;# obtiene buffer actual<br />
:py name = b.name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # nombre de archivo del buffer actual<br />
:py num = len(b) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# total de líneas en el buffer<br />
:py line = b[n] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # obtiene la línea n+1<br />
:py lines = b[n:m] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# obtiene una lista de líneas<br />
:py b[n] = str &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# reemplaza la línea n+1<br />
:py b[n:m] = [str1, str2, str3] # reemplaza varias líneas a la vez<br />
:py b[0:0] = [&quot;hola mundo&quot;] &nbsp; &nbsp; # inserta una línea al comienzo<br />
:py b.append(&quot;fin&quot;) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # inserta una línea al final<br />
:py del b[n] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# borra la línea n+1<br />
:py del b[n:m] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# borra varias líneas a la vez<br />
:py b[:] = None &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # borra el buffer completo</div></div>
<p>Usando<code>vim.current.window</code>:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py cw = vim.current.window &nbsp; &nbsp; &nbsp;# obtiene la ventana actual<br />
:py cw.height = 30 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # setea el alto de la ventana<br />
:py cw.width = 80 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# setea el ancho<br />
:py pos = cw.cursor &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# posicion del cursor (row, col)</div></div>
<h3>Script para subrayado de títulos</h3>
<p>El siguiente script (<a href="http://blog.calcifer.com.ar/uploads/2010/02/heading.vim" title="">heading.vim</a>) lo escribí para no tener que, manualmente, subrayar títulos y delimitar bloques de texto. Especialmente quería que reconociera cuando se tratara de texto dentro de comentarios de código fuente y que respetara los caracteres especiales al comienzo (y final) de los mismos.</p>
<p>El script tiene una función que decora la línea actual colocando él o los caracteres decoradores tanto arriba como debajo de la misma (comportamiento por defecto). El largo (también por defecto) es el largo de la línea, pero se puede fijar un límite (ejemplo 80 columnas) y pedirle que ocupe todo el espacio disponible. Esta opción funciona bien sólamente cuando el indentado es con espacios. La opción uppercase funciona como se espera.</p>
<p>El código es el siguiente:</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px;height:500px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br /></div></td><td><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">&quot; ============================================================================<br />
&quot; File: &nbsp; &nbsp; &nbsp; &nbsp;heading.vim<br />
&quot; Version: &nbsp; &nbsp; 0.1<br />
&quot; Description: vim global plugin that provides a way to create headings.<br />
&quot; Maintainer: &nbsp;Leonardo Vidarte &lt;lvidarte at gmail dot com&gt;<br />
&quot; Last Change: 21 February, 2010<br />
&quot; ============================================================================<br />
if has('python')<br />
python &lt;&lt; EOF<br />
def heading(decorator='=', top=True, bottom=True, limit=0, uppercase=False):<br />
<br />
&nbsp; &nbsp; import vim<br />
&nbsp; &nbsp; from string import upper, rstrip, lstrip<br />
<br />
&nbsp; &nbsp; if not top and not bottom:<br />
&nbsp; &nbsp; &nbsp; &nbsp; return None # nothing to do<br />
<br />
&nbsp; &nbsp; (row, col) = vim.current.window.cursor<br />
&nbsp; &nbsp; line = vim.current.buffer[row-1].rstrip()<br />
&nbsp; &nbsp; line_length = len(line.decode('utf8'))<br />
&nbsp; &nbsp; title = line.lstrip()<br />
&nbsp; &nbsp; word_length = len(title.decode('utf8'))<br />
&nbsp; &nbsp; whitespace = line[0:line_length - word_length]<br />
<br />
&nbsp; &nbsp; if limit &gt; 0:<br />
&nbsp; &nbsp; &nbsp; &nbsp; decorator *= limit<br />
&nbsp; &nbsp; &nbsp; &nbsp; total_length = limit<br />
&nbsp; &nbsp; else:<br />
&nbsp; &nbsp; &nbsp; &nbsp; decorator *= word_length<br />
&nbsp; &nbsp; &nbsp; &nbsp; total_length = line_length<br />
<br />
&nbsp; &nbsp; if title[0:3] in ('// ', '/* ', '-- '):<br />
&nbsp; &nbsp; &nbsp; &nbsp; decoline = whitespace + title[0:3] + decorator<br />
&nbsp; &nbsp; elif title[0:2] in ('//', '/*', '--', '# ', '* ', '&quot; '):<br />
&nbsp; &nbsp; &nbsp; &nbsp; decoline = whitespace + title[0:2] + decorator<br />
&nbsp; &nbsp; elif title[0:1] in ('#', '*', '&quot;'):<br />
&nbsp; &nbsp; &nbsp; &nbsp; decoline = whitespace + title[0:1] + decorator<br />
&nbsp; &nbsp; else:<br />
&nbsp; &nbsp; &nbsp; &nbsp; decoline = whitespace + decorator<br />
<br />
&nbsp; &nbsp; # Special case: comments like C /* hello world */<br />
&nbsp; &nbsp; cend = ''<br />
&nbsp; &nbsp; if title[0:2] == '/*':<br />
&nbsp; &nbsp; &nbsp; &nbsp; if title[-3:] == ' */':<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cend = ' */'<br />
&nbsp; &nbsp; &nbsp; &nbsp; elif title[-2:] == '*/':<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cend = '*/'<br />
<br />
&nbsp; &nbsp; decoline = decoline[0:total_length - len(cend)] + cend<br />
&nbsp; &nbsp; final_heading = []<br />
<br />
&nbsp; &nbsp; if top:<br />
&nbsp; &nbsp; &nbsp; &nbsp; final_heading.append(decoline)<br />
<br />
&nbsp; &nbsp; if uppercase:<br />
&nbsp; &nbsp; &nbsp; &nbsp; final_heading.append(line.upper())<br />
&nbsp; &nbsp; else:<br />
&nbsp; &nbsp; &nbsp; &nbsp; final_heading.append(line)<br />
<br />
&nbsp; &nbsp; if bottom:<br />
&nbsp; &nbsp; &nbsp; &nbsp; final_heading.append(decoline)<br />
<br />
&nbsp; &nbsp; del vim.current.buffer[row-1]<br />
&nbsp; &nbsp; vim.current.buffer[row-1:0] = final_heading<br />
<br />
&nbsp; &nbsp; # Set final cursor position<br />
&nbsp; &nbsp; if top and bottom:<br />
&nbsp; &nbsp; &nbsp; &nbsp; vim.current.window.cursor = (row + 2, 0)<br />
&nbsp; &nbsp; else:<br />
&nbsp; &nbsp; &nbsp; &nbsp; vim.current.window.cursor = (row + 1, 0)<br />
<br />
H = heading # shortcut<br />
EOF<br />
<br />
&quot; ============================================================================<br />
&quot; Vim maps (see :help leader)<br />
&quot; ============================================================================<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;hh :python heading()&lt;CR&gt;<br />
<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h1 :python heading('#', uppercase=True)&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h2 :python heading('*', uppercase=True)&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h3 :python heading('=')&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h4 :python heading('-')&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;h5 :python heading('~', top=False)&lt;CR&gt;<br />
<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;HH :python heading(limit=78)&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;Hb :python heading(limit=78, top=False)&lt;CR&gt;<br />
nnoremap &lt;silent&gt; &lt;Leader&gt;Ht :python heading(limit=78, bottom=False)&lt;CR&gt;<br />
<br />
endif</div></td></tr></tbody></table></div>
<p>Para usarlo hay que colocar el archivo <a href="http://blog.calcifer.com.ar/uploads/2010/02/heading.vim" title="">heading.vim</a> en el directorio<code>~/.vim/plugins</code>.</p>
<h4>Ejemplos de uso</h4>
<p>1. Texto normal</p>
<pre>Título</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H()</div></div>
<pre>======
Título
======</pre>
<p>2. Comentario en línea (Python, Bash, Perl, PHP, Ruby)</p>
<pre>    # Comment</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H()</div></div>
<pre>    # =======
    # Comment
    # =======</pre>
<p>3. Comentario en bloque, estilo javadoc (C, C++, Java, Javascript, CSS, PHP, SQL)</p>
<pre>    /**
     * Comment
     */</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H('#', uppercase=True)</div></div>
<pre>    /**
     * #######
     * COMMENT
     * #######
     */</pre>
<p>4. Comentario en línea (C, C++, Java, Javascript, CSS, PHP, SQL)</p>
<pre>/* Comment */</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H('~+')</div></div>
<pre>/* ~+~+~+~ */
/* Comment */
/* ~+~+~+~ */</pre>
<p>5. Comentario en línea (C, Java, Javascript, PHP)</p>
<pre>// Comment</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H(limit=40)</div></div>
<pre>// =====================================
// Comment
// =====================================</pre>
<p>6. Comentario en línea (Vim script)</p>
<pre>" Comment</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H(top=None)</div></div>
<pre>" Comment
" ======</pre>
<p>7. Comentario en línea (Lua, SQL)</p>
<pre>-- Comment</pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">:py H()</div></div>
<pre>-- =======
-- Comment
-- =======</pre>
<h4>Atajos de teclado</h4>
<p>El script también define algunos atajos en modo normal para Vim. Para los mismos se usa la tecla especial<code>&lt;Leader&gt;</code>que es definida por la variable<code>mapleader</code>y que generealmente es el caracter<code>\</code>.</p>
<table>
<tr>
<th>Atajo</th>
<th>Comando</th>
</tr>
<tr>
<td>\hh</td>
<td>:python heading()</td>
</tr>
<tr>
<td>\h1</td>
<td>:python heading(&#8216;#&#8217;, uppercase=True)</td>
</tr>
<tr>
<td>\h2</td>
<td>:python heading(&#8216;*&#8217;, uppercase=True)</td>
</tr>
<tr>
<td>\h3</td>
<td>:python heading(&#8216;=&#8217;)</td>
</tr>
<tr>
<td>\h4</td>
<td>:python heading(&#8216;-&#8217;)</td>
</tr>
<tr>
<td>\h5</td>
<td>:python heading(&#8216;~&#8217;, top=False)</td>
</tr>
<tr>
<td>\HH</td>
<td>:python heading(limit=78)</td>
</tr>
<tr>
<td>\Hb</td>
<td>:python heading(limit=78, top=False)</td>
</tr>
<tr>
<td>\Ht</td>
<td>:python heading(limit=78, bottom=False)</td>
</tr>
</table>
<h3>Lectura adicional</h3>
<ul>
<li><a href="http://www.builderau.com.au/program/python/soa/Extending-Vim-with-Python/0,2000064084,339283181,00.htm">Extending Vim with Python</a></li>
<li><a href="http://www.tummy.com/Community/Presentations/vimpython-20070225/vim.html">Python and vim: Two great tastes that go great together</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2010/02/vim-scripting-con-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Accediendo a MySQL con Python y MySQLdb</title>
		<link>http://blog.calcifer.com.ar/2009/03/accediendo-a-mysql-con-python-y-mysqldb/</link>
		<comments>http://blog.calcifer.com.ar/2009/03/accediendo-a-mysql-con-python-y-mysqldb/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 15:00:27 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=330</guid>
		<description><![CDATA[MySQLdb es un módulo que implementa la API estándar (PEP249) para manejo de bases de datos, en este caso MySQL. MySQLdb es en realidad un wrapper del módulo _mysql que provee Python, el cual implementa la mayoría de las funciones definidas en la API C de MySQL. La idea de definir una API estándar es [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://sourceforge.net/projects/mysql-python" class="external">MySQLdb</a> es un módulo que implementa la <a href="http://www.python.org/dev/peps/pep-0249/">API estándar (PEP249)</a> para manejo de bases de datos, en este caso <a href="http://www.mysql.com" class="external">MySQL</a>. MySQLdb es en realidad un wrapper del módulo _mysql que provee Python, el cual implementa la mayoría de las funciones definidas en la <a href="http://mysql-python.sourceforge.net/MySQLdb.html#mysql-c-api-function-mapping">API C de MySQL</a>. La idea de definir una API estándar es que uno debería poder cambiar a otra base de datos sin modificar demasiado el código.</p>
<blockquote title="python.org"><p>This API has been defined to encourage similarity between the Python modules that are used to access databases.</p></blockquote>
<h3>Instalación MySQLdb</h3>
<p>El paquete que nos provee el módulo se llama python-mysqldb. Podemos comprobar que lo tenemos instalado mediante</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">dpkg</span> <span class="re5">--get-selections</span> <span class="sy0">|</span> <span class="kw2">grep</span> python-mysqldb</div></div>
<p>Si no existe lo instalamos</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> python-mysqldb</div></div>
<p>Para comprobar que efectivamente tenemos el módulo disponible y funcionando llamamos al <a href="http://docs.python.org/tutorial/interpreter.html" class="external">intérprete de Python</a> y escribimos</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px"><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy0">&gt;&gt;&gt;</span> <span class="kw1">import</span> MySQLdb</div></div>
<p>Un silencioso retorno de carro indica que podemos <a href="http://xkcd.com/353/" class="external">el módulo ha sido cargado</a>. Salimos del intérprete con<code>C-d</code>.</p>
<h3>Creación de una DB de pruebas</h3>
<p>Para nuestro ejemplo crearemos una base de datos con una única tabla. Entramos a la <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql.html" class="external">consola de MySQL</a> y escribimos</p>
<div class="codecolorer-container mysql " style="overflow:auto;white-space:nowrap;width:435px"><div class="mysql codecolorer" style="font-family:Monaco,Lucida Console,monospace">mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=CREATE&amp;lr=lang_en"><span class="kw1">CREATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=DATABASE&amp;lr=lang_en"><span class="kw2">database</span></a> test<span class="sy2">;</span><br />
Query OK<span class="sy2">,</span> <span class="nu0">1</span> row affected <span class="br0">&#40;</span><span class="nu0">0.01</span> sec<span class="br0">&#41;</span><br />
<br />
mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=USE&amp;lr=lang_en"><span class="kw1">USE</span></a> test<span class="sy2">;</span><br />
<a href="http://search.mysql.com/search?site=refman-51&amp;q=DATABASE&amp;lr=lang_en"><span class="kw2">Database</span></a> changed<br />
mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=CREATE&amp;lr=lang_en"><span class="kw1">CREATE</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=TABLE&amp;lr=lang_en"><span class="kw1">TABLE</span></a> users <span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> id <a href="http://search.mysql.com/search?site=refman-51&amp;q=INT&amp;lr=lang_en"><span class="kw4">INT</span></a> <a href="http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html"><span class="kw10">NOT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=NULL&amp;lr=lang_en"><span class="kw3">NULL</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=AUTO_INCREMENT&amp;lr=lang_en"><span class="kw6">AUTO_INCREMENT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=PRIMARY%20KEY&amp;lr=lang_en"><span class="kw1">PRIMARY KEY</span></a><span class="sy2">,</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> name <a href="http://search.mysql.com/search?site=refman-51&amp;q=VARCHAR&amp;lr=lang_en"><span class="kw4">VARCHAR</span></a><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span><span class="sy2">,</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> lastname <a href="http://search.mysql.com/search?site=refman-51&amp;q=VARCHAR&amp;lr=lang_en"><span class="kw4">VARCHAR</span></a><span class="br0">&#40;</span><span class="nu0">100</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> <span class="br0">&#41;</span><span class="sy2">;</span><br />
Query OK<span class="sy2">,</span> <span class="nu0">0</span> rows affected <span class="br0">&#40;</span><span class="nu0">0.01</span> sec<span class="br0">&#41;</span><br />
<br />
mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INSERT&amp;lr=lang_en"><span class="kw2">INSERT</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=INTO&amp;lr=lang_en"><span class="kw1">INTO</span></a> users <span class="br0">&#40;</span>name<span class="sy2">,</span> lastname<span class="br0">&#41;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=VALUES&amp;lr=lang_en"><span class="kw1">VALUES</span></a><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> <span class="br0">&#40;</span><span class="st0">'Juan'</span><span class="sy2">,</span> <span class="st0">'Perez'</span><span class="br0">&#41;</span><span class="sy2">,</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> <span class="br0">&#40;</span><span class="st0">'Ana Maria'</span><span class="sy2">,</span> <span class="st0">'Lopez'</span><span class="br0">&#41;</span><span class="sy2">,</span><br />
&nbsp; &nbsp; <span class="sy1">-&gt;</span> <span class="br0">&#40;</span><span class="st0">'Carlos L.'</span><span class="sy2">,</span> <span class="st0">'Gutierrez'</span><span class="br0">&#41;</span><span class="sy2">;</span><br />
Query OK<span class="sy2">,</span> <span class="nu0">3</span> rows affected <span class="br0">&#40;</span><span class="nu0">0.00</span> sec<span class="br0">&#41;</span><br />
Records: <span class="nu0">3</span> &nbsp;Duplicates: <span class="nu0">0</span> &nbsp;<a href="http://search.mysql.com/search?site=refman-51&amp;q=WARNINGS&amp;lr=lang_en"><span class="kw1">Warnings</span></a>: <span class="nu0">0</span></div></div>
<p>Nuestra tabla users quedó entonces</p>
<div class="codecolorer-container mysql " style="overflow:auto;white-space:nowrap;width:435px"><div class="mysql codecolorer" style="font-family:Monaco,Lucida Console,monospace">mysql<span class="sy1">&gt;</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=SELECT&amp;lr=lang_en"><span class="kw1">SELECT</span></a> <span class="sy1">*</span> <a href="http://search.mysql.com/search?site=refman-51&amp;q=FROM&amp;lr=lang_en"><span class="kw1">FROM</span></a> users<span class="sy2">;</span><br />
<span class="sy1">+----+-----------+-----------+</span><br />
<span class="sy1">|</span> id <span class="sy1">|</span> name &nbsp; &nbsp; &nbsp;<span class="sy1">|</span> lastname &nbsp;<span class="sy1">|</span><br />
<span class="sy1">+----+-----------+-----------+</span><br />
<span class="sy1">|</span> &nbsp;<span class="nu0">1</span> <span class="sy1">|</span> Juan &nbsp; &nbsp; &nbsp;<span class="sy1">|</span> Perez &nbsp; &nbsp; <span class="sy1">|</span> <br />
<span class="sy1">|</span> &nbsp;<span class="nu0">2</span> <span class="sy1">|</span> Ana Maria <span class="sy1">|</span> Lopez &nbsp; &nbsp; <span class="sy1">|</span> <br />
<span class="sy1">|</span> &nbsp;<span class="nu0">3</span> <span class="sy1">|</span> Carlos L. <span class="sy1">|</span> Gutierrez <span class="sy1">|</span> <br />
<span class="sy1">+----+-----------+-----------+</span><br />
<span class="nu0">3</span> rows <a href="http://search.mysql.com/search?site=refman-51&amp;q=IN&amp;lr=lang_en"><span class="kw2">in</span></a> <a href="http://search.mysql.com/search?site=refman-51&amp;q=SET&amp;lr=lang_en"><span class="kw1">set</span></a> <span class="br0">&#40;</span><span class="nu0">0.00</span> sec<span class="br0">&#41;</span></div></div>
<h3>Creación del script mysqldb.py</h3>
<p>Creamos el siguiente script que se conectará a la base de datos test y traerá todos los datos de los usuarios cargados en la tabla users. En el script es necesario reemplazar &lt;user&gt; y &lt;pass&gt; por los datos requeridos para acceder a tu DB.</p>
<div class="codecolorer-container python " style="overflow:auto;white-space:nowrap;width:435px;height:300px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /></div></td><td><div class="python codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1">#!/usr/bin/python</span><br />
<span class="kw1">import</span> MySQLdb<br />
<br />
<span class="co1"># Conexion a la base de datos</span><br />
conn = MySQLdb.<span class="me1">connect</span> <span class="br0">&#40;</span>host=<span class="st0">&quot;localhost&quot;</span>,<br />
&nbsp; &nbsp; <span class="kw3">user</span>=<span class="st0">&quot;&lt;user&gt;&quot;</span>, passwd=<span class="st0">&quot;&lt;pass&gt;&quot;</span>, db=<span class="st0">&quot;test&quot;</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># Creacion cursor</span><br />
cursor = conn.<span class="me1">cursor</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># Ejecucion query</span><br />
cursor.<span class="me1">execute</span><span class="br0">&#40;</span><span class="st0">&quot;SELECT * FROM users&quot;</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># Manejo de datos devueltos por la consulta</span><br />
<span class="kw1">while</span> <span class="kw2">True</span>:<br />
&nbsp; &nbsp; row = cursor.<span class="me1">fetchone</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> row <span class="kw1">is</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><br />
&nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;id: %s<span class="es0">\t</span>name: %s %s&quot;</span> <span class="sy0">%</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>row<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>, row<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>, row<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># Finalizado cursor y objeto conexion</span><br />
cursor.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
conn.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></td></tr></tbody></table></div>
<p>La salida debería ser</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">id: 1 &nbsp; name: Juan Perez<br />
id: 2 &nbsp; name: Ana Maria Lopez<br />
id: 3 &nbsp; name: Carlos L. Gutierrez</div></div>
<h4>Links recomendados para ampliar conocimientos</h4>
<ul>
<li><a href="http://mysql-python.sourceforge.net/MySQLdb.html" class="external">MySQLdb User&#8217;s Guide</a></li>
<li><a href="http://www.kitebird.com/articles/pydbapi.html" class="external">Writing MySQL Scripts with Python DB-API</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/03/accediendo-a-mysql-con-python-y-mysqldb/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>El Zen de Python</title>
		<link>http://blog.calcifer.com.ar/2007/07/el-zen-de-python/</link>
		<comments>http://blog.calcifer.com.ar/2007/07/el-zen-de-python/#comments</comments>
		<pubDate>Tue, 03 Jul 2007 12:36:43 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2007/07/03/el-zen-de-python/</guid>
		<description><![CDATA[Vía Mundo Geek
Hace mucho tiempo el entusiasta de Python Tim Peters plasmó de forma concisa los principios de diseño por los que guiarse al escribir en Python según el BDFL (NT: Benevolent Dictator for Life o Dictador Benévolo de por Vida, en este caso Guido van Rossum, el creador de Python) en 20 aforismos, de [...]]]></description>
			<content:encoded><![CDATA[<div class="from">Vía <a href="http://mundogeek.net/archivos/2007/07/02/el-zen-de-python/" class="linkexternal">Mundo Geek</a></div>
<p>Hace mucho tiempo el entusiasta de Python Tim Peters plasmó de forma concisa los principios de diseño por los que guiarse al escribir en Python según el BDFL (NT: Benevolent Dictator for Life o Dictador Benévolo de por Vida, en este caso Guido van Rossum, el creador de Python) en 20 aforismos, de los cuales sólo <a href="http://www.python.org/dev/peps/pep-0020/" class="linkexternal">19 han pasado a forma escrita</a>.</p>
<ol>
<li>Hermoso es mejor que feo.</li>
<li>Explícito es mejor que implícito.</li>
<li>Simple es mejor que complejo.</li>
<li>Complejo es mejor que complicado.</li>
<li>Plano es mejor que anidado.</li>
<li>Disperso es mejor que denso.</li>
<li>La legibilidad cuenta.</li>
<li>Los casos especiales no son suficientemente especiales como para romper las reglas.</li>
<li>Aunque lo pragmático gana a la pureza.</li>
<li>Los errores nunca deberían dejarse pasar silenciosamente.</li>
<li>A menos que se silencien explícitamente.</li>
<li>Cuando te enfrentes a la ambigüedad, rechaza la tentación de adivinar.</li>
<li>Debería haber una &#8212; y preferiblemente sólo una &#8212; manera obvia de hacerlo.</li>
<li>Aunque puede que no sea obvia a primera vista a menos que seas holandés. (NT: Guido van Rossum es holandés)</li>
<li>Ahora es mejor que nunca.</li>
<li>Aunque muchas veces nunca es mejor que *ahora mismo*.</li>
<li>Si la implementación es difícil de explicar, es una mala idea.</li>
<li>Si la implementación es sencilla de explicar, puede que sea una buena idea.</li>
<li>Los espacios de nombres son una gran idea &#8212; ¡tengamos más de esas!</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2007/07/el-zen-de-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

