Modulos y paquetes en Python 3

1. Módulos

Ya sabemos que un script es un guión de instrucciones guardadas en un fichero, ¿pero que ocurre si queremos una función o clase en diferentes scripts?

Pues para ello entra en juego los módulos, siendo posible importarlos en diferentes scripts. Así evitaremos repetir código.

Para empezar vamos a tener dos ficheros: saludos.py y test.py

El fichero saludos.py será un módulo, el cual contiene dentro una función denominada saludar() 

# Esto es un módulo

def saludar():

print(“Hola, guapi”)

Y por otro lado tendremos el fichero test.py desde donde importaremos el módulo saludos para poder usar la función saludar():

# test.py

import saludos

saludos.saludar()

# El caso anterior funciona pero existe otra forma de importar una función especifica o directamente todas las funciones:

from saludos import saludar # Si cambiamos saludar por un *, importará todos los métodos del módulo

saludar()

Si agregamos esta class al módulo saludos podemos llamarlo desde test.py:

# Saludos.py

class Saludo():

def __init__(self):

print(“Saludo desde la clase __init__”)

# Test.py

from saludos import Saludo

Saludo()

Esta forma de importar los métodos de este módulo funcionan, si los archivos se encuentran bajo un mismo directorio. ¿ Y si el módulo se encuentra en otra ruta ?

Ejemplo de estructura:

– saludos.py

– test.py

– test\ -> test1.py

Dentro de el fichero test1.py tendríamos que insertar manualmente la ruta del módulo ya que se encuentra en un directorio anterior, ya que el interprete de python analiza en el siguiente orden donde se encuentra:

  1. Si es un módulo estándar de python
  2. Busca un archivo con ese nombre en el syspath
  3. Directorio por defecto de la instalación de python

# test1.py

import sys

print(sys.path) # Para ver todos los directorios donde busca el módulo

sys.path.insert(1, ‘..’) # Insertamos un nuevo path con 2 puntos, para indicar que es el directorio anterior, en este caso el directorio test

from saludos import Saludo

Saludo()

Hola, guapi

No es muy útil insertar manualmente cada uno de las rutas en todos los scripts, si fuera el caso lo ideal sería añadir las rutas en el script principal.

Pero para esto python tiene una forma de utilizar los diferentes módulos en cualquier directorio del sistema y son los paquetes.

2. Paquetes

Los paquetes nos ofrecen la posibilidad de unificar distintos módulos bajo un mismo nombre de paquete.

Nos permiten manejar y distribuir nuestro código como si fueran librerías instalables de python, así se podrían utilizar como módulos estándar desde el script sin cargarlos previamente.

Teniendo en cuenta la siguiente estructura de directorios y ficheros:

El fichero __init__ le indicará que el directorio donde se encuentra este fichero, es un paquete. En este caso hace referencia al directorio Paquete. Por lo tanto viendo la captura, podemos obviar que adios y hola son subpaquetes.

# Código Fichero despedidas.py ( Módulo )

def despedirse():

print(“Adios, guapi”)

class Despedida():

def __init__(self):

print(“Adios desde la clase __init__”)

# Código Fichero saludos.py ( Módulo )

def saludar():

print(“Hola, guapi”)

class Saludo():

def __init__(self):

print(“Saludo desde la clase __init__”)

# Código Fichero script.py dentro del directorio paquete

# from NombrePaquetePrincipal.SubPaquete.NombreMódulo import NombreFunciónOClass O * ( Para todas )

from paquete.hola.saludos import saludar

from paquete.adiosdespedidas import Despedida

saludar()

Despedida()

Este ejemplo anterior funcionaría correctamente, sin embargo seguiría ocurriendo el mismo error de antes. Si ejecutamos el mismo código escrito en el fichero script.py pero dentro del directorio Paquete/test/ :

Nos devolvería el siguiente mensaje:

ImportError: No module named ‘paquete’

¿Solución? distribuir el paquete…

3. Distribucción

Instalar el paquete dentro de python, para poder utilizarlo desde cualquier sitio del sistema operativo. Lo primero sería convertir el paquete, en un paquete distribuible.

1. Crear un fichero setup.py en la raíz del directorio Paquete:

2. Escribir:

from setuptools import setup

