Creació de les nostres pròpies funcions¶
Les funcions ens permeten re-utilitzar codi sense tenir que tornar a escriure’l i dividir el nostre programa en fragments de codi més menuts. Cada funció es farà càrrec d’una part del problema que volem solucionar amb el nostre programa.
Ja hem utilitzat i definit funcions amb Guido van Robot, utilitzant l’instrucció defineix
seguida del nom d’una nova instrucció, però les funcions de Python són molt més potents que les de Guido: poden rebre arguments i poden retornar un valor.
En l’exemple següent s’executa una funció anomenada sumaDosNombres()
a la qual se li passen dos paràmetres. Els paràmetres van dins dels parèntesis, separats per comes. La funció retorna un valor, que és emmagatzemat en la variable x.
x = sumaDosNombres(3, 5)
En Python les funcions es defineixen de la següent manera:
1def imprimeix(text, repeticions):
2 """Imprimeix el text del primer paràmetre
3 tantes vegades com indique el segon paràmetre
4
5 Paràmetres per nom:
6 text - String, amb el text a imprimir.
7 repeticions - Int, vegades que es repetirà el text."""
8
9 print(text * repeticions)
Observa que la funció comença amb un text entre triples cometes («»»). Aquest text s’anomena cadena de documentació (docstring) i serveix per explicar el funcionament de la funció. Encara que no és obligatori, documentar les nostres funcions d’aquesta manera és molt recomanable.
La funció d’exemple imprimeix()
necessita dos paràmetres per a funcionar: el text que imprimirà i el nombre de vegades que haurà de imprimir el text. Aquestos paràmetres es defineixen quan es declara la funció i apareixen entre parèntesis, separats per comes, després del nom de la funció. En el nostre exemple, la funció imprimeix()
defineix els paràmetres nom i repeticions. Quan escrivim una funció hem de pensar que aquestos paràmetres tindran assignat un valor qualsevol que no coneguem i que podrà ser diferent cada vegada que es cride la funció. Aquestos paràmetres es comportaran com variables internes a la funció, i que no existiran fora d’ella.
La manera d’utilitzar aquesta funció és la següent:
>>> imprimeix('A', 10)
AAAAAAAAAA
En aquest cas hem cridat la funció amb dos arguments. Els arguments són els valors concrets amb els quals es crida la funció i que seran assignats als paràmetres de la funció. Observa que quan es crida la funció els seus paràmetres prenen els valors text=”A” i repeticions=10. També podem utilitzar altres variables per a cridar la funció:
>>> t = 'AEIOU'
>>> n = 3
>>> imprimeix(t, n)
AEIOUAEIOUAEIOU
D’aquesta manera, quan es crida la funció, internament es fan les assignacions de valors text = t
i repeticions = n
. Cal insistir en que els paràmetres són variables que solament existeixen dins de la funció. Observa el següent exemple:
>>> def funcio(x):
nombre = x
doble_de_nombre = 2 * x
print('La variable \'nombre\' val {0}'.format(nombre))
print('La variable \'doble_de_nombre\' val {0}'.format(doble_de_nombre))
>>> nombre = 3
>>> funcio()
La variable 'nombre' val 5
La variable 'altre_nombre' val 10
>>> nombre
3
>>> altre_nombre
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
altre_nombre
NameError: name 'altre_nombre' is not defined
En l’exemple anterior es pot observar com la les variables nombre i altre_nombre que es creen dins de la funció no són accessibles des de fora de la funció, i com la modificació d’una variable global dins de la funció (amb l’ordre nombre = 5
) solament afecta dins de l’àmbit de la funció, i no a nivell global.
Els paràmetres de les nostres funcions poden tenir valors per defecte, que s’utilitzaran en el cas que no indiquem altra cosa. Per exemple:
1def imprimeix(text, repeticions = 1):
2 """Imprimeix el text del primer paràmetre
3 tantes vegades com indique el segon paràmetre.
4
5 Paràmetres per nom:
6 nom - String, amb el text a imprimir.
7 repeticions = 1 - Int, vegades que es repetirà el text."""
8
9print(text * repeticions)
Ara podem escriure una ordre com imprimeix('Hola', 5)
que imprimirà el text «Hola» cinc vegades i també imprimeix('Hola')
que l’imprimirà solament una. El argument amb el nombre de repeticions és, en aquesta funció, opcional.
Fins ara hem aprés a definir funcions que mostraven resultats per pantalla amb l’ordre print()
però en ocasions ens pot interessar que una funció ens retorne un valor. Per exemple, imagina que tenim una funció anomenada arrel_quadrada()
que calcula l’arrel d’un nombre. Si en un programa hem de fer càlculs aquesta funció ens pot ser útil, però no ens interessa que el resultat de l’arrel es mostre per pantalla, el que desitgem és que la funció ens retorne aquest valor.
Per a que una funció retorne un valor utilitzarem l’ordre return
. Per exemple, la següent funció retorna l’arrel quadrada del nombre que li donem com a paràmetre:
1def arrel_quadrada(x):
2 """Calcula l'arrel quadrada d'un nombre.
3
4 Paràmetres per nom:
5 x - Int, nombre del qual calculem l'arrel.
6
7 Retorna: Int
8 """
9
10 arrel = x**(1/2)
11 return arrel
Ara podem utilitzar aquesta funció escrivint, per exemple:
>>> nombre = arrel_quadrada(81)
>>> nombre
9.0
>>> nombre2 = arrel_quadrada(nombre)
>>> nombre2
3.0
>>> 3*arrel_quadrada(81)
27.0
És important entendre la diferència entre la sortida d’un programa (o una funció) i el seu valor de retorn. El primer pot ser, per exemple, la sortida estàndard amb l’ordre print()
, mentre que el segon és un valor que es retorna amb l’ordre return
per a que el programa el puga utilitzar. Observa l’exemple següent:
1#!/usr/bin/env python3
2# mitjana.py
3#
4# Calcula la mitjana de dos nombres.
5
6def mitjana(n1, n2):
7 """Retorna la mitjana de dos nombres.
8
9 Paràmetres per nom:
10 n1 - Int, nombre del qual es calcula la mitjana.
11 n2 - Int, nombre del qual es calcula la mitjana.
12
13 Retorna: Int
14 """
15
16 return (n1 + n2 ) / 2
17
18nombre1 = int(input('Escriu un nombre sencer: '))
19nombre2 = int(input('Escriu un nombre sencer: '))
20mitjana = mitjana(nombre1, nombre2)
21print('La mitjana és', mitjana)
Fixa’t en que totes les funcions retornen un valor: input() retorna una cadena de text escrita per l’usuari, int()
retorna un valor sencer i factorial()
retorna el factorial d’un nombre. Tots aquestos valors de retorn són utilitzats per el programa de diferents maneres (per exemple es poden passar a altra funció o ser emmagatzemats en una variable), mentre que quan utilitzem l’ordre print()
enviem alguna cosa a la sortida estàndard. Per exemple, a l’última línia del programa anterior enviem a la sortida estàndard el valor de retorn de la funció factorial()
.
Per cert: He dit ja que totes les funcions retornen un valor? Quan una funció conté una ordre return
, aquesta indicarà el valor a retornar, però si en una funció no està present aquesta ordre es retornarà el valor especial None
.
Quan executem una ordre return
en una funció açò suposa sempre el fi de la funció i la tornada al programa principal. En aquest sentit return
es pot utilitzar de la mateixa manera que break
dins dels bucles.