Por que os parênteses impressos são voluntários no Python 2.7?

98

No Python 2.7, os dois itens a seguir farão o mesmo

print("Hello, World!") # Prints "Hello, World!"

print "Hello, World!" # Prints "Hello, World!"

No entanto, o seguinte não

print("Hello,", "World!") # Prints the tuple: ("Hello,", "World!")

print "Hello,", "World!" # Prints the words "Hello, World!"

No Python 3.x, o parêntese printé obrigatório, essencialmente tornando-o uma função, mas no 2.7 ambos funcionarão com resultados diferentes. O que mais devo saber sobre o printPython 2.7?

Hubro
fonte
7
No Python 2.x printé realmente uma instrução especial, não uma função. É também por isso que não pode ser usado como: lambda x: print xObserve que (expr)não cria uma tupla (resulta em expr), mas cria ,.
Estou assumindo que o suporte para imprimir como uma função e imprimir como uma instrução é para manter a compatibilidade com versões anteriores de python, enquanto encorajo as pessoas a usar a nova sintaxe para migrar para o python 3.
GWW
11
ps, Para habilitar a função de impressão no 2.7 (e não ter o comportamento da instrução de impressão), você deve fazer uma importação futura:from __future__ import print_function
Jeff Mercado
O segundo exemplo irá de fato imprimir "Hello, World!" (sem o espaço) ou imprimirá "Hello, World!" (com o espaço) como no exemplo.
kapad de

Respostas:

106

Em Python 2.x printé realmente uma instrução especial e não uma função *.

É também por isso que não pode ser usado como: lambda x: print x

Observe que (expr)não cria uma tupla (resulta em expr), mas cria ,. Isso provavelmente resulta na confusão entre print (x)e print (x, y)no Python 2.7

(1)   # 1 -- no tuple Mister!
(1,)  # (1,)
(1,2) # (1, 2)
1,2   # 1 2 -- no tuple and no parenthesis :) [See below for print caveat.]

No entanto, como printé uma instrução de sintaxe / construção gramatical especial no Python 2.x, então, sem o parêntese, trata o de ,uma maneira especial - e não cria uma tupla. Este tratamento especial da printdeclaração permite que ela atue de forma diferente se houver um trailing ,ou não.

Boa codificação.


* Este printcomportamento em Python 2 pode ser alterado para Python 3:

from __future__ import print_function
user2357112 suporta Monica
fonte
3
Obrigado pela (expr) != tupleexplicação :-)
Hubro
5

É tudo muito simples e não tem nada a ver com compatibilidade com versões anteriores ou anteriores.

A forma geral da printdeclaração em todas as versões do Python antes da versão 3 é:

print expr1, expr2, ... exprn

(Cada expressão, por sua vez, é avaliada, convertida em uma string e exibida com um espaço entre elas.)

Mas lembre-se de que colocar parênteses em torno de uma expressão ainda é a mesma expressão.

Então, você também pode escrever isso como:

print (expr1), (expr2), ... (expr3)

Isso não tem nada a ver com chamar uma função.

Don O'Donnell
fonte
Esta é uma resposta perfeitamente correta, também não sei por que foi tão rejeitada.
Martijn Pieters
Não é sobre print (expr1), (expr2), ... (expr3), é sobre por que print (expr1, expr2, ... , expr3)é legal no python 2.x enquanto não deveria estar de acordo com os padrões 2.x.
vinnief
5

Aqui temos um efeito colateral interessante quando se trata de UTF-8.

>> greek = dict( dog="σκύλος", cat="γάτα" )
>> print greek['dog'], greek['cat']
σκύλος γάτα
>> print (greek['dog'], greek['cat'])
('\xcf\x83\xce\xba\xcf\x8d\xce\xbb\xce\xbf\xcf\x82', '\xce\xb3\xce\xac\xcf\x84\xce\xb1')

A última impressão é uma tupla com valores hexadecimais de bytes.

Karlo Smid
fonte
7
Presumo que seja porque print imprime UTF-8 corretamente, mas quando recebe uma tupla, como sua última impressão, ela é executada repre, nesse ponto, provavelmente codifica todas as strings no dicionário para ASCII.
Hubro de
3
@Codemonkey, você está certo sobre repr . Você está errado sobre ASCII. ASCII é a codificação padrão para Python. Mas eu tenho no início do script Python #encoding=utf-8, env do linux LANG=en_US.UTF-8. Portanto, reprodifique não usando ASCII padrão, mas a codificação utf-8.
Karlo Smid
1
Repr codifica strcom a string_escapecodificação especial . A string já estava codificada em Unicode como UTF-8.
tzot
@KarloSmid: O que eu quis dizer é que reprprovavelmente toma medidas para garantir que o texto possa ser representado por ASCII (por meio de símbolos de escape não ASCII), não necessariamente que a string seja codificada como ASCII. Ainda não sei se isso é totalmente correto.
Hubro
Todos os contêineres Python (lista, dict, tuple, set) incluem seu conteúdo como repr()saída quando convertidos em uma string (eles não implementam __str__, apenas __repr__). O que você vê não é especial para UTF-8; O repr()de uma string fornece literais de string Python válidos que são seguros para ASCII.
Martijn Pieters
2

Basicamente no Python antes do Python 3, print era uma instrução especial que imprimia todas as strings se obtidas como argumentos. Então, print "foo","bar"significa simplesmente "imprimir 'foo' seguido por 'bar'". O problema com isso era que era tentador agir como se print fosse uma função, e a gramática Python é ambígua quanto a isso, já que (a,b)é uma tupla contendo ae, bmas foo(a,b)é uma chamada para uma função de dois argumentos.

Então, eles fizeram a alteração incompatível para 3 para tornar os programas menos ambíguos e mais regulares.

(Na verdade, acho que o 2.7 se comporta como o 2.6 nisso, mas não tenho certeza.)

Charlie Martin
fonte
Não, não era "tentador" usá-lo como uma função. :) Porém, era impossível usá-lo como uma função, então você não pode fazer [print x for x in alist] por exemplo.
Lennart Regebro