Função devolvendo valor por referência?????

9 views
Skip to first unread message

Henrique Cesar Ulbrich

unread,
Jan 26, 2014, 11:11:15 PM1/26/14
to garoa-...@googlegroups.com
Pessoal, desculpem a pergunta noob, mas eu fiquei perdido nessa.

Até onde sei, você só consegue alterar uma variável global dentro de uma função usando a declaração "global" deste jeito:

bar_global = "Valor qualquer"

def foo( ):
    global bar_global
    bar_global = "Mudei e pronto, belê?"

print(bar_global)
foo()
print(bar_global)

Resultado:
'Valor qualquer'
'Mudei e pronto, belê?'

Até aí tudo bem.

Só que num prugraminha que estou fazendo aqui eu NÃO ESTOU USANDO a declaração "global". Mesmo assim, a função está modificando o valor das variáveis (do tipo lista, que é mutável) passadas como parâmetro. Por exemplo, uma função do tipo:

def foo(sacanagem):
    sacanagem = [9,7,5,3,1]
    return sacanagem

bar = [1,2,3,4,5]
print(bar)
foo(bar)
print(bar)

Veja que a linha onde está a chamada à função não é 
    bar = foo(bar)
mas simplesmente
    foo(bar)

Mesmo assim o resultado é
[1,2,3,4,5]
[9,7,5,3,1]

quando deveria ser
[1,2,3,4,5]
[1,2,3,4,5]

O que eu fiz de errado?
 

Henrique Cesar Ulbrich
henrique...@gmail.com

Henrique Cesar Ulbrich

unread,
Jan 26, 2014, 11:29:06 PM1/26/14
to garoa-...@googlegroups.com
Opa, falei bobagem, tentei simplificar o código pra pergunta e acabei fazendo um que se comporta como esperado. 

Mas vejam esta versão aqui:

def foo(sacanagem):
    sacanagem[2] = sacanagem[2] * 4
    return sacanagem

bar = [1,2,3,4,5]
print(bar[2])
foo(bar)
print(bar[2])

o resultado deveria ser
   3
   3
mas na verdade é
   3
   12

Por que?






Henrique Cesar Ulbrich
henrique...@gmail.com
Linux User #154139

Leandro Coletto Biazon

unread,
Jan 27, 2014, 10:23:33 AM1/27/14
to garoa-...@googlegroups.com
A explicação vem da diferença entre objetos mutáveis e imutáveis e o
fato que em Python não funcionam os conceitos de "passar por valor" ou
"passar por referência" como em C, mas sim a ideia de atribuir rótulos
para objetos (mutáveis ou imutáveis)

Achei esse artigo aqui bem escrito[1] e aborda sucintamente a questão.
Acho que o importante é entender a diferença entre esses três
snippets:

>>> a = "spam"
>>> def foo(param):
>>> param = "eggs"
>>> print(a)
"spam"

