Introducción a Python

Prólogo

Te damos la bienvenida al instructivo en línea de Python de Google. Está basado en el curso introductorio de Python que se ofrece de forma interna. Como se mencionó en la página de configuración, este material abarca Python 3.

Si deseas realizar un curso complementario de MOOC, prueba los de Udacity y Coursera (introducción a la programación [principiantes] o introducción a Python). Por último, si quieres aprender a tu propio ritmo en línea sin mirar videos, prueba los que se indican al final de esta publicación. Cada una incluye contenido educativo, además de un intérprete interactivo de Python con el que puedes practicar. ¿Qué es el "intérprete" que mencionamos? Lo descubrirás en la siguiente sección.

Introducción al lenguaje

Python es un lenguaje interpretado y dinámico (compilado mediante código de bytes). No hay declaraciones de tipo de variables, parámetros, funciones o métodos en el código fuente. Esto hace que el código sea corto y flexible, y se pierde la verificación del tipo de tiempo de compilación del código fuente. Python realiza un seguimiento de los tipos de todos los valores en el entorno de ejecución y marca el código que no tiene sentido mientras se ejecuta.

Una manera excelente de ver cómo funciona el código de Python es ejecutar el intérprete de Python y escribir código directamente en él. Si alguna vez tienes una pregunta como: “¿Qué sucede si agrego un int a un list?”. Solo escribirlo en el intérprete de Python es una manera rápida y, probablemente, la mejor manera de ver qué sucede. (A continuación, verás lo que realmente sucede).

$ python3        ## Run the Python interpreter
Python 3.X.X (XXX, XXX XX XXXX, XX:XX:XX) [XXX] on XXX
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 6       ## set a variable in this interpreter session
>>> a           ## entering an expression prints its value
6
>>> a + 2
8
>>> a = 'hi'    ## 'a' can hold a string just as well
>>> a
'hi'
>>> len(a)      ## call the len() function on a string
2
>>> a + len(a)  ## try something that doesn't work
Traceback (most recent call last):
  File "", line 1, in 
TypeError: can only concatenate str (not "int") to str
>>> a + str(len(a))  ## probably what you really wanted
'hi2'
>>> foo         ## try something else that doesn't work
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'foo' is not defined
>>> ^D          ## type CTRL-d to exit (CTRL-z in Windows/DOS terminal)

Las dos líneas que Python imprime después de que escribes y antes del mensaje >>> te informan sobre la versión de Python que estás usando y dónde se compiló. Siempre que lo primero que se muestre sea “Python 3”, estos ejemplos deberían funcionar en tu caso.

Como puedes ver arriba, es fácil experimentar con variables y operadores. Además, el intérprete arroja, (o “genera” en términos de Python) un error de entorno de ejecución si el código intenta leer una variable a la que no se le asignó un valor. Al igual que C++ y Java, Python distingue mayúsculas de minúsculas, por lo que "a" y "A" son variables diferentes. El final de una línea indica el final de una instrucción, por lo que, a diferencia de C++ y Java, Python no requiere punto y coma al final de cada instrucción. Los comentarios comienzan con el símbolo "#" y se extienden hasta el final de la línea.

Código fuente de Python

Los archivos fuente de Python usan la extensión ".py" y se denominan "módulos". Con un módulo de Python hello.py, la forma más fácil de ejecutarlo es con el comando de shell "python hello.py Alice", que llama al intérprete de Python para ejecutar el código en hello.py y pasa el argumento de línea de comandos "Alice". Consulta la página de documentos oficiales para conocer todas las opciones que tienes cuando ejecutas Python desde la línea de comandos.

Este es un programa hello.py muy simple (ten en cuenta que los bloques de código están delimitados estrictamente con sangría en lugar de llaves; hablaremos sobre esto más adelante):

#!/usr/bin/python3

# import modules used here -- sys is a very standard one
import sys

# Gather our code in a main() function
def main():
    print('Hello there', sys.argv[1])
    # Command line args are in sys.argv[1], sys.argv[2] ...
    # sys.argv[0] is the script name itself and can be ignored

# Standard boilerplate to call the main() function to begin
# the program.
if __name__ == '__main__':
    main()

