No exame de recurso era apresentada a seguinte sessão no interpretador:
1.
>>>
def
teste(x):
2.
...
def
mist(y):
3.
...
return
x
*
*
y
4.
...
return
mist
5.
...
6.
>>> oops
=
teste(
2
)
7.
>>> oops(
4
)
8.
16
e perguntava-se para explicitar o que se tinha passado.
As respostas demonstram a grande
confusão conceptual que ainda existe. Mas vamos por partes. A sessão pode ser dividida em três partes. Na primeira, é definida uma função (
teste) cujo corpo é formado pela definição de outra função (
mist). A função
teste devolve como resultado a função
mist. Na segunda, é feita a atribuição
Em Python, todas as atribuições são do tipo:
Assim o que vai acontecer é que é calculado o valor associado à
expressão teste(2) e esse valor é um novo objecto de nome …
nome! No nosso caso, a expressão vai ter como valor um objecto do tipo função que devolve 2**y, que tem
oops como um atributo do tipo
nome. Na terceira parte, essa nova função é chamada com o argumento igual a 4, pelo que o resultado que se obtém será 2**4 = 16.
A sessão abaixo ilustra o que acabámos de dizer.
01.
>>> id(teste)
02.
4504739912
03.
>>> type(oops)
04.
<
class
'function'
=
"">
05.
>>> id(oops)
06.
4504740048
07.
>>> dir()
08.
[
'__builtins__'
,
'__doc__'
,
'__loader__'
,
'__name__'
,
'__package__'
,
'__spec__'
,
'oops'
, ‘teste']
09.
<
/
class
>
Como use pode ver, no
espaço de nomes apenas são conhecidos
oops e
teste. Sao ambos nomes associados a
funções distintas. Podemos expandir as coisas recorrendo ao
módulo inspect.
01.
>>>
import
inspect
02.
>>> inspect.getargspec(oops)
03.
ArgSpec(args
=
[
'y'
], varargs
=
None
, keywords
=
None
, defaults
=
None
)
04.
>>> inspect.getargspec(teste)
05.
ArgSpec(args
=
[
'x'
], varargs
=
None
, keywords
=
None
, defaults
=
None
)
06.
>>> inspect.getclosurevars(oops)
07.
ClosureVars(nonlocals
=
{
'x'
:
2
}, globals
=
{}, builtins
=
{}, unbound
=
set())
08.
>>> inspect.getclosurevars(teste)
09.
ClosureVars(nonlocals
=
{}, globals
=
{}, builtins
=
{}, unbound
=
set())
Como notamos, cada uma das funções tem o seu argumento (
x, para
teste,
y, para
oops), mas
oops tem
x como variável
não local instanciada a 2!