Nesta páxina non temos exercicios, pero intentamos aclarar cousas importantes coas funcións e as variables que poden levar a erros conceptuais moi habituais:
- Cando invoco unha función, antes ou despois de creala?
- Como invoco unha función (con parámetro ou sen parámetro)?
- Que nome de variable utilizo para o argumento dunha función?
- Podo modificar dentro dunha función o valor dunha variable creada fora da función?
- Como uso unha variable creada dentro dunha función fora desa función, no programa?
Seguramente prefiras ir traballando un pouco coas funcións en Python antes de ler esta parte. Podes visitar o resto das páxinas de Python e cando xurdan problemas ou aparezan mensaxes raros ao executar o código coas funcións e as variables voltar.
A importancia de secuenciar: Name ____ is not defined
Cando apareza esa mensaxe de erro estás a utilizar un nome de variable ou función non definido anteriormente. É un erro de secueciación. O máis probable é que apareza se invocas unha función antes de creala:
|
|
|
|
No segundo exemplo vemos o importante de secuenciar correctamente. O parámetro ten valor, pero está dado despois de chamar á variable.
Función en busca de parámetro/argumento (required positional argument)
Cando apareza un mensaxe de erro similar a TypeError: proba() missing 1 required positional argument: 'nome' tes que lelo da seguinte maneira: a función, proba(), ten un parámetro, nome, e non lle dimos un valor antes ou no momento de chamar á función. Se unha función ten 3 parámetros e só lle damos 2 pasará o mesmo.
|
|
|
|
Convén pensar con calma por que non funciona o primeiro código. Temos un parámetro, nome, e ademáis unha variable que se chama igual e ten un valor, pero ao chamar á función o facemos sen valor no parámetro, por iso da erro. Isto pode e debe ser confuso, pero é unha das cousas que fai máis sinxelo e amigable a Python. Por exemplo, grazas a isto é moito máis sinxelo reciclar código dun programa a outro.
Se complicas a función simplificarás o programa: Argumentos e retornos
Podemos establecer unha taxonomía de funcións, dende as máis simples pero menos útiles, ás máis complexas e útiles.
1.- Función sen parámetro.
En Python podes crear funcións sen parámetros, e chamalas polo seu nome:
|
|
Cal é o problema de facelo así?: Que tes que utilizar sempre o mesmo nome das variables, a e b. E non é tan doado copiar a función a outro programa, porque tes que usar as mesmas variables (estes programas de proba son moi sinxelos, falamos de programas de complexidade media).
2.- Función con parámetros.
Se modificamos a función, podemos utilizala con calesquera outras variables, e incluso reciclala noutro programa:
|
|
O normal é rematar a función coa orde return, retorno, pero neste caso funcionaría igual sen ela. Pero é unha boa práctica de programación facelo así, facilita a lectura do código.
3.- Función con parámetros que devolve o resultado nunha variable.
Pero aínda temos un problema: a variable suma garda o resultado da función. Se queremos utilizala fora da función non vai funcionar (ver máis abaixo o problema "Dentro/Fóra"). Ou sexa, como podemos debemos crear unha variable dentro da función para almacenar o resultado de aplicar á función a uns parámetros e utilizar fora da función esa variable?. Pois retornando, return, o resultado da función. así é como podemos utilizalo:
|
|
4.- Función con número de parámetros indeterminado: *args
A función anterior podemos aplicala só a a dous parámetros. Pero e se queremos sumar un número calesquera de valores?. Pois sustituimos os parámetros por *args e podemos pasar a función a calquera número de parámetros. O de *args fai referencia a argumentos.
|
|
Se agora quiseras sumar 10 variables en vez de 4 poderías facelo facilmente.
Se queres mellorar o código podes probar a escribir na última liña: print('A suma total de {} + {} + {} + {} é '.format(a,b,c,d), suma_total)
5.- Función que devolve 2 ou máis resultados.
Por último podemos facer que a función devolva máis dun valor, cada un gardado nunha variable.
|
|
O problema "Dentro/Fora": variables globais, locais e nonlocais
O problema das variables globais e locais remata sendo tan sinxelo como a explicación de cando estás Dentro e cando Fóra, e tan importante de entender coma calquera cousa que che teñan explicado en Barrio Sésamo:
Se volvemos por un momento a Scratch podemos lembrar que ao crear unha variable temos dúas opcións, para todas as figuras ou só para unha:
Se a creamos para todas as figuras, logo non podemos crear outra variable co mesmo nome cando creamos unha segunda figura, pero a cambio xa a temos creada esta variable e podemos utilizala no código da nova figura. Se a creamos só para a primeira figura, podemos repetir nome na variable da segunda figura pero non podemos utilizar a primeira variable no código da segunda.
Isto ten unha certa equivalencia en Python, pero é un pouquiño máis lioso. En Scratch o normal é crear variables globais, e poñerlle nomes distintos á de cada figura.
A lembrar
En Python usar este tipo de variables globais para todo o programa se considera unha mala práctica de programación, non está aconsellada (agás para definir constantes e outras excepcións) en programas de complexidade media, aínda que o facemos normalmente en programas sinxelos para aprender a programar.
En Python3 temos 3 posibilidades para unha variable: global, local e nonlocal. Global sería a creada para todo o programa (similar á de Scratch para todas as figuras) e pode usarse dentro das funcións, local é creada dentro da función (similar á de Scratch para unha figura) e non pode utilizarse fora dela, nonlocal é creada dentro dunha subfunción (unha función aniñada noutra) e o seu valor é dado pola función.
(nota: declarar unha variable é creala, poñerlle nome e darlle un valor inicial que logo pode variar)
O importante non son os nomes, senón saber cales van ser o problemas no código coas variables.
Global vs local
Cando creamos unha variable fora dunha función, iso é unha variable global. Cando a creamos dentro dunha función é local.
Os problemas aparecen cando queremos utilizar a variable global dentro da función, ou cando queremos utilizar a variable local no resto do programa, fora da función.
No seguinte programa temos unha variable global e outra local:
def funcion_con_variable(): #podemos poñer y como parámetro, pero de momento non é necesario
y = 'Eu son local'
x = 'Eu son global'
Este programa de momento no fai nada. Imos imprimir os valores das variables. Temos varias posibilidades:
Descrición | Código | Saída |
Imprimir variable global fora e variable local dentro |
|
|
Por que non imprime a variable y?. Pois por que non temos chamada á función. Imos modificalo:
Descrición | Código | Saída |
Imprimir variable global fora e variable local dentro |
|
|
Imprimir variable global dentro da función |
|
|
Imprimir variable local fora da función |
|
|
No último caso a variable local y non pode utilizarse fora da función, pero a variable global si pode utilizarse dentro da función. Para obter o valor de y fora da función teremos que utilizar return, tal e como vimos máis arriba no apartado de argumentos e retornos.
Variables co mesmo nome
Que sucede se as dúas variables teñen o mesmo nome (cousa habitual se copiamos código doutro programa)?. Pois que temos dúas variables co mesmo nome, unha local que só funciona dentro da función cando lle damos un valor. Vexamos posibilidades:
Descrición | Código | Saída |
Variable global e local co mesmo nome, unha dentro e outra fora |
|
|
Chamada a variable global dentro de función |
|
|
É fundamental entender que x global está fora da función, e unha función sen parámetros utiliza varibales locais, que están dentro da función. Cando Python chama á función vai coller x local e se atopa con que non ten valor (tenno máis abaixo), Esta é razón pola que non está aconsellado utilizar variables globais, interfiren coas locais se teñen o mesmo nome. Se x non tivese valor dentro da función, o intérprete de comando buscaría o valor de x fora e atoparía o valor global.
COMO MODIFICAR VARIABLES GLOBAIS DENTRO DE FUNCIÓNS: GLOBAL KEYWORD
O normal nos programas sinxelos é que teñamos datos en variables globais, fagamos funcións para modificalos (é decir, as variables globais son parámetros) e queramos obter valores de saída da función. Vexamos que o máis probable é que teñamos problemas e que unha posible solución é utilizar a palabra reservada por Python (keyword) global para identificar como global a unha variable dentro dunha función:
Descrición | Código | Saída |
Variable global como parámetro de función |
|
|
Variable global que intentamos modificar dentro de función e non funciona |
|
|
Variable global que modificamos dentro de función |
|
|
Pode ser necesario reflexionar sobre por que na función utilizamos como argumento a y, e logo na función non aparece. Se utilizaramos x como argumento daría erro.
VARIABLES NONLOCAIS E FUNCIÓNS ANIÑADAS: NONLOCAL KEYWORD
A medida que aumente a complexidade do algoritmo pode ser necesario ter funcións aniñadas. Dende Python 3 temos a posibilidade de crear e usar variables non locais, que se usan na subfunción e reciben o valor na función (non son globais, pero tampouco locais de todo).
Descrición | Código | Saída |
Función aniñada con variable local |
|
|
Función aniñada con variable non local |
|
|