La ejecución de este programa desde la línea de comandos se ve de la siguiente manera:

$ python3 hello.py Guido
Hello there Guido
$ ./hello.py Alice  ## without needing 'python3' first (Unix)
Hello there Alice

Las importaciones, los argumentos de la línea de comandos y len()

Las sentencias más externas de un archivo de Python, o “módulo”, realizan su configuración por única vez. Esas instrucciones se ejecutan de arriba abajo la primera vez que el módulo se importa en algún lugar, configurando sus variables y funciones. Un módulo de Python se puede ejecutar directamente (como se muestra arriba de python3 hello.py Bob) o se puede importar y usar en otro módulo. Cuando un archivo de Python se ejecuta directamente, la variable especial "__name__" se establece en "__main__". Por lo tanto, es común que el if __name__ ==... estándar se muestre arriba para llamar a una función main() cuando el módulo se ejecuta directamente, pero no cuando otro módulo lo importa.

En un programa estándar de Python, la lista sys.argv contiene los argumentos de la línea de comandos de la manera estándar: sys.argv[0] es el programa en sí, sys.argv[1] es el primer argumento y así sucesivamente. Si conoces argc o la cantidad de argumentos, simplemente puedes solicitar este valor de Python con len(sys.argv), al igual que lo hicimos en el código de intérprete interactivo anterior cuando se solicitó la longitud de una cadena. En general, len() puede indicarte la longitud de una string, la cantidad de elementos en listas y tuplas (otra estructura de datos similar a un array) y la cantidad de pares clave-valor en un diccionario.

Funciones definidas por el usuario

Las funciones en Python se definen de la siguiente manera:

# Defines a "repeat" function that takes 2 arguments.
def repeat(s, exclaim):
    """
    Returns the string 's' repeated 3 times.
    If exclaim is true, add exclamation marks.
    """

    result = s + s + s # can also use "s * 3" which is faster (Why?)
    if exclaim:
        result = result + '!!!'
    return result

Observa también cómo las líneas que conforman la función o la sentencia if se agrupan por todas con el mismo nivel de sangría. También presentamos 2 formas diferentes de repetir cadenas, con el operador +, que es más fácil de usar, pero * también funciona porque es el operador "repetir" de Python, lo que significa que '-' * 10 le brinda a '----------' una forma sencilla de crear una "línea" en la pantalla. En el comentario del código, dimos a entender que * funciona más rápido que +, el motivo es que * calcula el tamaño del objeto resultante una vez, mientras que con +, ese cálculo se hace cada vez que se llama a +. Los operadores + y * se denominan operadores "sobrecargados" porque tienen distintos significados para los números en comparación con las cadenas (y otros tipos de datos).

La palabra clave def define la función con sus parámetros entre paréntesis y su código con sangría. La primera línea de una función puede ser una cadena de documentación ("docstring") que describa lo que hace la función. La docstring puede ser una sola línea o una descripción de varias líneas, como en el ejemplo anterior. (Sí, se trata de "comillas triples", una función exclusiva de Python). Las variables definidas en la función son locales de esa función, por lo que el "resultado" en la función anterior es independiente de una variable "resultado" en otra función. La sentencia return puede tomar un argumento, en cuyo caso ese es el valor que se muestra al llamador.

Este es un código que llama a la función repeat() anterior e imprime lo que muestra:

def main():
    print(repeat('Yay', False))      ## YayYayYay
    print(repeat('Woo Hoo', True))   ## Woo HooWoo HooWoo Hoo!!!

En el tiempo de ejecución, las funciones se deben definir mediante la ejecución de un “def” antes de que se las llame. Es común definir una función main() en la parte inferior del archivo con las funciones que llama encima de ella.

Sangría

Una característica inusual de Python es que la sangría del espacio en blanco de un fragmento de código afecta su significado. Un bloque lógico de sentencias, como los que conforman una función, deben tener la misma sangría, establecidos a partir de la sangría de su función superior, "if" o lo que sea. Si una de las líneas de un grupo tiene una sangría diferente, se marca como un error de sintaxis.

