PDF de programación - Separar el código en partes

Imágen de pdf Separar el código en partes

Separar el código en partesgráfica de visualizaciones

Publicado el 31 de Agosto del 2020
1.256 visualizaciones desde el 31 de Agosto del 2020
1,1 MB
35 paginas
Creado hace 3a (22/07/2020)
Separar el código en partes

22 de julio de 2020

Una piedra angular del código claro es la división de sus diversas tareas en
piezas pequeñas y manejables. El código claro requiere que tengas menos
conocimiento en tu cabeza en cualquier momento dado, lo que hace que el
código sea más fácil de razonar. Los segmentos cortos de código con una
intención clara son un gran paso en esta dirección, pero los bits de código
no deben dividirse a lo largo de límites arbitrarios.

En este texto, analizaré las herramientas integradas en Python para sepa-
rar de manera lógica y coherente su código en partes más manejables, así
como la filosofía que se necesita para decidir cómo y cuándo usarlas.

1. Espacio de nombres

Al igual que muchos lenguajes de programación, Python aísla el código
a través del concepto de espacios de nombres. A medida que se ejecuta
un programa, realiza un seguimiento de todos los espacios de nombres
conocidos y la información disponible en esos espacios de nombres.

Los espacios de nombres son útiles de varias maneras:

A medida que el software crece, múltiples conceptos necesitarán nombres
similares o idénticos. Los espacios de nombres ayudan a minimizar las co-
lisiones, por lo que queda claro a qué concepto se refiere un nombre. A

1

medida que el software crece, se vuelve exponencialmente más difícil sa-
ber qué código ya está presente en la base. Los espacios de nombres lo
ayudan a hacer conjeturas informadas sobre dónde podría vivir el código,
si es que existe. Al agregar un nuevo código a una base de código grande,
los espacios de nombres existentes pueden guiar dónde debería vivir el
nuevo código. Si no existe una opción obvia, un nuevo espacio de nombres
podría ser apropiado.

Los espacios de nombres son tan importantes, de hecho, que se incluyen
como la última declaración en "The Zen of Python":

Los espacios de nombres son una gran idea, ¡hagamos más de

eso!

El zen de Python

Los nombres de todas las variables, funciones y clases que ha usado en
Python fueron nombres en un espacio de nombres u otro. Los nombres, co-
mo x o total o EssentialBusinessDomainObject, son referencias a algo.
Cuando su código de Python dice x = 3, significa "asignar el valor 3 al nom-
bre x", y luego puede hacer referencia a x en su código. Una "variable" es
un nombre que se refiere a un valor, aunque los nombres pueden referirse
a funciones, clases y más en Python.

1.1. Espacios de nombres y la declaración de

importación

Cuando abre por primera vez el intérprete de Python, el espacio de nom-
bres incorporado se completa con todas las cosas integradas en Python.
Este espacio de nombres contiene funciones integradas como print() y
open(). Estas funciones incorporadas no tienen prefijo y no necesita hacer
nada especial para usarlas. Python los pone a su disposición en cualquier
parte de su código. Es por eso que la famosa print(’¡Hola, mundo!’)
funciona sin más en Python.

2

A diferencia de algunos idiomas, no creará explícitamente espacios de nom-
bres en su código Python, pero su estructura de código afectará qué espa-
cios de nombres se crean y cómo interactúan. Como ejemplo, la creación
de un módulo de Python crea automáticamente un espacio de nombres
adicional para ese módulo. En su forma más simple, un módulo de Pyt-
hon es un fichero .py que contiene algo de código. Un fichero llamado
sales_tax.py, por ejemplo, es "el módulo sales_tax":

# sales_tax.py

def add_sales_tax(total, tax_rate):

return total * tax_rate

Cada módulo tiene un espacio de nombres global, al que puede acceder
libremente el código del módulo. Las funciones, clases y variables que no
están anidadas dentro de nada están en el espacio de nombres global del
módulo:

# sales_tax.py

# Ref_1
TAX_RATES_BY_STATE = {

’MI’: 1.06,
# ...

}

# Ref_2
def add_sales_tax(total, state):

return total * TAX_RATES_BY_STATE[state]

Ref_1 TAX_RATES_BY_STATE está en el espacio de nombres global del mó-

dulo.

Ref_2 El código en el módulo puede usar TAX_RATES_BY_STATE sin ningún

problema.

3

Las funciones y clases en un módulo también tienen un espacio de nombres
local al que solo ellos pueden acceder:

# sales_tax.py

TAX_RATES_BY_STATE = {

’MI’: 1.06,
...

}

def add_sales_tax(total, state):

# Ref_1

tax_rate = TAX_RATES_BY_STATE[state]

# Ref_2

return total * tax_rate

Ref_1 tax_rate solo está en el ámbito local para add_sales_tax().

Ref_2 El código en add_sales_tax() puede usar tax_rate sin ningún pro-

blema.

Un módulo que quiera usar una variable, función o clase de otro módulo
debe importarlo a su espacio de nombres global. Importar es una forma de
extraer un nombre de otro lugar en el espacio de nombres deseado.

# receipt.py

# Ref_1
from sales_tax import add_sales_tax

def print_receipt():

total = ...
state = ...
print(f’TOTAL: {total}’)

# Ref_2

print(f’AFTER TAX: {add_sales_tax(total, state)}’)

