.. -*- rst -*- ======== Funcions ======== Concepte -------- - Anàleg al concepte de `funció `__ en matemàtiques (de moment) Ús ---- Funcions predefinides ~~~~~~~~~~~~~~~~~~~~~ - Una :term:`funció predefinida` és una :term:`funció` integrada a Python i disponible sense necessitat d\':term:`importar ` cap :term:`mòdul` - Per exemple: - Valor absolut: :py:func:`abs` - Conversió de tipus: :py:class:`float`, :py:class:`int` - Màxim i mínim: :py:func:`max`, :py:func:`min` - Arrodonir: :py:func:`round` - Tipus (o classe) d'un objecte (valor): :py:class:`type` - Escriure a la sortida: :py:func:`print` - Vegeu la llista completa a la secció :ref:`python:built-in-funcs` del manual :doc:`python:library/index` Crida d'una funció ~~~~~~~~~~~~~~~~~~ - Sintaxi de la :term:`crida` d'una :term:`funció`:: nom_de_la_funció(argument_1, argument_2, ...) - Els :term:`arguments ` són les dades a partir de les quals la funció calcula el resultat - Els arguments són :term:`expressions ` - La crida d'una funció és una expressió que s'avalua al valor descrit a la seva documentació (especificació) Mòduls ~~~~~~ - El :term:`mòdul` és la unitat d'organització del :term:`codi ` en Python - El mòduls contenen :term:`funcions ` i :term:`variables ` - Per cridar les funcions o usar les variables d'un mòdul, cal :term:`importar `-lo. Es pot fer de dues maneres: - Amb la sentència :code:`from` .. code-block:: python from nom_de_mòdul import funció_o_variable_1, funció_o_variable_2... Només es poden usar les funcions o variables de la llista amb la sintaxi :code:`funció_o_variable_1` - Amb la sentència :code:`import` .. code-block:: python import nom_de_mòdul Es pot usar qualsevol funció o variable definida en el mòdul amb la sintaxi :code:`nom_de_mòdul.funció_o_variable` - Exemples d'importació del mòdul :py:mod:`math` - Importar amb :code:`from`: >>> from math import sin, pi >>> r = sin(pi/2) >>> print(r) 1.0 - Importar amb :code:`import`: >>> import math >>> r = math.sin(math.pi/2) >>> print(r) 1.0 - La funció :py:func:`dir` llista els noms definits per un objecte Definició --------- - Permet posar nom al càlcul d'un resultat a partir d'unes dades (paràmetres) - Sintaxi de la :term:`definició d'una funció`: .. sourcecode:: python def nom_de_la_funció(llista_de_paràmetres): # capçalera sentències # cos return expressió # resultat - La :term:`sentència` :code:`def` és la :term:`capçalera` de la definició de la funció - La capçalera conté el nom de la funció i la llista de paràmetres - Un :term:`paràmetre` és una :term:`variable` que correspon a una de les dades nencessàries per tal de calcular el resultat - El cos és un bloc de :term:`codi ` format per una seqüència de sentències - El bloc s'escriu `sagnat `__ respecte de la capçalera - El resultat de la funció s'obté a l\':term:`avaluar ` l\':term:`expressió` de la sentència :code:`return` - Per exemple .. code-block:: python def recta(a, b, x): y = a*x + b return y - Escriurem la definició d'una funció en un :term:`mòdul` - Un fitxer amb `extensió `__ ``.py`` és un mòdul Flux d'execució de la crida d'una funció ---------------------------------------- - L'execució de la :term:`definició d'una funció` associa el nom a l'objecte funció: no altera el :term:`flux d'execució` - L'avaluació de la :term:`crida` d'una :term:`funció` durant l'avaluació d'una :term:`expressió` comporta: - Avaluar els arguments de la crida - Congelar l\':term:`estat` del `bloc d'activació `__ (`stack frame `__) actual - Crear el bloc d'activació de la funció a la `pila de crides `__ (`call stack `__) en què l'estat incial només conté els paràmetres - Cada :term:`paràmetre` fa referència a l\':term:`argument` que li correspon per posició - Executar les :term:`sentències ` del :term:`cos ` fins a trobar una sentència :code:`return` - L'execució d'una :term:`assignació` defineix una :term:`variable local` - Executar la sentència :code:`return` que implica: - Avaluar l'expressió - Destruir el bloc d'activació de la funció - Reprendre l'avaluació de l'expressió on hi ha la crida amb el valor retornat per la funció - Vegeu un exemple a `Online Python Tutor\: recta`_ - Quan es produeix un :term:`error d'execució`, l\':term:`intèrpret` mostra la traça de la pila de crides (*traceback* o `stack trace `__) +---------------------------------------+----------------------------------+ | >>> from funcions import f | .. literalinclude:: funcions.py | | >>> f() | :language: python3 | | Traceback (most recent call last): | :linenos: | | File "", line 1, in | :emphasize-lines: 4 | | File "funcions.py", line 4, in f | :lines: -4 | | return 1/0 | | | ~^~ | | | ZeroDivisionError: division by zero | | +---------------------------------------+----------------------------------+ - Descarregueu el mòdul :download:`funcions ` i proveu-lo .. _Online Python Tutor\: recta: http://pythontutor.com/visualize.html#code=def%20recta(a,%20b,%20x%29%3A%0A%20%20%20%20y%20%3D%20a*x%20%2B%20b%0A%20%20%20%20return%20y%0A%20%20%20%20%0Ax%20%3D%200%0Az%20%3D%20recta(3,%202,%20x%29%0Aprint(x,%20z%29%0A%0Ax%20%3D%201%0Az%20%3D%20recta(3,%202,%20x%29%0Aprint(x,%20z%29%0A&cumulative=false&curInstr=0&heapPrimitives=true&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false> Sentència ``return`` -------------------- - Les :term:`funcions ` sempre retornen un valor - En una sentència :code:`return` es pot ometre l\':term:`expressió` - Al :term:`cos d'una funció` pot haver-hi cap, una o més d'una sentències :code:`return` - La funció acaba quan executa la primera sentència :code:`return` o quan arriba al final del cos - Codi inassolible (`unreachable code `__): les sentències que hi hagi darrera d'una sentència :code:`return` no s'executaran mai El valor ``None`` de tipus ``Nonetype`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Quan una funció acaba perquè executa una sentència :code:`return` sense `expressió` o bé perquè arriba al final del cos, retorna el valor ``None`` de tipus ``Nonetype`` - Vegeu un exemple a `Online Python Tutor\: oblit`_ .. _Online Python Tutor\: oblit: http://pythontutor.com/visualize.html#code=%23%20Hem%20oblidat%20retornar%20un%20valor%0A%0Adef%20oblit(a,%20b%29%3A%0A%20%20%20%20c%20%3D%20a%20%2B%20b%0A%20%20%20%20%0Am%20%3D%20oblit(3,%202%29%0Aprint(m,%20type(m%29%29%0A&cumulative=false&curInstr=0&heapPrimitives=true&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false Funcions que retornen més d'un resultat ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - La sintaxi de la sentència :code:`return` quan la :term:`funció` calcula més d'un resultat és .. sourcecode:: python3 return expressió_1, expressió_2... - Per exemple >>> def segons_a_hms(s): ... h = s // 3600 ... s = s % 3600 ... m = s // 60 ... s = s % 60 ... return h, m, s >>> h1, m1, s1 = segons_a_hms(7854) >>> h1 2 >>> m1 10 >>> s1 54 >>> h1*3600 + m1*60 + s1 7854 Àmbit de visibilitat -------------------- - L\':term:`àmbit de visibilitat` d'una variable o funció és la regió del :term:`codi ` on és accessible. - Python defineix tres àmbits de visibilitat: - *global*: conté les funcions predefinides i són visibles a tot arreu - *mòdul*: conté les :term:`funcions ` i :term:`variables ` definides en un :term:`mòdul` i són visibles en el mòdul on s'han definit - *local*: conté els :term:`paràmetres ` i les :term:`variables locals ` definides al :term:`cos d'una funció` i només són visibles al cos de la funció. - Vegeu `àmbit de visibilitat en Python `__ a la Viquipèdia Crides entre funcions --------------------- - Al :term:`cos d'una funció` es pot cridar qualsevol - :term:`funció predefinida` - funció definida en el mateix :term:`mòdul` - funció definida en un mòdul que s'ha :term:`importat ` - Vegeu a l\'`Online Python Tutor\: geom`_ l\':ref:`exemple ` del :doc:`howto:index` - Descarregueu el mòdul :download:`geom ` i proveu-lo .. _Online Python Tutor\: geom: http://pythontutor.com/visualize.html#code=import%20math%0A%0Adef%20distance(x1,%20y1,%20x2,%20y2%29%3A%0A%20%20%20%20dx%20%3D%20x2%20-%20x1%0A%20%20%20%20dy%20%3D%20y2%20-%20y1%0A%20%20%20%20result%20%3D%20math.hypot(dx,%20dy%29%0A%20%20%20%20return%20result%0A%20%20%20%20%0Adef%20area(r%29%3A%0A%20%20%20%20return%20math.pi%20*%20r**2%0A%0Adef%20area2(xc,%20yc,%20xp,%20yp%29%3A%0A%20%20%20%20radius%20%3D%20distance(xc,%20yc,%20xp,%20yp%29%0A%20%20%20%20result%20%3D%20area(radius%29%0A%20%20%20%20return%20result%0A%0A%0Ad%20%3D%20distance(0,%200,%201,%201%29%0Aprint(d%29%0A%0Aa%20%3D%20area(2%29%0Aprint(a%29%0A%0Ab%20%3D%20area2(0,%200,%200,%203%29%0Aprint(b%29&cumulative=false&curInstr=0&heapPrimitives=true&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false Funcions d'ordre superior ------------------------- - En Python, una :term:`funció` és un nom que fa referència a un :term:`objecte` cridable de tipus :class:`function` - Una `funció d'ordre superior `__ és una :term:`funció` que - té una funció com a :term:`paràmetre` o - retorna una funció com a resultat - Per exemple +----------------------------------------+----------------------------------+ | >>> from funcions import q, parabola_1 | .. literalinclude:: funcions.py | | >>> q(parabola_1, 0, 1e-3) | :language: python3 | | -1.9970000000000265 | :lines: 7-16 | | >>> from math import cos | | | >>> q(cos, 1, 1e-3) | | | -0.8417409956931188 | | +----------------------------------------+----------------------------------+ - Descarregueu el mòdul :download:`funcions ` i proveu-lo Documentació d'una funció ------------------------- - Documentació d'una funció: :term:`python:docstring`. - Vegeu les seccions :ref:`tut-functions` i :ref:`tut-docstrings` del :doc:`python:tutorial/index` Desenvolupament incremental --------------------------- .. incremental development .. scaffolding - Vegeu a l\'`Online Python Tutor\: distance`_ l\':ref:`exemple ` del :doc:`howto:index` .. _Online Python Tutor\: distance: http://pythontutor.com/visualize.html#code=%23%20Versi%C3%B3%201%0A%0Adef%20distance_1(x1,%20y1,%20x2,%20y2%29%3A%0A%20%20%20%20return%200.0%0A%0Ad%20%3D%20distance_1(0,%200,%201,%201%29%0Aprint(1,%20d%29%0A%0A%23%20Versi%C3%B3%202%0A%0Adef%20distance_2(x1,%20y1,%20x2,%20y2%29%3A%0A%20%20%20%20dx%20%3D%20x2%20-%20x1%0A%20%20%20%20dy%20%3D%20y2%20-%20y1%0A%20%20%20%20return%20dx,%20dy%0A%20%20%20%20%0Ad%20%3D%20distance_2(0,%200,%201,%201%29%0Aprint(2,%20d%29%0A%0A%23%20Versi%C3%B3%203%0A%0Adef%20distance_3(x1,%20y1,%20x2,%20y2%29%3A%0A%20%20%20%20dx%20%3D%20x2%20-%20x1%0A%20%20%20%20dy%20%3D%20y2%20-%20y1%0A%20%20%20%20dsquared%20%3D%20dx*dx%20%2B%20dy*dy%0A%20%20%20%20return%20dsquared%0A%20%20%20%20%0Ad%20%3D%20distance_3(0,%200,%201,%201%29%0Aprint(3,%20d%29%0A%0A%23%20Versi%C3%B3%204%0A%0Adef%20distance_4(x1,%20y1,%20x2,%20y2%29%3A%0A%20%20%20%20dx%20%3D%20x2%20-%20x1%0A%20%20%20%20dy%20%3D%20y2%20-%20y1%0A%20%20%20%20dsquared%20%3D%20dx*dx%20%2B%20dy*dy%0A%20%20%20%20result%20%3D%20dsquared**0.5%0A%20%20%20%20return%20result%0A%20%20%20%20%0Ad%20%3D%20distance_4(0,%200,%201,%201%29%0Aprint(4,%20d%29%0A%0A%23%20Versi%C3%B3%205%0A%0Aimport%20math%0A%0Adef%20distance_5(x1,%20y1,%20x2,%20y2%29%3A%0A%20%20%20%20dx%20%3D%20x2%20-%20x1%0A%20%20%20%20dy%20%3D%20y2%20-%20y1%0A%20%20%20%20dsquared%20%3D%20dx*dx%20%2B%20dy*dy%0A%20%20%20%20result%20%3D%20math.sqrt(dsquared%29%0A%20%20%20%20return%20result%0A%20%20%20%20%0Ad%20%3D%20distance_5(0,%200,%201,%201%29%0Aprint(5,%20d%29%0A%0A%23%20Versi%C3%B3%205%0A%0Aimport%20math%0A%0Adef%20distance_6(x1,%20y1,%20x2,%20y2%29%3A%0A%20%20%20%20dx%20%3D%20x2%20-%20x1%0A%20%20%20%20dy%20%3D%20y2%20-%20y1%0A%20%20%20%20result%20%3D%20math.hypot(dx,%20dy%29%0A%20%20%20%20return%20result%0A%20%20%20%20%0Ad%20%3D%20distance_6(0,%200,%201,%201%29%0Aprint(6,%20d%29%0A&cumulative=false&curInstr=0&heapPrimitives=true&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false Programació amb estil --------------------- .. programming with style - Vegeu la secció :ref:`howto:style` del llibre :doc:`howto:index` Exercicis --------- - :doc:`fi:temes/funcions/Percentatge/index` - :doc:`fi:temes/funcions/Contaminació/index` - :doc:`fi:temes/funcions/Física/index`, punts 1 al 4 - :doc:`fi:temes/funcions/Conversions/index` .. Retorna més d'un valor - :doc:`fi:temes/funcions/Equació_de_segon_grau/index`, punt 1 .. Retorna més d'un valor, sqrt - :doc:`fi:temes/funcions/Nòmines/index` .. Crides entre funcions - :doc:`fi:temes/funcions/Zona_cerca/index`, punts de l'1 al 3 .. Crides entre funcions, sqrt, pi - :doc:`fi:temes/funcions/Mètriques_en_l_Eixample/index` .. Funcions com a paràmetre, abs, max, sqrt