Várias atribuições na mesma linha

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Várias atribuições na mesma linha

Luciano Ramalho
Colegas,

Sabemos que Python aceita atribuições em cascata, assim:

>>> a = b = c = 3

Vale notar que a mesma sintaxe funciona em Ruby, C, PHP, JavaScript
etc. mas por motivos diferentes. Naquelas linguagens, a atribuição é
uma expressão (cujo valor é o valor atribuído), portanto isso:

a = b = c = 3

é o mesmo que isso nessas outras linguagens:

a = b = (c = 3)  # erro sintático em Python

Inclusive o fato de que a atribuição é um comando especial, e não uma
expressão, é uma excelente idéia, pois evita um bug comum em outras
linguagens, ou seja, o famoso:

if (a = b):   # erro sintático em Python

quando a pessoa queria dizer:

if (a == b):  # isso é Python, mas os parênteses são desnecessários

Então na verdade a = b = c = 3 funciona porque o parser entende como se fosse

c = 3
b = 3
a = 3

A questão é que eu não achei onde isto está documentado na Language
Reference. Alguém sabe?

Dica: a documentação da atribuição eu achei aqui:

http://docs.python.org/reference/simple_stmts.html

[ ]s
Luciano

--
Luciano Ramalho
programador repentista || stand-up programmer
Twitter: @luciano
Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Alberto Fabiano-2
2011/8/7 Luciano Ramalho <[hidden email]>

> **
>
>
> Colegas,
>
> Sabemos que Python aceita atribuições em cascata, assim:
>
> >>> a = b = c = 3
>
> Vale notar que a mesma sintaxe funciona em Ruby, C, PHP, JavaScript
> etc. mas por motivos diferentes. Naquelas linguagens, a atribuição é
> uma expressão (cujo valor é o valor atribuído), portanto isso:
>
> a = b = c = 3
>
> é o mesmo que isso nessas outras linguagens:
>
> a = b = (c = 3) # erro sintático em Python
>
> Inclusive o fato de que a atribuição é um comando especial, e não uma
> expressão, é uma excelente idéia, pois evita um bug comum em outras
> linguagens, ou seja, o famoso:
>
> if (a = b): # erro sintático em Python
>
> quando a pessoa queria dizer:
>
> if (a == b): # isso é Python, mas os parênteses são desnecessários
>
> Então na verdade a = b = c = 3 funciona porque o parser entende como se
> fosse
>
> c = 3
> b = 3
> a = 3
>
> A questão é que eu não achei onde isto está documentado na Language
> Reference. Alguém sabe?
>
> Dica: a documentação da atribuição eu achei aqui:
>
> http://docs.python.org/reference/simple_stmts.html
>

Boa pergunta! :-)

A algum tempo atrás eu estava realizando a mesma pesquisa e não encontrei,
seja buscando como 'assign * "variables simultaneously"' ou "cascading
assignment" - mas talvez eu não tenha empregado as keywords corretas.

O que encontrei foram referências no tutorial informal de introdução:

http://docs.python.org/tutorial/introduction.html

Além de outros referências em releases no docs.python.org.

Cheguei a tentar buscar referências cruzadas via DUP_TOP, mas também não
encontrei...

<OFF>

Foi nesta busca que descobri que em Python  'a * a'  tem desempenho melhor
que 'pow(a,2)' e 'a ** 2', mas que este resultado pode não ser verdadeiro se
a potência for maior que 4.

</OFF>

Mas não encontrei nada na "Language Reference"

[]s

Alberto

>
>
> [ ]s
> Luciano
>
> --
> Luciano Ramalho
> programador repentista || stand-up programmer
> Twitter: @luciano
>  
>


[As partes desta mensagem que não continham texto foram removidas]



------------------------------------

Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
Links do Yahoo! Grupos

<*> Para visitar o site do seu grupo na web, acesse:
    http://br.groups.yahoo.com/group/python-brasil/

<*> Para sair deste grupo, envie um e-mail para:
    [hidden email]

<*> O uso que você faz do Yahoo! Grupos está sujeito aos:
    http://br.yahoo.com/info/utos.html


Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Rodolpho Henrique Orlovsky Eckhardt
In reply to this post by Luciano Ramalho
On 00:39 Mon 08 Aug     , Rodolpho Henrique Orlovsky Eckhardt wrote:

> On 20:58 Sun 07 Aug     , Luciano Ramalho wrote:
> > A questão é que eu não achei onde isto está documentado na Language
> > Reference. Alguém sabe?
> >
> > Dica: a documentação da atribuição eu achei aqui:
> >
> > http://docs.python.org/reference/simple_stmts.html
>
> Olá Ramalho,
>
> Acho que é nessa documentação mesmo, na definição de atribuição ele usa
> 'assignment_stmt ::=  (target_list "=")+ (expression_list | yield_expression)'
>
> Permitindo a existência de um ou mais '(target_list "=")'.
>
> Em seguida, é mencionado:
>
> "If the target list is a single target: The object is assigned to that target."
>
> Abraços!

Eu tentei enviar essa resposta, mas a lista rejeitou meu email. Tentando novamente.

Abraços!!

--
Rodolpho Eckhardt <[hidden email]>
http://rodolphoeck.com


[As partes desta mensagem que não continham texto foram removidas]

Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Samuel Teixeira Santos
eu nao advanced in python mas...

se ele interpretasse assim:
> Então na verdade a = b = c = 3 funciona porque o parser entende como se
> fosse
>
> c = 3
> b = 3
> a = 3
>

quando fizesse com uma classe que voce definisse, a segunda forma teria
sempre a mesma referência.
e nao tem (com classes que voce definiu pelo que testei no Idle)

contudo se usar uma classe builtin como a Decimal, aí ele tem o mesmo
comportamento nos dois casos...

tipo, viajei?




Em 8 de agosto de 2011 15:45, Rodolpho Henrique Orlovsky Eckhardt <
[hidden email]> escreveu:

> **
>
>
> On 00:39 Mon 08 Aug , Rodolpho Henrique Orlovsky Eckhardt wrote:
>
> > On 20:58 Sun 07 Aug , Luciano Ramalho wrote:
> > > A questão é que eu não achei onde isto está documentado na Language
> > > Reference. Alguém sabe?
> > >
> > > Dica: a documentação da atribuição eu achei aqui:
> > >
> > > http://docs.python.org/reference/simple_stmts.html
> >
> > Olá Ramalho,
> >
> > Acho que é nessa documentação mesmo, na definição de atribuição ele usa
> > 'assignment_stmt ::= (target_list "=")+ (expression_list |
> yield_expression)'
> >
> > Permitindo a existência de um ou mais '(target_list "=")'.
> >
> > Em seguida, é mencionado:
> >
> > "If the target list is a single target: The object is assigned to that
> target."
> >
> > Abraços!
>
> Eu tentei enviar essa resposta, mas a lista rejeitou meu email. Tentando
> novamente.
>
> Abraços!!
>
> --
> Rodolpho Eckhardt <[hidden email]>
> http://rodolphoeck.com
>
>
> [As partes desta mensagem que não continham texto foram removidas]
>
>  
>



--
Falou!

Samuel Teixeira Santos
サントスサムエル テイェイラ

*
P*ost *S*criptum:

Por favor, ao encaminhar as mensagens "globais"(não direcionadas somente a
minha pessoa):
1. *Apague* o *meu e-mail* e o meu *nome* no corpo da mensagem.
2. *Apague* também qualquer *endereço de e-mail* e *nome* que esteja no
corpo da mensagem
3. Inclua *seus destinatários* apenas na opção de *cópia oculta (Cco ou Bcc)
*.

Agindo assim *podemos* dificultar a disseminação de vírus, spams e banner.
Acho que vale a pena tentar.


[As partes desta mensagem que não continham texto foram removidas]

Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Henr"Ikke" Pereira
In reply to this post by Rodolpho Henrique Orlovsky Eckhardt
2011/8/8 Rodolpho Henrique Orlovsky Eckhardt <[hidden email]>

> On 00:39 Mon 08 Aug     , Rodolpho Henrique Orlovsky Eckhardt wrote:
> > On 20:58 Sun 07 Aug     , Luciano Ramalho wrote:
> > > A questão é que eu não achei onde isto está documentado na Language
> > > Reference. Alguém sabe?
> > >
> > > Dica: a documentação da atribuição eu achei aqui:
> > >
> > > http://docs.python.org/reference/simple_stmts.html
> >
> > Olá Ramalho,
> >
> > Acho que é nessa documentação mesmo, na definição de atribuição ele usa
> > 'assignment_stmt ::=  (target_list "=")+ (expression_list |
> yield_expression)'
> >
> > Permitindo a existência de um ou mais '(target_list "=")'.
> >
> > Em seguida, é mencionado:
> >
> > "If the target list is a single target: The object is assigned to that
> target."
> >
>