4

Ref_1 La función add_sales_tax se agrega al espacio de nombres global

del recibo.

Ref_2 add_sales_tax todavía sabe acerca de TAX_RATES_BY_STATE y tax_rate

de su propio espacio de nombres.

Entonces, para referirse a una variable, función o clase en Python, uno de
los siguientes debe ser verdadero:

El nombre está en el espacio de nombres incorporado de Python.

El nombre es el espacio de nombres global del módulo actual.

El nombre está en la línea actual del espacio de nombres local del
código.

La precedencia de los nombres en conflicto funciona en el orden opuesto:
un nombre local anulará un nombre global, que anulará un nombre incor-
porado. Puede recordar esto porque generalmente la definición más espe-
cífica del código actual es la que se utiliza. Esto se muestra en la figura
1.

Es posible que haya visto un error NameError: name ’my_var’ is not
defined en algún momento de sus aventuras con Python. Eso significa que
el nombre my_var no se encontró en ninguno de los espacios de nombres
conocidos por ese código. Esto generalmente significa que nunca le asignó
a my_var un valor, o lo asignó a otro lugar y necesita importarlo.

Los módulos son una excelente manera de comenzar a dividir el código. Si
tiene un fichero largo script.py con un montón de funciones no relaciona-
das, considere dividir esas funciones en módulos.

1.2. Las muchas máscaras de importación

La sintaxis para importar en Python parece sencilla al principio, pero hay
algunas maneras de hacerlo, y cada una produce diferencias sutiles en la
información que se introduce en el espacio de nombres. Anteriormente,

5

Figura 1: Especificidad de los espacios de nombres

importó la función add_sales_tax() del módulo sales_tax al módulo de
recibo:

# receipt.py

from sales_tax import add_sales_tax

Esto agrega la función add_sales_tax() al espacio de nombres global del
módulo de recibo. Eso está muy bien, pero supongamos que agrega diez
funciones más al módulo sales_tax y desea utilizarlas todas como recibo.
Si continúa por el mismo camino, terminará con algo como esto:

# receipt.py

from sales_tax import add_sales_tax, add_state_tax,

add_city_tax,

6

add_local_millage_tax, ...

Hay una sintaxis alternativa que mejora un poco esto:

# receipt.py

from sales_tax import (

add_sales_tax,
add_state_tax,
add_city_tax,
add_local_millage_tax,
...

)

Todavía no es genial. Cuando necesite una gran cantidad de funcionalida-
des de otro módulo, puede importar ese módulo completo en su lugar:

# receipt.py

import sales_tax

Esto agrega todo el módulo sales_tax al espacio de nombres actual, y sus
funciones se pueden referenciar con sales_tax.prefijo:

# receipt.py

import sales_tax

def print_receipt():

total = ...
locale = ...
...
print(f’AFTER MILLAGE: {sales_tax.

add_local_millage_tax(total,

locale)}’)

7

Esto tiene el beneficio de evitar largas declaraciones de importación y, co-
mo verá en la siguiente sección, el prefijo ayuda a evitar colisiones en el
espacio de nombres.

Advertencia
Python le permite importar todos los nombres de un módulo en for-
ma abreviada usando from modulo import *. Es tentador usar es-
te formulario en lugar de prefijar esos nombres con el módulo a lo
largo de su código, ¡pero no lo haga! Estas importaciones de co-
modines pueden causar colisiones de nombres y dificultar la depu-
ración de problemas porque no puede ver los nombres específicos
que se importan. ¡Quédate con las importaciones explícitas!a

aImportar todo de una vez ahorra código y el espacio de nombres está mági-
camente (implícitamente) disponible. El problema es que eso sólo lo sabes
tú, y obligas a otras personas a rebuscar en módulos lejanos para tratar de
entender tu lógica ***Es mejor explícito que implícito***

1.3. Los espacios de nombres previenen colisiones

Si desea obtener la hora actual en un programa Python, puede hacerlo
importando la función time() desde el módulo de hora:

from time import time
print(time())

Debería ver una salida como esta:

1546021709.3412101

time() devuelve la hora actual de Unix1. El módulo de fecha y hora también
contiene algo con el nombre de la hora, pero hace algo diferente:

from datetime import time
print(time())

1Consulte el artículo de Wikipedia para obtener una explicación del tiempo de Unix:

https://es.wikipedia.org/wiki/Tiempo_Unix

8

Esta vez deberías ver esta salida:

00:00:00

Esta vez es en realidad una clase, y llamarla devuelve una instancia de
datetime.time que por defecto es medianoche (0 horas, 0 minutos, etc.).
¿Qué sucede cuando los importas a ambos?

from time import time
from datetime import time
# Ref_1
print(time())

Ref_1 ¿Qué hora es esta?

En casos de ambigüedad, Python usa la definición más reciente que cono-
ce.

Si importa time desde un lugar y luego importa otro time desde otro lugar,
solo sabrá sobre este último. Si no utiliza espacios de nombres, será difícil
saber a qué hora se hace referencia en el código, y puede usar el incorrec-
to por error. Esta es una razón convincente para importar módulos en su
conjunto; te obliga a prefijar nombres del módulo para que quede claro de
dónde provienen los nombres.

import t
  • Links de descarga
http://lwp-l.com/pdf18151

Comentarios de: Separar el código en partes (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad