{"id":7597,"date":"2014-03-04T17:25:23","date_gmt":"2014-03-04T16:25:23","guid":{"rendered":"http:\/\/elclubdelautodidacta.es\/wp\/?p=7597"},"modified":"2014-03-05T12:18:25","modified_gmt":"2014-03-05T11:18:25","slug":"python-y-finalmente-finally","status":"publish","type":"post","link":"http:\/\/elclubdelautodidacta.es\/wp\/2014\/03\/python-y-finalmente-finally\/","title":{"rendered":"Python &#8211; Y, finalmente, finally"},"content":{"rendered":"<p><a href=\"http:\/\/elclubdelautodidacta.es\/wp\/wp-content\/uploads\/2011\/12\/ECDA-python.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/elclubdelautodidacta.es\/wp\/wp-content\/uploads\/2011\/12\/ECDA-python.png\" alt=\"\" title=\"ECDA-python\" width=\"181\" height=\"242\" class=\"alignleft size-full wp-image-2584\" \/><\/a><em><strong>Objetivo<\/strong>: presentar la cl\u00e1usula finally en el manejo de excepciones en Python.<br \/>\n<\/em><br \/>\nImaginemos, por un momento, que soy un perverso programador que, bajo el aspecto de un aparente d\u00f3cil y simple programa esconde en \u00e9l una intenci\u00f3n oculta. Supongamos que, aprovech\u00e1ndome del deseo de todo el mundo de disponer de una aplicaci\u00f3n que permita calcular la divisi\u00f3n de dos n\u00fameros enteros, intento colar un sutil mensaje subliminal al ejecutarla:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">dividendo = int(input(&#039;Introduce el dividendo: &#039;))\ndivisor = int(input(&#039;Introduce el divisor: &#039;))\nprint(&#039;El cociente de la divisi\u00f3n de ambos n\u00fameros es&#039;, dividendo\/\/divisor)\nprint(&quot;Viva el Betis manque pierda&quot;)<\/code><\/pre><\/p>\n<p><pre><code class=\"preserve-code-formatting\">&gt;&gt;&gt; \nIntroduce el dividendo: 10\nIntroduce el divisor: 2\nEl cociente de la divisi\u00f3n de ambos n\u00fameros es 5\nViva el Betis manque pierda <\/code><\/pre><\/p>\n<p>Impresionante, pero no tanto&#8230;<\/p>\n<p>Si por un casual introducimos como divisor un cero, la divisi\u00f3n no podr\u00e1 realizarse y el programa abortar\u00e1, muriendo con \u00e9l tambi\u00e9n nuestras oscuras pretensiones:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">&gt;&gt;&gt; \nIntroduce el dividendo: 10\nIntroduce el divisor: 0\nTraceback (most recent call last):\n&nbsp;&nbsp;File &quot;C:\/Python33\/pruebas.py&quot;, line 3, in &lt;module&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;print(&#039;El cociente de la divisi\u00f3n de ambos n\u00fameros es&#039;, dividendo\/\/divisor)\nZeroDivisionError: integer division or modulo by zero<\/code><\/pre><\/p>\n<p>En los art\u00edculos anteriores presentamos la <a href=\"http:\/\/elclubdelautodidacta.es\/wp\/2014\/01\/python-un-lenguaje-excepcional\/\" title=\"Captura de excepciones en Python\">captura de excepciones<\/a> en Python, de modo que tenemos recursos para solucionar esto:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">try:\n&nbsp;&nbsp;&nbsp;&nbsp;dividendo = int(input(&#039;Introduce el dividendo: &#039;))\n&nbsp;&nbsp;&nbsp;&nbsp;divisor = int(input(&#039;Introduce el divisor: &#039;))\n&nbsp;&nbsp;&nbsp;&nbsp;print(&#039;El cociente de la divisi\u00f3n de ambos n\u00fameros es&#039;, dividendo\/\/divisor)\nexcept:\n&nbsp;&nbsp;&nbsp;&nbsp;print(&quot;No ha podido realizarse la operaci\u00f3n&quot;)\n&nbsp;&nbsp;&nbsp;&nbsp;\nprint(&quot;Viva el Betis manque pierda&quot;)<\/code><\/pre><\/p>\n<p><pre><code class=\"preserve-code-formatting\">&gt;&gt;&gt; \nIntroduce el dividendo: 10\nIntroduce el divisor: 0\nNo ha podido realizarse la operaci\u00f3n\nViva el Betis manque pierda<\/code><\/pre><\/p>\n<p>Desde luego, esto funciona. La operaci\u00f3n de divisi\u00f3n ha sido protegida con un <em>try\/except<\/em> que, tal como est\u00e1 planteado, intercepta cualquier excepci\u00f3n que pudiera ocurrir. He introducido en el bloque <em>try <\/em>las dos sentencias <em>input<\/em>, no s\u00f3lo la divisi\u00f3n, pues tambi\u00e9n ocurrir\u00eda una excepci\u00f3n si se facilitase un valor no num\u00e9rico cuando <em>int()<\/em> intentara la conversi\u00f3n a entero.<\/p>\n<p>El c\u00f3digo no fallar\u00e1 ante una eventual divisi\u00f3n por cero (<em>ZeroDivisionError<\/em>), la introducci\u00f3n de letras en vez de n\u00fameros (<em>ValueError<\/em>), o una interrupci\u00f3n con <em>Ctrl-C<\/em> (<em>KeyboardInterrupt<\/em>).<\/p>\n<p>Pero no me convence. Quiero emplear mi propio manejador ante una divisi\u00f3n por cero o la introducci\u00f3n de letras, pero quiero respetar el gestor por omisi\u00f3n que trae Python (el mensaje de error cl\u00e1sico tras abortar el programa) para poder finalizar la ejecuci\u00f3n con <em>Ctrl-C<\/em> si as\u00ed lo deseo.<\/p>\n<p>Hemos aprendido a <a href=\"http:\/\/elclubdelautodidacta.es\/wp\/2014\/01\/python-captura-selectiva-de-excepciones\/\" title=\"Captura selectiva de excepciones en Python\">interceptar selectivamente las excepciones<\/a> tambi\u00e9n:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">try:\n&nbsp;&nbsp;&nbsp;&nbsp;dividendo = int(input(&#039;Introduce el dividendo: &#039;))\n&nbsp;&nbsp;&nbsp;&nbsp;divisor = int(input(&#039;Introduce el divisor: &#039;))\n&nbsp;&nbsp;&nbsp;&nbsp;print(&#039;El cociente de la divisi\u00f3n de ambos n\u00fameros es&#039;, dividendo\/\/divisor)\nexcept (ZeroDivisionError, ValueError):\n&nbsp;&nbsp;&nbsp;&nbsp;print(&quot;No ha podido realizarse la operaci\u00f3n&quot;)\n&nbsp;&nbsp;&nbsp;&nbsp;\nprint(&quot;Viva el Betis manque pierda&quot;)<\/code><\/pre><\/p>\n<p>Ahora, si dividimos entre cero, salvamos el error y tambi\u00e9n nuestro mensaje subliminal:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">&gt;&gt;&gt; \nIntroduce el dividendo: 10\nIntroduce el divisor: 0\nNo ha podido realizarse la operaci\u00f3n\nViva el Betis manque pierda<\/code><\/pre><\/p>\n<p>Lo mismo si introducimos valores no num\u00e9ricos:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">&gt;&gt;&gt; \nIntroduce el dividendo: GOL!!!\nNo ha podido realizarse la operaci\u00f3n\nViva el Betis manque pierda<\/code><\/pre><\/p>\n<p>Pero nuestro gozo en un pozo si abortamos con <em>Ctrl-C<\/em>:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">&gt;&gt;&gt; \nIntroduce el dividendo: \nTraceback (most recent call last):\n&nbsp;&nbsp;File &quot;C:\/Python33\/pruebas.py&quot;, line 2, in &lt;module&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;dividendo = int(input(&#039;Introduce el dividendo: &#039;))\nKeyboardInterrupt<\/code><\/pre><\/p>\n<p>Se rompe la ejecuci\u00f3n del programa y, con ello, el Betis pierde.<\/p>\n<p>Para seguir insufl\u00e1ndole \u00e1nimos, Python dispone de la cla\u00fasula <strong>finally <\/strong>en el bloque <strong>try<\/strong>. El c\u00f3digo que se incluya en ella, ap\u00fantate esto bien, <strong>se ejecutar\u00e1 siempre, suceda o no suceda una excepci\u00f3n<\/strong>.<\/p>\n<p>En su versi\u00f3n m\u00e1s simple, <em>finally <\/em>no necesita que haya ning\u00fan <em>except<\/em>:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">try:\n&nbsp;&nbsp;&nbsp;&nbsp;dividendo = int(input(&#039;Introduce el dividendo: &#039;))\n&nbsp;&nbsp;&nbsp;&nbsp;divisor = int(input(&#039;Introduce el divisor: &#039;))\n&nbsp;&nbsp;&nbsp;&nbsp;print(&#039;El cociente de la divisi\u00f3n de ambos n\u00fameros es&#039;, dividendo\/\/divisor)\nfinally:\n&nbsp;&nbsp;&nbsp;&nbsp;print(&quot;Viva el Betis manque pierda&quot;)<\/code><\/pre><\/p>\n<p>Ahora, <strong>pase lo que pase<\/strong> dentro del <em>try<\/em>, la instrucci\u00f3n del <em>finally <\/em>se ejecutar\u00e1 siempre. Tanto si sucede algo bueno:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">&gt;&gt;&gt; \nIntroduce el dividendo: 10\nIntroduce el divisor: 2\nEl cociente de la divisi\u00f3n de ambos n\u00fameros es 5\nViva el Betis manque pierda<\/code><\/pre><\/p>\n<p>Como si no:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">&gt;&gt;&gt; \nIntroduce el dividendo: 10\nIntroduce el divisor: 0\nViva el Betis manque pierda\nTraceback (most recent call last):\n&nbsp;&nbsp;File &quot;C:\/Python33\/pruebas.py&quot;, line 4, in &lt;module&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;print(&#039;El cociente de la divisi\u00f3n de ambos n\u00fameros es&#039;, dividendo\/\/divisor)\nZeroDivisionError: integer division or modulo by zero<\/code><\/pre><\/p>\n<p>Se ejecuta el <em>print <\/em>del <em>finally <\/em>y, a continuaci\u00f3n, el manejador por omisi\u00f3n se ocupa del tratamiento de la excepci\u00f3n, abortando el programa e informando por qu\u00e9.<\/p>\n<p>Podemos combinar <em>finally <\/em>con <em>except <\/em>tambi\u00e9n:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">try:\n&nbsp;&nbsp;&nbsp;&nbsp;dividendo = int(input(&#039;Introduce el dividendo: &#039;))\n&nbsp;&nbsp;&nbsp;&nbsp;divisor = int(input(&#039;Introduce el divisor: &#039;))\n&nbsp;&nbsp;&nbsp;&nbsp;print(&#039;El cociente de la divisi\u00f3n de ambos n\u00fameros es&#039;, dividendo\/\/divisor)\nexcept (ZeroDivisionError, ValueError):\n&nbsp;&nbsp;&nbsp;&nbsp;print(&quot;No ha podido realizarse la operaci\u00f3n&quot;)\nfinally:\n&nbsp;&nbsp;&nbsp;&nbsp;print(&quot;Viva el Betis manque pierda&quot;)<\/code><\/pre><\/p>\n<p>En este caso utilizamos nuestro propio gestor ante una divisi\u00f3n por cero o la introducci\u00f3n de valores no num\u00e9ricos, pero mantenemos el que trae por defecto Python para cualquier otra excepci\u00f3n, lo que nos permite abortar el programa con <em>Ctrl- C<\/em>. El c\u00f3digo dentro de la cla\u00fasula <em>finally <\/em>se ejecuta siempre, suceda o no suceda una excepci\u00f3n:<\/p>\n<p><pre><code class=\"preserve-code-formatting\">&gt;&gt;&gt; \nIntroduce el dividendo: 10\nIntroduce el divisor: 4\nEl cociente de la divisi\u00f3n de ambos n\u00fameros es 2\nViva el Betis manque pierda\n&gt;&gt;&gt; ================================ RESTART ================================\n&gt;&gt;&gt; \nIntroduce el dividendo: \nViva el Betis manque pierda\nTraceback (most recent call last):\n&nbsp;&nbsp;File &quot;C:\/Python33\/pruebas.py&quot;, line 2, in &lt;module&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;dividendo = int(input(&#039;Introduce el dividendo: &#039;))\nKeyboardInterrupt<\/code><\/pre><\/p>\n<p>El uso t\u00edpico de la cla\u00fasula <em>finally <\/em>es la realizaci\u00f3n de <strong>tareas de limpieza<\/strong> para que no queden flecos en caso de que se produzca una excepci\u00f3n. Piensa, por ejemplo, en el gesto de cerrar un fichero una vez ha sido abierto para asegurarnos de que, suceda lo que suceda mientras estemos procesando el fichero, siempre quedar\u00e1 perfectamente cerrado.<\/p>\n<p>Dedicaremos el pr\u00f3ximo art\u00edculo, a modo de resumen, a esquematizar lo que hemos tratado hasta ahora en estos cuatro art\u00edculos dedicados a la gesti\u00f3n de excepciones en Python.<\/p>\n<p><em>Nota: no soy futbolero, ni tengo preferencia por ning\u00fan equipo sobre otro, pero s\u00ed que admito un cari\u00f1o y especial admiraci\u00f3n por la afici\u00f3n del Betis, tan incondicional, fiel y estoica.<\/em><\/p>\n<p><strong><span style=\"color: #808080;\">Javier Montero Gabarr\u00f3<\/span><\/strong><\/p>\n<hr \/>\n<blockquote data-secret=\"gqYObQXv1T\" class=\"wp-embedded-content\"><p><a href=\"http:\/\/elclubdelautodidacta.es\/wp\/2014\/03\/python-y-finalmente-finally\/\">Python &#8211; Y, finalmente, finally<\/a><\/p><\/blockquote>\n<p><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"display:none;\" src=\"http:\/\/elclubdelautodidacta.es\/wp\/2014\/03\/python-y-finalmente-finally\/embed\/#?secret=gqYObQXv1T\" data-secret=\"gqYObQXv1T\" width=\"600\" height=\"338\" title=\"Entrada de WordPress incrustada\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe><\/p>\n<hr \/>\n<p>El texto de este art\u00edculo se encuentra sometido a una licencia <em>Creative Commons<\/em> del tipo <strong>CC-BY-NC-ND<\/strong> (reconocimiento, no comercial, sin obra derivada, 3.0 unported)<\/p>\n<hr \/>\n<p><em>El Club del Autodidacta<\/em><\/p>\n<hr \/>\n<p>Consulta el \u00edndice completo de art\u00edculos relacionados con <a href=\"http:\/\/elclubdelautodidacta.es\/wp\/indice-python\/\">Python<\/a>.<\/p>\n<div class=\"SPOSTARBUST-Related-Posts\"><H3>Tal vez te interese...<\/H3><ul class=\"entry-meta\"><li class=\"SPOSTARBUST-Related-Post\"><a title=\"Python &#8211; Buscando a Wally.txt\" href=\"http:\/\/elclubdelautodidacta.es\/wp\/2016\/02\/python-buscando-a-wally-txt\/\" rel=\"bookmark\">Python &#8211; Buscando a Wally.txt<\/a><\/li>\n<li class=\"SPOSTARBUST-Related-Post\"><a title=\"Python &#8211; Troceando desde el lado izquierdo\" href=\"http:\/\/elclubdelautodidacta.es\/wp\/2015\/12\/python-troceando-desde-el-lado-izquierdo\/\" rel=\"bookmark\">Python &#8211; Troceando desde el lado izquierdo<\/a><\/li>\n<li class=\"SPOSTARBUST-Related-Post\"><a title=\"Comparando objetos en Python\" href=\"http:\/\/elclubdelautodidacta.es\/wp\/2015\/06\/comparando-objetos-en-python\/\" rel=\"bookmark\">Comparando objetos en Python<\/a><\/li>\n<li class=\"SPOSTARBUST-Related-Post\"><a title=\"Python &#8211; Sumando objetos\" href=\"http:\/\/elclubdelautodidacta.es\/wp\/2015\/05\/python-sumando-objetos\/\" rel=\"bookmark\">Python &#8211; Sumando objetos<\/a><\/li>\n<li class=\"SPOSTARBUST-Related-Post\"><a title=\"Python &#8211; Una tortuga de brocha fina\" href=\"http:\/\/elclubdelautodidacta.es\/wp\/2014\/12\/python-una-tortuga-de-brocha-fina\/\" rel=\"bookmark\">Python &#8211; Una tortuga de brocha fina<\/a><\/li>\n<\/ul><\/div>","protected":false},"excerpt":{"rendered":"<p>Objetivo: presentar la cl\u00e1usula finally en el manejo de excepciones en Python. Imaginemos, por un momento, que soy un perverso programador que, bajo el aspecto de un aparente d\u00f3cil y simple programa esconde en \u00e9l una intenci\u00f3n oculta. Supongamos que, aprovech\u00e1ndome del deseo de todo el mundo de disponer de una aplicaci\u00f3n que permita calcular &hellip; <a href=\"http:\/\/elclubdelautodidacta.es\/wp\/2014\/03\/python-y-finalmente-finally\/\" class=\"more-link\">Continuar leyendo<span class=\"screen-reader-text\"> \u00abPython &#8211; Y, finalmente, finally\u00bb<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[8],"tags":[482,503],"class_list":["post-7597","post","type-post","status-publish","format-standard","hentry","category-python","tag-excepciones","tag-python"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1PGgv-1Yx","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/posts\/7597","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/comments?post=7597"}],"version-history":[{"count":19,"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/posts\/7597\/revisions"}],"predecessor-version":[{"id":7616,"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/posts\/7597\/revisions\/7616"}],"wp:attachment":[{"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/media?parent=7597"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/categories?post=7597"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/elclubdelautodidacta.es\/wp\/wp-json\/wp\/v2\/tags?post=7597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}