Módulos de Python3

En los capítulos anteriores, básicamente hemos programado con el intérprete de Python. Si sales del intérprete de Python y vuelves a entrar, todos los métodos y variables que hayas definido desaparecen.

Para ello, Python proporciona una solución: almacenar estas definiciones en archivos para usarlas en algunos scripts o en instancias interactivas del intérprete. Este archivo se denomina módulo.

Un módulo en Python es un archivo que contiene definiciones y sentencias de Python. El nombre del archivo es el nombre del módulo más el.pysufijo.

Los módulos pueden contener funciones, clases, variables y código ejecutable. Mediante los módulos, podemos organizar el código en unidades reutilizables, lo que facilita su gestión y mantenimiento.

La función de los módulos

  • Reutilización de código: encapsular las funciones de uso común en módulos permite reutilizarlas en varios programas.

  • Gestión de espacios de nombres: los módulos evitan conflictos de nombres; las funciones o variables con el mismo nombre en diferentes módulos no interfieren entre sí.

  • Organización del código: dividir el código en diferentes módulos según su funcionalidad hace que la estructura del programa sea más clara.

A continuación se muestra un ejemplo del uso de un módulo de la biblioteca estándar de Python.

Ejemplo (Python 3.0+)

#!/usr/bin/python3 # Nombre de archivo: using_sys.py import sys print('Los argumentos de la línea de comandos son:') for i in sys.argv: print(i) print('\n\nLa ruta de Python es:', sys.path, '\n')

El resultado de la ejecución es el siguiente:

$ python using_sys.py 参数1 参数2
命令行参数如下:
using_sys.py
参数1
参数2