setup(

name=”paquete”,

version=0.1″,

description=”esto es un paquete de ejemplo”,

author=”Charlie Sanchez”,

author_email=”admin@charliejsanchez.com”,

url=””,

scripts=[], # Si queremos integrar scripts dentro del paquete, Ejemplo: scripts[‘script.py’]

packages=[“paquete”,”paquete.adios”,”paquete.hola”] # Indicar los paquetes que van a formar parte de él, Paquete + Subpaquetes

)

3. Crear distribuible con el fichero:

Abrir terminal en la raíz:

python setup.py sdist

4. Si todo ha ido satisfactoriamente en el mismo nivel de directorio que se encuentra el directorio Paquete, se creará un nuevo directorio llamado dist con un fichero comprimido dentro:

Este comprimido podríamos compartirlo con cualquier usuario, y podría utilizar dichos módulos.

5. Instalar el paquete en nuestro python:

cd dist/

pip install paquete-0.1.tar.gz # Si no funciona pip, probar con pip3

Nota: para ver los paquetes que tenemos instalados: pip3 list

Ahora si volvemos a ejecutar el código script.py desde cualquier otra ubicación debería funcionar:

6. Si quisieramos desinstalar el paquete de python:

pip uninstall paquete

4. Módulos estándar

  • copy : para copiar variables como colecciones y objetos
  • collections : para utilizar las colas y más utilidades (Siguiente Apartado)
  • datetime : para manejar las fechas y las horas
  • doctest y unittest : para crear pruebas y hacer testing
  • html, xml y json : para manejar estructuras de datos web
  • pickle : para trabajar con ficheros
  • math : para operaciones matemáticas
  • re : para expresiones regulares
  • random : para generar contenidos aleatorios y seleccionar aleatoriamente
  • socket : para sistemas cliente-servidor
  • sqlite3 : gestionar una base de datos relacional mediante un fichero
  • sys : para manejar algunas funciones del sistema
  • threading : para dividir procesos en subprocesos
  • tkinter : para generar interfaces gráficas

5. Módulo Collections

# Contador

from collections import Counter

l = [1,2,3,4,1,2,3,1,2,1]

Counter(l)

Counter({1: 4, 2: 3, 3: 2, 4: 1})

p = “palabra”

Counter({‘a’: 3, ‘b’ : 1, ‘l’ : 1, ‘p’ : 1, ‘r’ :1})

animales = “gato perro canario perro canario perro”

animales.split()

[‘gato’,’perro’,’canario’,’perro’,’canario’,’perro’]

Counter(animales.split())

c.most_common(1) # Muestra el primer elemento más común

[(‘perro’, 3)]

c.most_common(2)

[(‘perro’, 3), (‘canario’, 2}]

l = [10,20,30,40,10,20,30,10,20,10]

# Transformar la lista en un contador

c = Counter(l)

# Es una subclase de diccionarios y por tanto tiene algunos de sus métodos:

c.items()

# Muestra las clases, con el número de veces que se repite

dict_items([40, 1), (10, 4), (20, 3), (30, 2)])

c.keys()

dict_keys([40, 10, 20, 30])

# Values nos devuelve el número de repeticiones

c.values()

dict_values([1, 4, 3, 2])

# También podríamos sumarlos, teniendo el total de elementos del contador.

sum(c.values())

10

Diccionario con un tipo por defecto:

d = {}

d[‘algo’]

KeyError: ‘algo’

# Defaultdict

from collections import defaultdict

d = defaultdict(float)

d[‘algo’]

0.0

d = defaultdict(str)

d[‘algo’]

‘ ‘

d = defaultdict(int)

d[‘algo’] = 10.5

d[‘algo’]

10.5

Otro problema que tienen los diccionarios es que son colecciones desordenadas, mostrando los elementos aleatoriamente:

n = {}

n[‘uno’] = ‘one’

n[‘dos’] = ‘two’

n[‘tres’] = ‘three’

n

{‘dos’: ‘two’, ‘tres’: ‘three’, ‘uno’: ‘one’}

# La colección OrderedDict, nos ordena el diccionario en el orden de creación de los elementos

n = OrderedDict()

n[‘uno’] = ‘one’

n[‘dos’] = ‘two’

n[‘tres’] = ‘three’

n

OrderedDict([(‘uno’, ‘one’), (‘dos’, ‘two’), (‘tres’, ‘three’)])

Tuplas con nombre:

from collections import namedtuple

Persona = namedtuple(‘Persona’,‘nombre apellido edad’)

p = Persona(nombre=“Charlie”,apellido=“Sanchez”,edad=25)

p.nombre o p[0]

‘Charlie’

p.apellido o p[1]

‘Sanchez’

