sexta-feira, 26 de janeiro de 2018

Exame Recurso - P1

No exame de recurso era apresentada a seguinte sessão no interpretador:
>>> def teste(x):
...    def mist(y):
...        return x**y
...    return mist
...
>>> oops = teste(2)
>>> oops(4)
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
oops = teste(2)
Em Python, todas as atribuições são do tipo:
nome = expressão
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.
>>> id(teste)
4504739912
>>> type(oops)

>>> id(oops)
4504740048
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'oops', ‘teste']
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.
>>> import inspect
>>> inspect.getargspec(oops)
ArgSpec(args=['y'], varargs=None, keywords=None, defaults=None)
>>> inspect.getargspec(teste)
ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)
>>> inspect.getclosurevars(oops)
ClosureVars(nonlocals={'x': 2}, globals={}, builtins={}, unbound=set())
>>> inspect.getclosurevars(teste)
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!

Sem comentários:

Enviar um comentário