Python 路径为: ['/root', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages'] 

  • 1. `import sys` importa el módulo `sys.py` de la biblioteca estándar de Python; esta es la forma de importar un módulo.
  • 2. `sys.argv` es una lista que contiene los argumentos de la línea de comandos.
  • 3. `sys.path` contiene una lista de rutas que el intérprete de Python busca automáticamente para encontrar los módulos necesarios.

La sentencia import

Para usar un archivo fuente de Python, solo necesitas ejecutar la sentencia `import` en otro archivo fuente, con la siguiente sintaxis:

import module1[, module2[,... moduleN]

Cuando el intérprete encuentra una sentencia `import`, el módulo se importa si está en la ruta de búsqueda actual.

La ruta de búsqueda es una lista de todos los directorios que un intérprete buscará en primer lugar. Si quieres importar el módulo `support`, coloca el comando en la parte superior del script:

Código del archivo support.py

#!/usr/bin/python3 # Filename: support.py def print_func( par ): print ("Hello : ", par) return

test.py importa el módulo `support`:

Código del archivo test.py

#!/usr/bin/python3 # Filename: test.py # Importar el módulo import support # Ahora se pueden llamar las funciones contenidas en el módulo support.print_func("Ejemplo")

El resultado del ejemplo anterior es:

$ python3 test.py 
Hello :  Ejemplo

Descargar código

Un módulo solo se importa una vez, sin importar cuántas veces lo ejecutesimport. Esto evita que el módulo importado se ejecute una y otra vez.

Cuando usamos la sentencia `import`, ¿cómo encuentra el intérprete de Python el archivo correspondiente?

Esto implica la ruta de búsqueda de Python. La ruta de búsqueda está compuesta por una serie de nombres de directorios, y el intérprete de Python busca los módulos importados en esos directorios sucesivamente.

Ruta de búsqueda de los módulos

Al importar un módulo, Python lo busca en el siguiente orden:

  1. El directorio actual.

  2. Variables de entornoPYTHONPATHDirectorios especificados.

  3. Directorio de la biblioteca estándar de Python.

  4. .pthDirectorio especificado en el archivo.

La ruta de búsqueda se determina durante la compilación o instalación de Python; instalar nuevas bibliotecas también debería modificarla. La ruta de búsqueda se almacena en la variable `path` del módulo `sys`. Haz un experimento sencillo: en el intérprete interactivo, ingresa el siguiente código:

>>> import sys
>>> sys.path
['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
>>> 

`sys.path` genera una lista, cuyo primer elemento es una cadena vacía `''`, que representa el directorio actual (si se imprime desde un script, se puede ver más claramente qué directorio es), es decir, el directorio desde el que ejecutamos el intérprete de Python (para un script, es el directorio donde se encuentra el script en ejecución).

Por lo tanto, si, como en mi caso, existe un archivo con el mismo nombre que el módulo que se desea importar en el directorio actual, este archivo ocultará el módulo que se va a importar.

Una vez entendido el concepto de ruta de búsqueda, se puede modificar en el scriptsys.pathpara importar módulos que no están en la ruta de búsqueda.

Ahora, crea un archivo `fibo.py` en el directorio actual del intérprete o en un directorio de `sys.path`, con el siguiente código:

Ejemplo

# Módulo de la secuencia de Fibonacci def fib(n): # Define la secuencia de Fibonacci hasta n a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a+b print() def fib2(n): # Devuelve la secuencia de Fibonacci hasta n result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result

Luego entra al intérprete de Python y usa el siguiente comando para importar este módulo:

>>> import fibo

Esto no escribe los nombres de las funciones definidas directamente en `fibo` en la tabla de símbolos actual; solo escribe el nombre del módulo `fibo` allí.

Puedes usar el nombre del módulo para acceder a las funciones:

Ejemplo

>>>fibo.fib(1000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 >>> fibo.fib2(100) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] >>> fibo.__name__ 'fibo'

Si tienes la intención de usar una función con frecuencia, puedes asignarla a un nombre local:

>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377


La sentencia from … import

La sentencia `from` de Python te permite importar una parte específica de un módulo al espacio de nombres actual, con la siguiente sintaxis:

from modname import name1[, name2[, ... nameN]]

Por ejemplo, para importar la función `fib` del módulo `fibo`, usa la siguiente sentencia:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Esta declaración no importa todo el módulo `fibo` al espacio de nombres actual; solo introduce la función `fib` de `fibo`.

Poner alias a los módulos

Usaasla palabra clave para asignar un alias a módulos o funciones:

import numpy as np  # 将 numpy 模块别名设置为 np
from math import sqrt as square_root  # 将 sqrt 函数别名设置为 square_root


La sentencia from … import *

También es posible importar todo el contenido de un módulo al espacio de nombres actual, simplemente usando la siguiente declaración:

from modname import *

Esto proporciona una forma sencilla de importar todos los elementos de un módulo.

No se recomienda, ya que puede causar conflictos de nombres.


Profundizando en los módulos

Además de las definiciones de funciones, un módulo puede incluir código ejecutable. Este código se usa generalmente para inicializar el módulo. Este código solo se ejecuta la primera vez que se importa.

Cada módulo tiene su propia tabla de símbolos independiente, que se utiliza como tabla de símbolos global para todas las funciones dentro del módulo.

Por lo tanto, el autor del módulo puede usar estas variables globales con total tranquilidad, sin preocuparse por mezclarlas con las variables globales de otros usuarios.

Por otro lado, cuando realmente sabes lo que estás haciendo, también puedes acceder a las funciones del módulo mediante una notación como `modname.itemname`.

Los módulos pueden importar otros módulos. Se usa `import` al principio de un módulo (o script, o en otro lugar) para importar un módulo; por supuesto, esto es solo una convención, no una obligación. El nombre del módulo importado se colocará en la tabla de símbolos del módulo actualmente en operación.

También hay un método de importación: se puede usar `from ... import` para importar directamente los nombres (funciones, variables) del módulo al módulo actualmente en operación. Por ejemplo:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Este método de importación no coloca el nombre del módulo importado en la tabla de símbolos actual (por lo que, en este ejemplo, el nombre `fibo` no está definido).

Existe otro método que puede importar de una sola vez todos los nombres (funciones, variables) del módulo a la tabla de símbolos del módulo actual:

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Esto importará todos los nombres, pero aquellos que comiencen con un guion bajo simple (`_`) no se incluyen. En la mayoría de los casos, los programadores de Python no usan este método, porque los nombres introducidos de otras fuentes pueden sobrescribir definiciones existentes.


El atributo `__name__`

Cuando un módulo es importado por primera vez por otro programa, su programa principal se ejecutará.

Si queremos que un bloque de código del módulo no se ejecute cuando el módulo sea importado, podemos usar el__name__atributo `__name__` para que ese bloque de código solo se ejecute cuando el módulo se ejecute por sí mismo.

#!/usr/bin/python3
# Filename: using_name.py

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')

La salida de la ejecución es la siguiente:

$ python using_name.py
程序自身在运行
$ python
>>> import using_name
我来自另一模块
>>>

Nota: cada módulo tiene un atributo `__name__`.

  • Si el módulo se ejecuta directamente,__name__el valor de `__name__` es__main__。

  • Si el módulo es importado,__name__el valor de `__name__` es el nombre del módulo.

Nota:__name__y__main__Son dos guiones bajos,_ _y así se elimina el espacio en el medio.


La función dir()

La función incorporada `dir()` puede encontrar todos los nombres definidos en un módulo. Devuelve una lista de cadenas:

>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
 '__package__', '__stderr__', '__stdin__', '__stdout__',
 '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
 '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
 'call_tracing', 'callstats', 'copyright', 'displayhook',
 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
 'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
 'thread_info', 'version', 'version_info', 'warnoptions']

Si no se le da ningún argumento, la función dir() listará todos los nombres definidos actualmente:

>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir() # 得到一个当前模块中定义的属性列表
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
>>> a = 5 # 建立一个新的变量 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a # 删除变量名a
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']
>>>

Módulos estándar

Python incluye algunos módulos de biblioteca estándar, que se presentarán en la documentación de referencia de la biblioteca de Python (es decir, la "documentación de referencia de la biblioteca" más adelante).

Nombre del móduloDescripción de la funcionalidad
mathOperaciones matemáticas (como raíz cuadrada, funciones trigonométricas, etc.)
osFunciones relacionadas con el sistema operativo (como operaciones con archivos y directorios)
sysParámetros y funciones relacionados con el sistema
randomGeneración de números aleatorios
datetimeManejo de fechas y horas
jsonProcesamiento de datos JSON
reOperaciones con expresiones regulares
collectionsProporciona estructuras de datos adicionales (como defaultdict, deque)
itertoolsProporciona herramientas de iteradores
functoolsHerramientas de funciones de orden superior (como reduce, lru_cache)

Algunos módulos están construidos directamente en el intérprete. Aunque no son funciones integradas del lenguaje, pueden usarse de manera muy eficiente, incluso para llamadas a nivel de sistema.

Estos componentes se configuran de diferentes formas según el sistema operativo. Por ejemplo, el módulo winreg solo está disponible en sistemas Windows.

Debe notarse que hay un módulo especial, sys, que está integrado en cada intérprete de Python. Las variables sys.ps1 y sys.ps2 definen las cadenas correspondientes al indicador principal y al indicador secundario:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Ejemplo!')
Ejemplo!
C> 

Paquete

Un paquete es una forma de gestionar el espacio de nombres de los módulos de Python, utilizando "nombres de módulo con puntos".

Por ejemplo, si el nombre de un módulo es A.B, entonces representa el submódulo B dentro del paquete A.

Así como al usar módulos no te preocupas de que las variables globales de diferentes módulos se afecten entre sí, con la forma de nombres de módulo con puntos tampoco debes preocuparte por la duplicación de nombres de módulos entre diferentes bibliotecas.

De esta manera, diferentes autores pueden proporcionar módulos NumPy, o bibliotecas gráficas de Python.

Supongamos que quieres diseñar un conjunto de módulos para manejar de manera unificada archivos y datos de audio (o llámalo un "paquete").

Existen muchos formatos de archivos de audio (básicamente se distinguen por su extensión, por ejemplo: .wav, :file:.aiff, :file:.au,), por lo que necesitas un conjunto cada vez mayor de módulos para convertir entre diferentes formatos.

Y además, para estos datos de audio, hay muchas operaciones diferentes (como mezclar, añadir eco, agregar funciones de ecualizador, crear efectos de sonido estereofónico artificial), así que también necesitas un conjunto interminable de módulos para manejar estas operaciones.

Aquí se muestra una posible estructura de paquete (en un sistema de archivos jerárquico):

sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

Al importar un paquete, Python busca los subdirectorios contenidos en el paquete según los directorios en sys.path.

Un directorio solo se considera un paquete si contiene un archivo llamado __init__.py, principalmente para evitar que algunos nombres demasiado comunes (como string) afecten inadvertidamente a los módulos válidos en la ruta de búsqueda.

En el caso más simple, basta con poner un :file:__init__.py vacío. Por supuesto, este archivo también puede contener código de inicialización o asignar un valor a la variable __all__ (que se presentará más adelante).

El usuario puede importar solo un módulo específico de un paquete cada vez, por ejemplo:

import sound.effects.echo

Esto importará el submódulo: sound.effects.echo. Debe usar el nombre completo para acceder a él:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

Otra forma de importar un submódulo es:

from sound.effects import echo

Esto también importará el submódulo: echo, y no necesita esos prefijos largos, por lo que puede usarse así:

echo.echofilter(input, output, delay=0.7, atten=4)

Otra variante es importar directamente una función o variable:

from sound.effects.echo import echofilter

Del mismo modo, este método importará el submódulo: echo, y puede usar directamente su función echofilter():

echofilter(input, output, delay=0.7, atten=4)

Ten en cuenta que al usarfrom package import itemcon esta forma, el item correspondiente puede ser un submódulo (subpaquete) dentro del paquete, u otros nombres definidos en el paquete, como funciones, clases o variables.

La sintaxis de import primero tratará a item como un nombre definido en el paquete; si no lo encuentra, intentará importarlo como un módulo. Si aún no lo encuentra, lanzará una:exc:ImportErrorexcepción.

Por el contrario, si se usa una forma comoimport item.subitem.subsubitemEn esta forma de importación, todos los elementos excepto el último deben ser paquetes, y el último puede ser un módulo o un paquete, pero no puede ser el nombre de una clase, función o variable.


Importar * desde un paquete

Si usamosfrom sound.effects import *¿qué sucederá?

Python entrará en el sistema de archivos, encontrará todos los submódulos dentro de este paquete y los importará uno por uno.

Pero este método no funciona muy bien en la plataforma Windows, porque Windows es un sistema que no distingue entre mayúsculas y minúsculas.

En la plataforma Windows, no podemos determinar si un archivo llamado ECHO.py se importa como módulo echo, Echo o ECHO.

Para resolver este problema, solo necesitamos proporcionar un índice exacto del paquete.

La declaración de importación sigue la siguiente regla: si el archivo de definición del paquete __init__.pycontiene una variable de lista llamada__all__entonces al usarfrom package import *se importarán todos los nombres de esa lista como contenido del paquete.

Como autor del paquete, no olvides asegurarte de que__all__también se actualice.

El siguiente ejemplo contiene el siguiente código en file:sounds/effects/__init__.py:

__all__ = ["echo", "surround", "reverse"]

Esto significa que cuando uses from sound.effects import *, solo importarás estos tres submódulos del paquete.

Si__all__realmente no está definido, entonces al usarfrom sound.effects import *con esta sintaxis, no se importará ningún submódulo del paquete sound.effects. Solo importará el paquete sound.effects y todo el contenido definido en él (posiblemente ejecutando el código de inicialización definido en __init__.py).

Esto importará todos los nombres definidos en __init__.py. Y no destruirá los módulos explícitamente especificados que importamos antes de esta declaración. Veamos esta parte del código:

import sound.effects.echo
import sound.effects.surround
from sound.effects import *

En este ejemplo, antes de ejecutar from...import, los módulos echo y surround del paquete sound.effects ya se importaron al espacio de nombres actual. (Por supuesto, si se define __all__, no hay problema)

Generalmente no recomendamos usar*este método para importar módulos, porque este método a menudo reduce la legibilidad del código. Sin embargo, ciertamente ahorra bastante tecleo, y algunos módulos están diseñados para importarse solo mediante métodos específicos.

Recuerda, usarfrom Package import specific_submoduleeste método nunca está mal. De hecho, es el método recomendado. A menos que el submódulo que quieras importar pueda tener el mismo nombre que un submódulo de otro paquete.

Si en la estructura el paquete es un subpaquete (como en este ejemplo para el paquete sound), y quieres importar paquetes hermanos (paquetes al mismo nivel), debes usar rutas absolutas para importar. Por ejemplo, si el módulo sound.filters.vocoder quiere usar el módulo echo del paquete sound.effects, debes escribir from sound.effects import echo.

from . import echo
from .. import formats
from ..filters import equalizer

Tanto las importaciones relativas implícitas como las explícitas comienzan desde el módulo actual. El nombre del módulo principal siempre es "__main__"; el módulo principal de una aplicación de Python siempre debe ser referenciado usando rutas absolutas.

El paquete también proporciona un atributo adicional __path__. Esta es una lista de directorios, donde cada directorio incluido tiene un __init__.py que sirve a este paquete; debes definirlo antes de que otros __init__.py se ejecuten. Esta variable se puede modificar para afectar a los módulos y subpaquetes contenidos en el paquete.

Esta funcionalidad no se usa con frecuencia; generalmente se utiliza para extender los módulos dentro de un paquete.

Otras extensiones