Wow.
Acabei de me tocar que k,y = a = c,d = e,f = (1,2) é um assignment válido em
python



> > Abraços!
>
> Eu tentei enviar essa resposta, mas a lista rejeitou meu email. Tentando
> novamente.
>
> Abraços!!
>
> --
> Rodolpho Eckhardt <[hidden email]>
> http://rodolphoeck.com
>
>
> [As partes desta mensagem que não continham texto foram removidas]
>
>
>
> ------------------------------------
>
> Python-Brasil
> http://www.python.org.br/wiki/AntesDePerguntar
> Links do Yahoo! Grupos
>
>
>


--
Henr"Ikke" G.G. Pereira
http://www.halts.com.br
+55 (55) 9619-7499
|_|0|_|
|_|_|0|
|0|0|0|


[As partes desta mensagem que não continham texto foram removidas]

Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Luciano Ramalho
In reply to this post by Samuel Teixeira Santos
2011/8/8 Samuel Teixeira Santos <[hidden email]>:

> eu nao advanced in python mas...
>
> se ele interpretasse assim:
>> Então na verdade a = b = c = 3 funciona porque o parser entende como se
>> fosse
>>
>> c = 3
>> b = 3
>> a = 3
>>
>
> quando fizesse com uma classe que voce definisse, a segunda forma teria
> sempre a mesma referência.
> e nao tem (com classes que voce definiu pelo que testei no Idle)
>
> contudo se usar uma classe builtin como a Decimal, aí ele tem o mesmo
> comportamento nos dois casos...
>
> tipo, viajei?

Oi, Samuel, compartilha conosco os testes que vocẽ fez para que a
gente possa interpretar o que você viu.


--
Luciano Ramalho
programador repentista || stand-up programmer
Twitter: @luciano
Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Luciano Ramalho
In reply to this post by Rodolpho Henrique Orlovsky Eckhardt
2011/8/8 Rodolpho Henrique Orlovsky Eckhardt <[hidden email]>:

> On 00:39 Mon 08 Aug     , Rodolpho Henrique Orlovsky Eckhardt wrote:
>> On 20:58 Sun 07 Aug     , Luciano Ramalho wrote:
>> > A questão é que eu não achei onde isto está documentado na Language
>> > Reference. Alguém sabe?
>> >
>> > Dica: a documentação da atribuição eu achei aqui:
>> >
>> > http://docs.python.org/reference/simple_stmts.html
>>
>> Olá Ramalho,
>>
>> Acho que é nessa documentação mesmo, na definição de atribuição ele usa
>> 'assignment_stmt ::=  (target_list "=")+ (expression_list | yield_expression)'
>>
>> Permitindo a existência de um ou mais '(target_list "=")'.

É isso, aí, o + é onde isso está documentado.

>> Em seguida, é mencionado:
>>
>> "If the target list is a single target: The object is assigned to that target."

Esse trecho do doc não ajuda nada, né? Porque a target_list é a lista
de alvos (separados por vírgulas) e não a repetição de target_list
seguida de =.

Mas tá esclarecido o mistério.

Valeu, Rodolpho!

--
Luciano Ramalho
programador repentista || stand-up programmer
Twitter: @luciano
Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Luciano Ramalho
Para aprofundar na questão da ordem de execução das atribuições em
cascata, fiz um teste:

http://code.google.com/p/propython/source/browse/fundamentos/assign.py

O teste mostra que na atribuição:

a = b = c = x

O valor de x é avaliado primeiro (é sempre assim em atribuições em
Python, o que está à direita do = acontece primeiro, no caso de uma
cascata, é o que está à direita do = mais à direita de todos), e as
atribuições são feitas nesta ordem:

a = x
b = x
c = x

Para ver como eu constatei isso, veja o doctest embutido no assign.py.

[ ]s
Luciano

--
Luciano Ramalho
programador repentista || stand-up programmer
Twitter: @luciano
Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Samuel Teixeira Santos
foi este teste que fiz no Idle

http://dpaste.com/589866/

tem a ver com a discussão?

Em 8 de agosto de 2011 19:32, Luciano Ramalho <[hidden email]> escreveu:

> **
>
>
> Para aprofundar na questão da ordem de execução das atribuições em
> cascata, fiz um teste:
>
> http://code.google.com/p/propython/source/browse/fundamentos/assign.py
>
> O teste mostra que na atribuição:
>
> a = b = c = x
>
> O valor de x é avaliado primeiro (é sempre assim em atribuições em
> Python, o que está à direita do = acontece primeiro, no caso de uma
> cascata, é o que está à direita do = mais à direita de todos), e as
> atribuições são feitas nesta ordem:
>
> a = x
> b = x
> c = x
>
> Para ver como eu constatei isso, veja o doctest embutido no assign.py.
>
> [ ]s
> Luciano
>
> --
>
> Luciano Ramalho
> programador repentista || stand-up programmer
> Twitter: @luciano
>
>  
>



--
Falou!

Samuel Teixeira Santos
サントスサムエル テイェイラ

*
P*ost *S*criptum:

Por favor, ao encaminhar as mensagens "globais"(não direcionadas somente a
minha pessoa):
1. *Apague* o *meu e-mail* e o meu *nome* no corpo da mensagem.
2. *Apague* também qualquer *endereço de e-mail* e *nome* que esteja no
corpo da mensagem
3. Inclua *seus destinatários* apenas na opção de *cópia oculta (Cco ou Bcc)
*.

Agindo assim *podemos* dificultar a disseminação de vírus, spams e banner.
Acho que vale a pena tentar.


[As partes desta mensagem que não continham texto foram removidas]

Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Leonardo Santagada
In reply to this post by Henr"Ikke" Pereira
2011/8/8 Henr"Ikke" Pereira <[hidden email]>:
>> > "If the target list is a single target: The object is assigned to that
>> target."
>> >
>>
>
>
> Wow.
> Acabei de me tocar que k,y = a = c,d = e,f = (1,2) é um assignment válido em
> python

e eu que existe um erro bem bizarro que pode potencialmente acontecer:

>>> lambda a: x=2
  File "<stdin>", line 1
SyntaxError: can't assign to lambda

ahã

--
Leonardo Santagada
Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Leonardo Santagada
In reply to this post by Samuel Teixeira Santos
2011/8/8 Samuel Teixeira Santos <[hidden email]>:
> http://dpaste.com/589866/
>
> tem a ver com a discussão?

Não muito, tem vários erros no teu exemplo, um é que criar um atributo
de instancia é self.foo_member e não foo_member, self é explicito no
python. Outro problema é que a=2 diz que a label a aponta para o
inteiro 2 e não muda o valor do decimal. deve ter mais coisas mas isso
já ajuda a esclarecer as tuas duvidas eu acho


--
Leonardo Santagada
Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Pedro Werneck-2
In reply to this post by Luciano Ramalho
2011/8/7 Luciano Ramalho <[hidden email]>
>
> Então na verdade a = b = c = 3 funciona porque o parser entende como se fosse
>
> c = 3
> b = 3
> a = 3
>
> A questão é que eu não achei onde isto está documentado na Language
> Reference. Alguém sabe?

Creio que não esteja documentado mesmo. O comentário do Samuel faz
sentido, pois a rigor o que o código faz é colocar o valor na pilha e
duplicá-lo várias vezes para atribuí-lo às variáveis. Se ele
interpretasse segundo o código acima, cada um poderia receber uma
instância distinta.



---
Pedro Werneck
Reply | Threaded
Open this post in threaded view
|

Re: Várias atribuições na mesma linha

Rudá Moura-2
On 09/08/2011, at 16:19, Pedro Werneck wrote:

> Creio que não esteja documentado mesmo. O comentário do Samuel faz
> sentido, pois a rigor o que o código faz é colocar o valor na pilha e
> duplicá-lo várias vezes para atribuí-lo às variáveis. Se ele
> interpretasse segundo o código acima, cada um poderia receber uma
> instância distinta.
>
>
Olha que simpático o código que o interpretador gera…

>>> import dis
>>> def f():
...  a = b = c = 3
...
>>> dis.dis(f)
  2           0 LOAD_CONST               1 (3)
              3 DUP_TOP            
              4 STORE_FAST               0 (a)
              7 DUP_TOP            
              8 STORE_FAST               1 (b)
             11 STORE_FAST               2 (c)
             14 LOAD_CONST               0 (None)
             17 RETURN_VALUE        

(Python 2.7).




[As partes desta mensagem que não continham texto foram removidas]



------------------------------------

Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
Links do Yahoo! Grupos

<*> Para visitar o site do seu grupo na web, acesse:
    http://br.groups.yahoo.com/group/python-brasil/

<*> Para sair deste grupo, envie um e-mail para:
    [hidden email]

<*> O uso que você faz do Yahoo! Grupos está sujeito aos:
    http://br.yahoo.com/info/utos.html