Python, para empezar...
Lo que hay que saber cuando empiezas con Python
No soy un especialista en este lenguaje.
Este es un breve esquema de los puntos que me parecen importantes para empezar con Python.
¿Porqué Python?
Mis razones...
- Tiene una enorme comunidad
- Es muy popular
- Extraordinariamente bien documentado
- Fácil encontrar respuesta a cualquier cuestión en internet
- Viene instalado en todas las distribuciones linux
- Curva de aprendizaje suave
- Prefiero hacer scripts en Python que en bash
- Fantástica y amplia librería (para casi todo)
- Llamadas a código C fácilmente
Tabla características
Característica | Observaciones | |
---|---|---|
OOP | sí | |
Herencia múltiple | sí | Mixins |
Prog. estructurada | sí | |
Módulos | sí | |
Parámetros por nombre | sí | |
Parámetros por defecto | sí | |
Número parámetros variable | sí | |
Parámetros por referencia | na | No aplica (ver variables|asignación) |
Parámetros por valor | na | No aplica (ver variables|asignación) |
Funcional | p | Parcial |
Recursión de cola | no | Al menos en CPython |
Closures | sí | Todas las funciones son closures |
Eventos | no |
Tener un modelo de eventos tipo delegados o signal/slot no debería ser un problema gracias a losclosures
|
Lambdas | sí | limitadas a una expresión |
Corrutinas | sí | Lo llaman generadores |
Multimétodos | no | |
Declaración explícita de variables | no | |
Declaración de constantes | no | |
Variables montículo | na | No aplica |
Variables pila | na | No aplica |
Tipado dinámico | sí | duck typing |
Tipado fuerte | sí | |
Literal string | sí | |
String multilínea | sí | |
Tuplas | sí | |
Listas | sí | |
Mapas | sí | diccionarios |
Regular expresions | sí | librería estándar |
Enteros gigantes | sí | |
REPL | sí | |
Metaprogramación | sí | |
Reflexión | sí | |
Popularidad | sí | ENORME |
Librerías | sí | Enormes |
Generación código nativo | no | Cython sí |
Rendimiento | p | Bajo |
JIT | p | pypy sí. CPython no |
Gestión memoria | v | Contador referencias y recolector de basura para ciclos |
RAII | sí | width |
Properties | sí | ver más abajo |
Concurrencia | p | Corrutinas y threads. Ver paralelismo |
Paralelismo | p | Bloqueos GIL |
Singleton | p | Fácil de crear en librería. Discutible necesidad por soporte prog. estructurada. |
Curva aprendizaje | suave | |
Decoradores | sí | |
Integración con librerías C | sí | Muy sencillo |
Control de errores | sí | try... except |
Control división por cero | sí | lanza una excepción |
General
-
- Paradigma:
- OOP y estructurado
- Parcialmente funcional y metaprogramación
-
- Tipado:
- Dinámico
- Estricto
-
- Gestión memoria
- Combinación de contador de referencias y recolector de basura para ciclos
-
- Filosofía Python
- “there should be one—and preferably only one—obvious way to do it”vs Perl...“here is more than one way to do it”
-
- Estructuración de código
- No punto y coma
- No llaves
- Identación
-
- Comentarios
- Sólo # para comentario hasta final de la línea
-
- Estructuras de control
- import
- if... elif... else...
- for ... in ...
- while...
- try... finally
- class...
- def...
- with... (RAII)
- pass
- assert
- yield coroutines, llamadas generadores en Python
-
- Operadores y expresiones
- Comparación concatenados a<=b<=c
- // división entera
- == Compara por valor
- and or not
- condicional expresions x if c else y
- list comprehesion
- lambda expresions
-
- Tipos
- Tipado dinámico
- tipado fuerte
- duck typing
-
- Inmutables
- str
- bytes
- tuple
- frozenset
- int
- float
- complex
- bool
-
- Mutables
- bytearray
- list (slice e índice)
- set
- dict (the keys has to be inmutables)
-
- Strings
- ‘hola’
- “hola”
- r’hola’
- “”“En un lugar de la mancha,de cuyo nombre, no quiero acordarme,vivía un hidalgo caballero...”“”
-
- OOP
- instance.method(argument) es una simplificación (azúcar sintáctico) de Class.method(instance, argument)
- Métodos requieren el parámetro self
- Herencia múltiple
- Mixins
Herramientas imprescindibles
- Sphinx para la documentación
- PEP8 para revisión de estilo
- Pylint para revisión de estilo y posibles errores
Atención y precauciones
Estilo
- http://www.python.org/dev/peps/pep-0008/
- joined_lower para variables y nombre de métodos
- JOINED_UPPER para constantes
- CamelCase para nombres de clases
- Todos los módules, clases, funciones y métodos deben tener cadenas de documentación
-
- Utilizar comentarios de mantenimiento
- # !!! BUG: ...
- # !!! FIX: ...
- # TODO: ...
- # ???
- if x == True: NO, en su lugar... if x:
- Nunca print a, siempre print(a) compatible con Python 2 y 3
Parámetros por defecto
Muy buena funcionalidad, pero observa el siguiente error:
La salida no es la esperada
Pylint nos avisará de estos problemas. Cuando el valor por defecto es un mutable, no puede hacerse así
Variables
Se asocia un nombre a un valor.
Sin declaración explícita de variables
Tipado estricto sí
pero...
En otros lenguajes:
Asignación variables
Dos nombres apuntan al mismo valor.
Ahora dos nombres apuntan al mismo valor, y luego uno de los nombres apunta a un valor diferente
Pero...
Aquí se modifica el valor de a al cambiar el de b. En este caso, las dos etiquetas siguen apuntando al mismo valor.
La diferencia en ambos casos, es que una lista es mutable mientras que un entero es inmutable
Copia variables
Como hemos comentado, el operador ‘=’ no significa copiar el valor. Pero si el valor es de un tipo inmutable, el resultado es equivalente.
¿Qué hacer con el frecuente caso de que el valor no sea inmutable?
En los tipos dic, list, set... tenemos un constructor para copiar.
También podemos hacerlo así:
Perfecto, b = dict(a) nos crea una copia.
Pero atención:
Sorpresa, hemos realizado una copia, pero... han cambiado d["sd"]["b"] y d2["sd"]["b"]
Para evitar esto...
Ahora sí.
Soy consciente de ignorar una de las reglas de estilo Python al escribir from copy import deepcopy, pero lo considero justificado en este caso.
¿Variable global o local?
En este programa no hay sorpresas
Pero con esta pequeña variación...
Tenemos un error porque dice que vg es utilizada antes de ser asignada. Para evitar este error...
import y path
Organizar módulos en directorios.
Podemos hacer esto en Python al estilo de otros lenguajes.
Pero no olvides crear el fichero __init__.py aunque esté vacío en cada directorio que quieras que sea un módulo
import, path y pruebas
Supongamos que organizamos nuestro proyecto en directorios (muy lógico). El path para la búsqueda de módulos estará en el directorio actual y podríamos tener algo como...
Pero este módulo podría ser utilizado en unas pruebas unitarias desde otro módulo y otro directorio.
Eventos
Utilizando PyQt4 es directo con signal/slot de Qt, pero, no es Pythonic
Es fácil crear un sistema tipo signal/slot o delegates
Pasar por referencia
Como ya hemos visto, no se puede pasar por referencia. Todo son valores de etiquetas.
Si el objeto pasado es o no inmutable...
No suele ser neceario pasar por referencia. Lógicamente hay que utilizar las tuplas.
Pero en el caso de la clase Event anterior, sí podemos necesitar pasar por referencia para recoger un valor de todos los llamados.
Para evitar problemas con los mutable e inmutable, basta con pasar una lista, que es mutable
Ocultar
private, protected, ocultación.
No existe en Python. Guido dice que Python es para adultos, y no necesitan un filtro de protección.
No obstante, se utiliza como convenio _ al principio de los métodos que queremos indicar que no son de “libre acceso”, y que se debería acceder a ellos siendo mayores de edad y con madured acreditada.
Múltiples líneas
Sí, se puede utilizar \ para dividir una línea, pero es más claro cómodo y sencillo, utilizar paréntesis
Gestión de errores
Un ejemplo muy sencillo
Propiedades
O utilizando decoradores...
Ejemplo completo
Típico problema de los misioneros y caníbales:
Comentarios