p.edad o p[-1]

25

Y como recordatorio, recordar que las tuplas son inmutables y no podemos cambiar estos valores.

6. Módulo Datetime

import datetime

dt = datetime.datetime.now #Ahora

dt

datetime.datetime(2017, 9, 8, 12, 33, 28, 607208)

dt.year

2017

dt.month

9

dt.day

8

dt.hour

12

dt.minute

33

dt.second

28

dt.microsecond

607208

# Mostrar la hora de la variable dt

print(“{}:{}:{}”.format(dt.hour, dt.minute, dt.second))

13:33:28

# Mostrar la fecha de la variable dt

print(“{}/{}/{}”.format(dt.day, dt.month, dt.year))

# Crear una fecha manualmente

dt = datetime.datetime(2003,1,1)

dt

datetime.datetime(2003, 1, 1, 0, 0)

Cambiar el valor de un campo de la tupla:

dt.replace(year=3000)

datetime.datetime(3000, 1, 1, 0, 0)

Mostrar la hora con el formato iso

dt = datetime.datetime.now()

dt.isoformat()

‘2017-09-08T12:35:10.303386’

Mostrar la hora con un formato personalizado  – Enlace

dt.strftime(“%A %d %B %Y %I:%M”)

‘Friday 08 September 2017 12:35’

# Te lo devuelve en ingles, para cambiar el idioma antes de ejecutar la instrucción anterior

import locale

locale.setlocale(locale.LC_ALL, ‘es-ES’)

dt.strftime(“%A %d %B %Y %I:%M”) # %I – Formato 12 horas

‘viernes 8 de septiembre 2017 12:35’

Lista de códigos de idiomas: Aquí

dt.strftime(“%A %d de %B del %Y – %H:%M”) #H – Formato 24 horas

‘viernes 8 de septiembre 2017 – 12:35’

Sumarle al día de hoy, dos semanas:

dt = datetime.datetime.now()

t = datetime.timedelta(days=14) # También se pueden sumar horas y segundos

dentro_de_dos_semanas = dt + t

dentro_de_dos_semanas.strftime(“%A %d de %B del %Y – %H:%M”)

‘viernes 22 de septiembre del 2017 – 12:35’

Módulo Python Pytz – Zonas Horarias

Instalación :

pip install pytz

Uso :

import pytz

# Para consultar todas las zonas horarias

pytz.all_timezones

# Ver la hora actual  de Tokyo

dt = datetime.datetime.now(pytz.timezone(‘Asia/Tokyo’))

dt.strftime(“A %d de %B del %Y – %H:%M”)

‘viernes 8 de septiembre del 2017 – 20:11’

7. Módulo Math

Integra funciones para trabajar con matemáticas

import math

# Redondeos

pi = 3.14159

# Redondeo integrado

round(pi)

3

# Redondear al suelo o al techo

math.floor(pi)

3

math.floor(3.99)

3

math.ceil(pi)

4

math.ceil(3.01)

4

# Valor Absoluto : La distancia entre el número y el 0

abs(-10)

10

# Sumatorio integrado
n = [0.9999999, 1, 2, 3]
sum(n)

6.999999900000001

# Sumatorio mejorado para números reales
math.fsum(n)

6.9999999

# Truncamiento

math.trunc(123.45) # Truncar, cortar la parte decimal

123

# Potencia y raíces

math.pow(2, 3) # Potencia con flotante

8.0

2 ** 3 # Potencia directa

8

math.sqrt(9) # Raíz cuadrada (square root)

3.0

# Constantes

math.pi # Constante pi

3.141592653589793

math.e # Constante e

2.718281828459045

8. Módulo Random

import random

random.random() # Mayor o igual que 0 y menor que 1.0

0.22646853912351683

random.uniform(1,10) # Mayor o igual que 1 y menor que 10.0

7.261887494395041

random.randrange(10) # Mayor o igual que 0 y menor que 10

9

random.randrange(0,101, 2) # Saldría un número múltiple de 2

22

random.randrange(0, 101, 5 # Múltiples de 5

# Cadenas

c = “Hello World”

random.choice(c)

‘l’

l = [1,2,3,4,5]

random.choice(l)

1

# Barajar los elementos aleatoriamente, quedando guardada

random.shuffle(l)

l

[4, 1, 5, 3, 2]

# Devolver 3 elementos aleatorios de la lista

random.sample(l, 3)

[5, 3, 2]

 

Autor entrada: CharlieJ

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *