Perché la parentesi stampata è volontaria in Python 2.7?


98

In Python 2.7, entrambi i passaggi seguenti faranno lo stesso

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

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

Tuttavia quanto segue non lo farà

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

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

In Python 3.x la parentesi printè obbligatoria, essenzialmente rendendola una funzione, ma in 2.7 entrambi funzioneranno con risultati diversi. Cos'altro dovrei sapere printin Python 2.7?


7
In Python 2.x printè in realtà un'istruzione speciale, non una funzione. Questo è anche il motivo per cui non può essere utilizzato come lambda x: print xsegue : Nota che (expr)non crea una tupla (ne risulta expr), ma lo ,fa.

Presumo che il supporto per print come funzione e print come istruzione sia per mantenere la compatibilità con le versioni precedenti di python incoraggiando le persone a utilizzare la nuova sintassi per migrare verso python 3.
GWW

11
ps, Per abilitare la funzione di stampa in 2.7 (e non avere il comportamento dell'istruzione print), devi fare un'importazione futura:from __future__ import print_function
Jeff Mercado

Il secondo esempio stamperà infatti "Hello, World!" (senza spazio) o stamperà "Hello, World!" (con lo spazio) come nell'esempio.
Kapad

Risposte:


106

In Python 2.x printè in realtà un'istruzione speciale e non una funzione *.

Questo è anche il motivo per cui non può essere utilizzato come: lambda x: print x

Nota che (expr)non crea una tupla (ne risulta expr), ma lo ,fa. Questo probabilmente porta alla confusione tra print (x)e print (x, y)in 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.]

Tuttavia, poiché printè una dichiarazione di sintassi / costrutto grammaticale speciale in Python 2.x, quindi, senza parentesi, tratta i ,'s in un modo speciale - e non crea una tupla. Questo trattamento speciale della printdichiarazione le consente di agire in modo diverso se c'è un trailing ,o meno.

Buona codifica.


* Questo printcomportamento in Python 2 può essere modificato in quello di Python 3:

from __future__ import print_function

3
Grazie per la (expr) != tuplespiegazione :-)
Hubro

5

È tutto molto semplice e non ha nulla a che fare con la compatibilità in avanti o all'indietro.

La forma generale per l' printistruzione in tutte le versioni di Python prima della versione 3 è:

print expr1, expr2, ... exprn

(Ogni espressione a sua volta viene valutata, convertita in una stringa e visualizzata con uno spazio tra di loro.)

Ma ricorda che mettere parentesi attorno a un'espressione è sempre la stessa espressione.

Quindi puoi anche scrivere questo come:

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

Questo non ha nulla a che fare con la chiamata di una funzione.


Questa è una risposta perfettamente corretta, non sono sicuro nemmeno del motivo per cui sia stato votato così tanto.
Martijn Pieters

Non si tratta print (expr1), (expr2), ... (expr3), si tratta del motivo per cui print (expr1, expr2, ... , expr3)è legale in python 2.x mentre non dovrebbe essere conforme agli standard 2.x.
vinnief

5

Qui abbiamo un effetto collaterale interessante quando si tratta di 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')

L'ultima stampa è una tupla con valori di byte esadecimali.


7
Presumo sia perché print stampa correttamente UTF-8, ma quando riceve una tupla, come l'ultima stampa, viene eseguita reprsu di essa, a quel punto probabilmente codifica tutte le stringhe nel dict in ASCII.
Hubro

3
@Codemonkey, hai ragione su repr . Ti sbagli su ASCII. ASCII è la codifica predefinita per Python. Ma all'inizio dello script Python #encoding=utf-8, linux env LANG=en_US.UTF-8. Quindi repr codifica non utilizzando l'ASCII predefinito, ma la codifica utf-8.
Karlo Smid

1
Repr codifica strcon la string_escapecodifica speciale . La stringa era già codificata Unicode come UTF-8.
tzot

@KarloSmid: Quello che volevo dire era che reprprobabilmente prende provvedimenti per garantire che il testo possa essere rappresentato da ASCII (mediante caratteri di escape non ASCII), non necessariamente che la stringa sia codificata come ASCII. Non so ancora se sia completamente accurato.
Hubro

Tutti i contenitori Python (list, dict, tuple, set) includono il loro contenuto come repr()output quando convertiti in una stringa (non implementano __str__, solo __repr__). Quello che vedi non è speciale per UTF-8; il valore repr()di una stringa fornisce valori letterali stringa Python validi che sono ASCII-safe.
Martijn Pieters

2

Fondamentalmente in Python prima di Python 3, print era un'istruzione speciale che stampava tutte le stringhe se ottenute come argomenti. Quindi print "foo","bar"significava semplicemente "print 'foo' seguito da 'bar'". Il problema era che si era tentati di agire come se print fosse una funzione, e la grammatica Python è ambigua su questo, poiché (a,b)è una tupla contenente ae bma foo(a,b)è una chiamata a una funzione di due argomenti.

Quindi hanno apportato la modifica incompatibile per 3 per rendere i programmi meno ambigui e più regolari.

(In realtà, penso che 2.7 si comporti come 2.6 su questo, ma non ne sono sicuro.)


No, non era "allettante" usarlo come funzione. :) Tuttavia, era impossibile usarlo come funzione, quindi non puoi fare [print x for x in alist] per esempio.
Lennart Regebro
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.