Funciones
Contents
Funciones#
Las funciones son objetos que permiten realizar tareas específicas de una manera más ordenada, sin hacer copias innecesarias del código. Esto facilita enormemente el mantenimiento del código.
Funciones como objetos#
En Python las funciones también son objetos, que pueden, por ejemplo,
copiarse
ser miembro de una colección (lista, tupla, diccionario)
pasarse como un argumento de otra función
type(max)
builtin_function_or_method
ser miembro de una colección#
from math import sin, cos, tan, pi
𝜋 = pi
trigonometricas = (sin, cos, tan)
[f(𝜋/3) for f in trigonometricas]
[0.8660254037844386, 0.5000000000000001, 1.7320508075688767]
copiarse#
coseno = cos
coseno(𝜋/3)
0.5000000000000001
pasarse como argumento de otra función#
from scipy import integrate
integrate.quad(cos, 0, 𝜋/2)[0]
0.9999999999999999
Definiendo funciones#
Una función se crea usando la palabra clave def
(definition) seguida de un nombre de su escogencia y paréntesis ( )
.
El programador puede escoger cualquier nombre para una función, excepto las palabras claves de Python y el nombre de funciones integradas existentes.
Esta línea debe terminar con un :
, luego deben seguir las instrucciones que la función ejecuta cuando es llamada, en líneas indentadas.
Por tanto, la sintaxis se ve así:
def function-name( ):
statements-to-be-executed
statements-to-be-executed
Para averiguar las palabras claves de Python:
import keyword
print(keyword.kwlist)
['False', 'None', 'True', '__peg_parser__', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
Una función sin argumentos#
def hello( ):
print('Hello')
print('Welcome to the UCR!')
Para correr esta función
hello()
Hello
Welcome to the UCR!
saludar = hello
saludar()
Hello
Welcome to the UCR!
Una función con argumentos#
Supongamos que deseamos escribir una función para convertir un dato de temperatura de Celsius a Fahrenheit. Para ello, sabemos que: $\(F = \tfrac{9}{5}C + 32 = 1.8C + 32\)$
def c2f(c):
f = 1.8 * c + 32
print(f'{c:.1f}° Celsius es igual a {f:.1f}° Fahrenheit')
c2f(15)
15.0° Celsius es igual a 59.0° Fahrenheit
y = c2f(100)
100.0° Celsius es igual a 212.0° Fahrenheit
type(y)
NoneType
Una función con parámetros predeterminados#
def c2f(c, *, mayuscula=False, mostrar=False):
f = 1.8 * c + 32
if mostrar:
if mayuscula:
print(f'{c:.1f}° CELSIUS = {f:.1f} FAHRENHEIT')
else:
print(f'{c:.1f}° Celsius = {f:.1f} Fahrenheit')
return f
c2f(15)
59.0
c2f(15, mostrar=True, mayuscula=True)
15.0° CELSIUS = 59.0 FAHRENHEIT
59.0
c2f(15, mostrar=True)
15.0° Celsius = 59.0 Fahrenheit
59.0
Una función con un número indefinido de parámetros posicionales#
Supongamos que queremos escribir una función que dependa de un número indefinido de parámetros. Por ejemplo, la función print
imprime un número arbitrario de elementos:
print(3, 4, 6)
3 4 6
print(5,3,7,1,"perro")
5 3 7 1 perro
Claramente no sería práctico hacer una función distinta para cada posible número de argumentos. Para ello utilizamos *args
(arguments) en la definición de la función. Por ejemplo, para escribir una operación de suma:
def imprimir_suma(*args):
numeros = (str(x) for x in args)
sumando = ' + '.join(numeros)
resultado = sum(args)
print(sumando, " = ", resultado)
print(f'\nEjecutando imprimir_suma con args = ', args, sep='\n')
print(f'\nEjecutando imprimir suma con *args = ', *args, sep='\n')
imprimir_suma(3,2,5)
3 + 2 + 5 = 10
Ejecutando imprimir_suma con args =
(3, 2, 5)
Ejecutando imprimir suma con *args =
3
2
5
imprimir_suma(1,1,1,1,1)
1 + 1 + 1 + 1 + 1 = 5
Ejecutando imprimir_suma con args =
(1, 1, 1, 1, 1)
Ejecutando imprimir suma con *args =
1
1
1
1
1
Vemos que a lo interno de la función, args
es una tupla, mientras que *args
son los elementos individuales de esa tupla.
Una función con un número indefinido de parámetros de palabra clave#
Supongamos que queremos escribir una función que dependa de un número indefinido de parámetros de palabras clave (usualmente para especificar opciones). Para ello, agrupamos esos parámetros en la variable **kwargs
(keyword arguments)
def imprimir_opciones(**kwargs):
for parametro, valor in kwargs.items():
print(parametro, " = ", valor)
print(f'\nEjecutando imprimir_suma con kargs = ', kwargs, sep='\n')
imprimir_opciones(color='rojo', modelo='2018', marca='Honda', estilo='SUV')
color = rojo
modelo = 2018
marca = Honda
estilo = SUV
Ejecutando imprimir_suma con kargs =
{'color': 'rojo', 'modelo': '2018', 'marca': 'Honda', 'estilo': 'SUV'}
Vemos que a lo interno de la función, **kwargs
es un diccionario. Esta característica de Python es muy útil para fijar un grupo de opciones en un diccionario y pasarlas repetidamente a funciones. Por ejemplo, la función print
separa elementos con un espacio y termina la operación con un salto de linea:
?print
Docstring:
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
Type: builtin_function_or_method
Podemos cambiar estos valores repetidamente así:
print(1,2,3)
print(4,5,6)
1 2 3
4 5 6
OPCIONES = {'sep': ' /*\ ', 'end': '\n\n'}
print(1,2,3, **OPCIONES)
print(4,5,6, **OPCIONES)
1 /*\ 2 /*\ 3
4 /*\ 5 /*\ 6
print(3,2,5, OPCIONES)
3 2 5 {'sep': ' /*\\ ', 'end': '\n\n'}
En la práctica, podemos combinar ambas características:
def imprimir_operacion(*numeros, **print_options):
print('Sin tomar en cuenta las opciones, la tupla de números es ')
print(*numeros)
print('pero tomando en cuenta las opciones, la tupla de números es ')
print(*numeros, **print_options)
imprimir_operacion(2,5,3,6,8,1)
Sin tomar en cuenta las opciones, la tupla de números es
2 5 3 6 8 1
pero tomando en cuenta las opciones, la tupla de números es
2 5 3 6 8 1
OPCIONES = dict(sep = ' * ', end = ' = ¿quién sabe?!!\n')
imprimir_operacion(2,5,3,6,8,1, **OPCIONES)
Sin tomar en cuenta las opciones, la tupla de números es
2 5 3 6 8 1
pero tomando en cuenta las opciones, la tupla de números es
2 * 5 * 3 * 6 * 8 * 1 = ¿quién sabe?!!
Vemos que lo importante de *args
y **kwargs
es el número de asteriscos, no el nombre mismo de la variable.
Documentando una función#
¡Es muy importante documentar lo que hace su código!
def c2f(c, show=False):
"""
Convierte dato de temperatura de grados Celsius a grados Fahrenheit
Parámetros:
c: un número escalar, grados en Celsius
show: un boolean, imprime el resultado si `True`
Resultado:
un número escalar, grados en Fahrenheit
Ejemplo:
c2f(0) # da 32.0 por resultado
"""
f = 1.8 * c + 32
if show:
print(f'{c:.1f}° Celsius = {f:.1f} Fahrenheit')
return f
z = c2f(15)
help(c2f)
Help on function c2f in module __main__:
c2f(c, show=False)
Convierte dato de temperatura de grados Celsius a grados Fahrenheit
Parámetros:
c: un número escalar, grados en Celsius
show: un boolean, imprime el resultado si `True`
Resultado:
un número escalar, grados en Fahrenheit
Ejemplo:
c2f(0) # da 32.0 por resultado
?c2f
Signature: c2f(c, show=False)
Docstring:
Convierte dato de temperatura de grados Celsius a grados Fahrenheit
Parámetros:
c: un número escalar, grados en Celsius
show: un boolean, imprime el resultado si `True`
Resultado:
un número escalar, grados en Fahrenheit
Ejemplo:
c2f(0) # da 32.0 por resultado
File: c:\users\randa\appdata\local\temp\ipykernel_8000\3486068780.py
Type: function
Entendiendo el ámbito de una variable#
Cuando una función encuentra una variable dentro de su definición que no hay sido definida dentro de la función, buscará su definición en el ambiente donde la función fue definida.
pi = 3.1415
def area(r):
A = pi * r**2
return A
pi
3.1415
print(area(10))
314.15000000000003
La siguiente línea da un error, porque A
es una variable definida a lo interno de la función area
, por lo que no es visible desde “fuera” de la función:
print(A)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_8000/212384544.py in <module>
----> 1 print(A)
NameError: name 'A' is not defined
Ahora cambiamos el valor de pi
, y ejectamos area
de nuevo:
pi = 9
area(10)
900
Vemos que el resultado cambia!!! Esto se debe a que la función area
busca el valor de pi
cada vez que es ejecutada, no al momento de definir la función.