>>> a = ["spam"]
>>> def bar(param):
>>> param = ["eggs"']
>>> print(a)
["spam"]

>>> a = ["spam"]
>>> def baz(param):
>>> param[0] = ["eggs"']
>>> print(a)
["eggs"]

Nos três, ao chamar a função atribuímos o rótulo param para os objetos
"spam" no primeiro caso e para ["spam"] no segundo e terceiro, o mesmo
objeto referenciado por a no escopo anterior.

Mas nos dois primeiros, nós mudamos o objeto referenciado pelo rótulo
param, para "eggs" no primeiro caso e para ["eggs"] no segundo, e em
ambos o rótulo param deixa de referenciar o objeto referenciado pelo
rótulo a.

No terceiro caso, o rótulo param continua apontando para o objeto
referenciado por a, e alteramos uma propriedade desse objeto. Podemos
fazer isso porque o objeto em questão é uma lista, mutável portanto.

Leandro
[1] http://www.jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/

2014-01-27 Henrique Cesar Ulbrich <henrique...@gmail.com>:
> --
> Você está recebendo esta mensagem porque se inscreveu no grupo
> "garoa-python" dos Grupos do Google.
> Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie
> um e-mail para garoa-python...@googlegroups.com.
> Visite este grupo em http://groups.google.com/group/garoa-python.

Leandro Coletto Biazon

unread,
Jan 27, 2014, 10:32:48 AM1/27/14
to garoa-...@googlegroups.com
Pra complementar, acho que vale destacar a diferença entre as operações

param = "eggs"
param = ["eggs"']
param[0] = ["eggs"']

apesar de parecerem a mesma coisa, as primeiras duas são operações de
atribuição de nomes à objetos, enquanto a terceira é apenas sintaxe
alternativa para a chamada do método

param.__setitem__(0, "eggs")

2014-01-27 Leandro Coletto Biazon <leandr...@gmail.com>:

Bruno Gola

unread,
Jan 27, 2014, 10:44:45 AM1/27/14
to garoa-...@googlegroups.com
olha, duas pessoas sumidas interagindo numa lista que eu nem lembrava que existia!

:P
--
Bruno Gola <brun...@gmail.com>
http://bgo.la/ | +55 11 9-5552-3599

Leandro Coletto Biazon

unread,
Jan 27, 2014, 10:47:08 AM1/27/14
to garoa-...@googlegroups.com
2014-01-27 Bruno Gola <brun...@gmail.com>:
> olha, duas pessoas sumidas interagindo numa lista que eu nem lembrava que
> existia!

Tipo isso:
http://www.youtube.com/watch?v=WnzlbyTZsQY

Henrique Cesar Ulbrich

unread,
Jan 28, 2014, 7:26:32 AM1/28/14
to garoa-...@googlegroups.com
A missa é no mesmo lugar ainda?
--
Bruno Gola <brun...@gmail.com>
http://bgo.la/ | +55 11 9-5552-3599

--
Você está recebendo esta mensagem porque se inscreveu no grupo "garoa-python" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para garoa-python...@googlegroups.com.
Visite este grupo em http://groups.google.com/group/garoa-python.


--

Henrique Cesar Ulbrich

unread,
Jan 28, 2014, 8:04:10 AM1/28/14
to garoa-...@googlegroups.com
Entendi, Leandro.

Então, pra funcionar do jeito que estou esperando, eu tenho que antes destruir a referência ao objeto original, certo?

Algo assim (testei e funcionou):
 def foo(sacanagem):
     sacanagem = sacanagem[ : ]
     sacanagem[2] = sacanagem[2] * 4
     return sacanagem

--

Henrique Cesar Ulbrich

unread,
Jan 28, 2014, 8:10:50 AM1/28/14
to garoa-...@googlegroups.com
Outra coisa: se os objetos não são destruídos quando um nome é reapontado para outro objeto, isso não acaba largando muito lixo na memória?
--
Henrique Cesar Ulbrich
henrique...@gmail.com
Linux User #154139

Bruno Gola

unread,
Jan 28, 2014, 8:15:12 AM1/28/14
to garoa-...@googlegroups.com
2014-01-28 Henrique Cesar Ulbrich <henrique...@gmail.com>:
> Outra coisa: se os objetos não são destruídos quando um nome é reapontado
> para outro objeto, isso não acaba largando muito lixo na memória?


pra isso existe o garbage collector :)

Bruno Gola

unread,
Jan 28, 2014, 8:16:02 AM1/28/14
to garoa-...@googlegroups.com
2014-01-28 Henrique Cesar Ulbrich <henrique...@gmail.com>:
> Entendi, Leandro.
>
> Então, pra funcionar do jeito que estou esperando, eu tenho que antes
> destruir a referência ao objeto original, certo?
>
> Algo assim (testei e funcionou):
> def foo(sacanagem):
> sacanagem = sacanagem[ : ]
> sacanagem[2] = sacanagem[2] * 4
> return sacanagem


eu só mudaria o nome da variavel pra não ficar confuso...

minha_sacanagem = sacanagem[:]

etc ...

:)
> --
> Você está recebendo esta mensagem porque se inscreveu no grupo
> "garoa-python" dos Grupos do Google.
> Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie
> um e-mail para garoa-python...@googlegroups.com.
> Visite este grupo em http://groups.google.com/group/garoa-python.



Henrique Cesar Ulbrich

unread,
Jan 28, 2014, 9:03:40 AM1/28/14
to garoa-...@googlegroups.com
A sacanagem é só local. 

Quem chamou a funcao usou outro nome.
> --
> Você está recebendo esta mensagem porque se inscreveu no grupo
> "garoa-python" dos Grupos do Google.
> Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie
> um e-mail para garoa-python...@googlegroups.com.
> Visite este grupo em http://groups.google.com/group/garoa-python.



--
Bruno Gola <brun...@gmail.com>
http://bgo.la/ | +55 11 9-5552-3599

--
Você está recebendo esta mensagem porque se inscreveu no grupo "garoa-python" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para garoa-python...@googlegroups.com.
Visite este grupo em http://groups.google.com/group/garoa-python.


--

Bruno Gola

unread,
Jan 28, 2014, 9:05:52 AM1/28/14
to garoa-...@googlegroups.com
eu sei, é só frescura minha

Henrique Cesar Ulbrich

unread,
Jan 28, 2014, 4:06:33 PM1/28/14
to garoa-...@googlegroups.com
Minha viola caipira existe ainda?

Henrique Cesar Ulbrich
henrique...@gmail.com
Linux User #154139


Mobi Yabiku Neto

unread,
Jan 28, 2014, 4:08:29 PM1/28/14
to garoa-...@googlegroups.com
Meu toca discos existe ainda? =P

Henrique Cesar Ulbrich

unread,
Jan 29, 2014, 1:51:54 PM1/29/14
to garoa-...@googlegroups.com
Existe, obviamente.

Eu fiz menção várias vezes de pagá-lo, inclusive, para que fosse meu.

Henrique Cesar Ulbrich
henrique...@gmail.com
Linux User #154139


Mobi Yabiku Neto

unread,
Jan 29, 2014, 1:57:56 PM1/29/14
to garoa-...@googlegroups.com
vou pensar mais um pouco sobre isso. =D


2014-01-29 Henrique Cesar Ulbrich <henrique...@gmail.com>
Reply all
Reply to author
Forward
0 new messages