Introducción a Python

Introducción

Te damos la bienvenida al instructivo en línea de Python de Google. Se basa 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 buscas un curso de MOOC complementario, prueba los de Udacity y Coursera (introducción a la programación [principiantes] o introducción a Python). Por último, si buscas aprendizaje en línea a tu propio ritmo sin mirar videos, prueba los que se enumeran al final de esta publicación. Cada uno incluye contenido de aprendizaje y un intérprete interactivo de Python con el que puedes practicar. ¿A qué nos referimos con ese "intérprete"? Lo descubrirás en la siguiente sección.

Introducción al lenguaje

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

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

$ 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 imprime Python después de que escribes python y antes de la instrucción >>> te informan sobre la versión de Python que usas y dónde se compiló. Siempre que lo primero que se imprima sea “Python 3”, estos ejemplos deberían funcionar.

Como puedes ver más arriba, es fácil experimentar con variables y operadores. Además, el intérprete arroja, o "genera" en el lenguaje de Python, un error de tiempo 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 marca el final de una sentencia, por lo que, a diferencia de C++ y Java, Python no requiere un punto y coma al final de cada sentencia. 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 le pasa el argumento de línea de comandos "Alice". Consulta la página de documentación oficial para ver todas las opciones que tienes cuando ejecutas Python desde la línea de comandos.

Este es un programa hello.py muy simple (observa que los bloques de código se delimitan estrictamente con sangría en lugar de llaves; hablaremos más 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()

Ejecutar 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

Importaciones, argumentos de línea de comandos y len()

Las sentencias más externas de un archivo de Python, o “módulo”, realizan su configuración única. Esas sentencias se ejecutan de arriba abajo la primera vez que se importa el módulo a algún lugar y configuran sus variables y funciones. Un módulo de Python se puede ejecutar directamente, como se muestra más arriba en python3 hello.py Bob, o lo puede importar y usar algún otro módulo. Cuando se ejecuta un archivo Python directamente, la variable especial "__name__" se establece en "__main__". Por lo tanto, es común tener el modelo de texto if __name__ ==... que se muestra 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 forma estándar, en la que 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, puedes solicitar este valor de Python con len(sys.argv), tal como lo hicimos en el código de intérprete interactivo anterior cuando solicitaste la longitud de una cadena. En general, len() puede indicarte la longitud de una cadena, 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 da '----------', una forma ordenada de crear una “línea” en pantalla. En el comentario del código, insinuamos que * funciona más rápido que +, ya que * calcula el tamaño del objeto resultante una vez, mientras que con +, ese cálculo se realiza cada vez que se llama a +. Tanto + como * se denominan operadores "sobrecargados" porque tienen significados diferentes para los números y las cadenas (y otros tipos de datos).

La palabra clave def define la función con sus parámetros dentro de 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 describe 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í, esas son "comillas triples", una función exclusiva de Python). Las variables definidas en la función son locales para 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 el código que llama a la función repeat() anterior y que imprime lo que muestra:

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

Durante el tiempo de ejecución, las funciones deben definirse mediante la ejecución de una "def" antes de que se las llame. Es habitual definir una función main() en la parte inferior del archivo con las funciones a las que llama por encima.

Sangría

Una característica inusual de Python es que la sangría de espacios 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, establecida a partir de la sangría de su función superior o “si” 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 de Python puede parecer un poco extraño al principio, pero es lógico y me acostumbré a él muy rápido. Evita usar TAB, ya que complican mucho el esquema de sangría (sin mencionar que los TAB pueden significar diferentes cosas en diferentes plataformas). Configura tu editor para que inserte espacios en lugar de TAB para el código de Python.

Una pregunta común de los principiantes es: "¿Cuántos espacios debo agregar sangría?". Según la guía de estilo oficial de Python (PEP 8), debes usar 4 espacios para la sangría. (Dato curioso: el manual de estilo interno de Google dicta que el texto debe tener una sangría de 2 espacios).

Código verificado durante el tiempo de ejecución