El uso de espacios en blanco en Python parece un poco extraño al principio, pero es lógico y descubrí que me acostumbré muy rápido. Evita usar tabulaciones, ya que complican en gran medida el esquema de sangría (sin mencionar que las tabulaciones pueden tener distintos significados en diferentes plataformas). Configura tu editor para que inserte espacios en lugar de pestañas para el código Python.

Una pregunta habitual que se hacen los principiantes es: “¿Cuántos espacios debo aplicar sangrías?”. Según la guía de estilo oficial de Python (PEP 8), debes aplicar una sangría de 4 espacios. (Dato curioso: El lineamiento de estilo interno de Google establece una sangría de 2 espacios)

Código verificado en el entorno de ejecución

Python realiza muy pocas verificaciones en el tiempo de compilación, aplazando casi todas las verificaciones de tipo, nombre, etc. en cada línea hasta que se ejecute esa línea. Supongamos que el método main() anterior llama a repeat() de la siguiente manera:

def main():
    if name == 'Guido':
        print(repeeeet(name) + '!!!')
    else:
        print(repeat(name))

La sentencia if contiene un error obvio, por el que la función repeat() se escribe accidentalmente como repeeeet(). Lo gracioso de Python: este código se compila y se ejecuta bien siempre que el nombre en el tiempo de ejecución no sea 'Guido'. Solo cuando una ejecución realmente intente ejecutar repeeeet(), se dará cuenta de que no existe tal función y se mostrará un error. Además, hay un segundo error en este fragmento. a este nombre no se le asignó un valor antes de compararlo con "Guido". Python generará un 'NameError' si intentas evaluar una variable no asignada. Estos son algunos ejemplos que demuestran que cuando ejecutas un programa en Python por primera vez, algunos de los primeros errores que verás serán errores tipográficos simples o variables no inicializadas como estas. Esta es un área en la que los lenguajes con un sistema de tipos más detallados, como Java, tienen una ventaja: pueden detectar esos errores en el tiempo de compilación (pero, por supuesto, debes mantener toda esa información de tipo... es una compensación).

Python 3 introdujo sugerencias de tipo. Las sugerencias de tipo te permiten indicar cuál es el tipo para cada argumento de una función, así como el tipo del objeto que muestra la función. Por ejemplo, en la función anotada def is_positive(n: int) -> bool:, el argumento n es int y el valor que se muestra es bool. Analizaremos el significado de estos tipos más adelante. Sin embargo, las sugerencias de tipo son totalmente opcionales. Verás cada vez más código para adoptar sugerencias de tipo porque, si las usas, algunos editores, como cider-v y VS.code, pueden ejecutar verificaciones para verificar que se llame a tus funciones con los tipos de argumento correctos. Incluso pueden sugerir y validar argumentos a medida que editas el código. En este instructivo, no se tratarán las sugerencias de tipo, pero queremos asegurarnos de que las conoces si te enteras de ellas o las ves en la naturaleza.

Nombres de variables

Debido a que las variables de Python no tienen ningún tipo escrito en el código fuente, es muy útil asignar nombres significativos a tus variables para recordar lo que está sucediendo. Así que usa "nombre" si es un solo nombre, "nombres" si es una lista de nombres y "tuplas" si es una lista de tuplas. Muchos errores básicos de Python son el resultado de olvidar qué tipo de valor hay en cada variable, así que usa los nombres de tus variables (todo lo que tengas) para mantener el orden.

En lo que respecta a los nombres reales, algunos idiomas prefieren partes_subrayadas para nombres de variables compuestos por "más de una palabra", pero otros idiomas prefieren el uso de camelCasing. En general, Python prefiere el método de guion bajo, pero guía a los desarrolladores para que opten por camelCasing si se integran en el código existente de Python que ya usa ese estilo. Recuentos de legibilidad Obtén más información en la sección sobre convenciones de nombres en PEP 8.

Como puedes suponer, las palabras clave como "if" y "while" no se pueden usar como nombres de variables; si lo haces, obtendrás un error de sintaxis. Sin embargo, ten cuidado de no utilizar elementos integrados como nombres de variables. Por ejemplo, si bien “str”, “list” e “print” pueden parecer buenos nombres, estarías anulando esas variables de sistema. Los elementos integrados no son palabras clave y, por lo tanto, los desarrolladores nuevos de Python pueden utilizarlos de forma involuntaria.

Más información sobre los módulos y sus espacios de nombres

Supongamos que tienes un módulo “binky.py” que contiene “def foo()”. El nombre completamente calificado de esa función foo es “binky.foo”. De esta manera, varios módulos de Python pueden nombrar sus funciones y variables como deseen, y los nombres de las variables no entrarán en conflicto: module1.foo es diferente de module2.foo. En el vocabulario de Python, diríamos que binky, module1 y module2 tienen sus propios “espacios de nombres” que, como puedes suponer, son vinculaciones de nombre a objeto de variable.

Por ejemplo, tenemos el módulo “sys” estándar que contiene algunas instalaciones de sistema estándar, como la lista argv y la función exit(). Con la instrucción "import sys", puede acceder a las definiciones en el módulo sys y hacer que estén disponibles por su nombre completamente calificado, p. ej., sys.exit(). (Sí, 'sys' también tiene un espacio de nombres).

  import sys

  # Now can refer to sys.xxx facilities
  sys.exit(0)

Hay otro formulario de importación similar a este: “from sys import argv, exit”. Eso hace que argv y exit() estén disponibles por sus nombres cortos; sin embargo, recomendamos el formulario original con los nombres completos porque es mucho más fácil determinar de dónde proviene una función o un atributo.

Hay muchos módulos y paquetes que se incluyen en una instalación estándar del intérprete de Python, por lo que no necesitas hacer nada adicional para usarlos. Se conocen en conjunto como la “Biblioteca estándar de Python”. Entre los módulos o paquetes más usados, se incluyen los siguientes:

  • sys: acceso a exit(), argv, stdin, stdout, ...
  • re: expresiones regulares
  • SO: interfaz de sistema operativo, sistema de archivos

Puede encontrar la documentación de todos los módulos y paquetes de la biblioteca estándar en http://docs.python.org/library.

Ayuda en línea, help() y dir()

Hay varias formas de obtener ayuda para Python.

  • Haz una búsqueda en Google que comience con la palabra “python”, como “lista de python” o “cadena de python en minúscula”. A menudo, el primer hit es la respuesta. Por alguna razón, esta técnica parece funcionar mejor para Python que para otros lenguajes.
  • El sitio oficial de documentos de Python, docs.python.org, tiene documentos de alta calidad. No obstante, suelo buscar un par de palabras en Google con más rapidez.
  • También existe una lista de distribución oficial para tutores diseñada específicamente para quienes son nuevos en Python o la programación.
  • Puedes encontrar muchas preguntas (y respuestas) en StackOverflow y Quora.
  • Usa las funciones help() y dir() (consulta a continuación).

Dentro del intérprete de Python, la función help() muestra cadenas de documentación para varios módulos, funciones y métodos. Estas cadenas de documentos son similares a la de javadoc de Java. La función dir() te indica cuáles son los atributos de un objeto. Estas son algunas maneras de llamar a help() y dir() desde el intérprete:

  • help(len): Es una cadena de ayuda para la función len() integrada. Ten en cuenta que es "len" no "len()", que es una llamada a la función que no queremos.
  • help(sys): Es una cadena de ayuda para el módulo sys (primero debe hacer un import sys).
  • dir(sys): dir() es como help(), pero solo proporciona una lista rápida de los símbolos definidos o "atributos".
  • help(sys.exit): Es una cadena de ayuda para la función exit() en el módulo sys.
  • help('xyz'.split): Es una cadena de ayuda para el método split() para objetos de cadena. Puedes llamar a help() con ese objeto en sí o con un ejemplo de ese objeto, más su atributo. Por ejemplo, llamar a help('xyz'.split) es lo mismo que llamar a help(str.split).
  • help(list): Es la cadena de ayuda para objetos list.
  • dir(list): Muestra atributos del objeto list, incluidos sus métodos.
  • help(list.append): Es una cadena de ayuda para el método append() para objetos list.