Python realiza muy pocas verificaciones en el tiempo de compilación y aplaza casi todas las verificaciones de tipo, nombre, etc. en cada línea hasta que se ejecute. Supongamos que el 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, en el que la función repeat() se escribe accidentalmente como repeeeet(). Lo curioso de Python es que este código se compila y se ejecuta bien, siempre y cuando el nombre en el tiempo de ejecución no sea "Guido". Solo cuando una ejecución intente ejecutar repeeeet(), notará que no hay tal función y arrojará un error. También hay un segundo error en este fragmento. al nombre no se le asignó un valor antes de que se comparara con 'Guido'. Python generará un "NameError" si intentas evaluar una variable no asignada. Estos son algunos ejemplos que demuestran que cuando ejecutas un programa 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 detallado, 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 un compromiso).

Python 3 introdujo las sugerencias de tipo. Las sugerencias de tipo te permiten indicar cuál es el tipo de cada argumento en una función, así como cuál es el tipo del objeto que muestra la función. Por ejemplo, en la función def is_positive(n: int) -> bool: con anotaciones, el argumento n es un int y el valor que se muestra es un bool. Más adelante, analizaremos qué significan estos tipos. Sin embargo, las sugerencias de tipo son totalmente opcionales. Verás que cada vez más código adopta 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 argumentos correctos. Incluso pueden sugerir y validar argumentos mientras editas el código. En este instructivo, no se abordan las sugerencias de tipos, pero queremos asegurarnos de que las conozcas si escuchas hablar de ellas o las ves en la naturaleza.

Nombres de variables

Dado que las variables de Python no tienen ningún tipo escrito en el código fuente, es muy útil asignarles nombres significativos para recordar lo que sucede. Por lo tanto, usa "name" si es un solo nombre, "names" si es una lista de nombres y "tuples" si es una lista de tuplas. Muchos errores básicos de Python se deben a que se olvida qué tipo de valor hay en cada variable, por lo que debes usar los nombres de las variables (todo lo que tienes realmente) para mantener la coherencia.

En cuanto a los nombres reales, algunos lenguajes prefieren underscored_parts para los nombres de variables que contienen "más de una palabra", pero otros prefieren camelCasing. En general, Python prefiere el método de guion bajo, pero guía a los desarrolladores a utilizar camelCasing si se integra en código existente de Python que ya usa ese estilo. La legibilidad es importante. Obtén más información en la sección sobre convenciones de nombres en PEP 8.

Como puedes adivinar, 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 usar funciones integradas como nombres de variables. Por ejemplo, aunque "str", "list" e "print" pueden parecer buenos nombres, deberías anular esas variables del sistema. Los elementos integrados no son palabras clave y, por lo tanto, son susceptibles de que los desarrolladores nuevos de Python los usen por error.

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

Supongamos que tienes un módulo "binky.py" que contiene un "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 quieran, y los nombres de las variables no entrarán en conflicto, ya que 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 adivinar, son vinculaciones de nombres de variables a objetos.

Por ejemplo, tenemos el módulo “sys” estándar que contiene algunas instalaciones estándar del sistema, como la lista argv y la función exit(). Con la sentencia "import sys", puedes acceder a las definiciones del 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 que se ve de la siguiente manera: “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 completamente calificados, ya que 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 tienes que hacer nada adicional para usarlos. Estos se conocen en conjunto como la “Biblioteca estándar de Python”. Entre los módulos o paquetes de uso general, se incluyen los siguientes:

  • sys: Acceso a exit(), argv, stdin, stdout, etc.
  • re: Expresiones regulares
  • os: Interfaz del sistema operativo, sistema de archivos

Puedes 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()

Existen varias formas de obtener ayuda para Python.

  • Realiza una búsqueda en Google y comienza con la palabra "python", como "lista de python" o "cadena de python en minúsculas". A menudo, el primer hit es la respuesta. Por alguna razón, esta técnica parece funcionar mejor en Python que en otros lenguajes.
  • El sitio oficial de documentación de Python, docs.python.org, tiene documentos de alta calidad. Sin embargo, a menudo encuentro que una búsqueda de Google de un par de palabras es más rápida.
  • También hay una lista de distribución oficial de Tutor diseñada específicamente para quienes son nuevos en Python o en 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() extrae cadenas de documentación para varios módulos, funciones y métodos. Estas cadenas de documentos son similares a javadoc de Java. La función dir() te indica cuáles son los atributos de un objeto. A continuación, se indican algunas formas de llamar a help() y dir() desde el intérprete:

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