Domanda

Questa domanda mi ha infastidito per un po '(come evidenziato da la mia domanda precedente ): perché esattamente print(x) è meglio (che è definito più pitonico) di print x?

Per chi non lo sapesse, l'istruzione print è stata cambiata in funzione in Python 3.0. La documentazione formale è in PEP 3105 e la motivazione è in Email di Guido van Rossum .

A quei punti vorrei fare un contrappunto:

  1. Ci sono altri operatori, come import che scriviamo come una dichiarazione, sebbene la loro funzionalità sia effettivamente duplicata con una funzione __import__
    • Per i principianti, l'operatore __print__ non appartiene alla logica generale dell'applicazione. Per loro è l'operatore misterioso che è il culmine del loro programma. Si aspettano che abbia un aspetto diverso.
    • Tutti i libri per principianti che descrivono Python 2.x di base ora sono garantiti per essere rotti dal primo esempio . Certamente, le lingue a volte cambiano, ma questi cambiamenti sono di solito meno visibili ai principianti.
    • Non è immediatamente ovvio per me che una funzionalità di <=> possa essere duplicata a livello di applicazione. Ad esempio, a volte vorrei reindirizzare la stampa da una console come una finestra di dialogo del sistema operativo modale.
    • Mentre le persone dicono che è difficile riscrivere tutte le <=> istruzioni in una funzione, hanno costretto tutti gli sviluppatori di Python 2.x a fare esattamente questo per tutti i loro progetti. Bene, non è difficile con il convertitore automatico.
    • Tutti coloro che amano avere la possibilità di manipolare la funzione <=> sarebbero altrettanto ben serviti se <=> fosse una funzione di wrapping delle istruzioni <=>.

Quindi, possiamo per favore avere una risposta canonica a questa domanda sulle pagine di Stack Overflow?

È stato utile?

Soluzione

Mi sembra che il tuo sia un dibattito, non una domanda - accetterai davvero una risposta che mostri quanto profondamente e gravemente hai sbagliato nelle tue affermazioni ?!

Passa ai punti di discussione:

  

Ci sono altri operatori, come   import che scriviamo come una dichiarazione,   sebbene la loro funzionalità sia effettivamente   duplicato con una funzione __import__

Assolutamente sbagliato: la funzione def (come ogni altra funzione - e l'operatore, del resto) lega nessun nomi nell'ambito di " & chiamante quot; (codice che lo contiene) - qualsiasi " thingie " che lega i nomi tra " ambito del chiamante " deve essere una dichiarazione (proprio come il compito, call e assert). Il tuo & Quot; punto & Quot; sembra mancare totalmente la distinzione estremamente profonda e cruciale che Python traccia tra affermazioni ed espressioni - si può ragionevolmente non amare questa distinzione, ma ignorare è, ovviamente, semplicemente sbagliato .

Le istruzioni Python sono cose di cui il compilatore Python deve essere specificamente consapevole - possono alterare l'associazione di nomi, possono alterare il flusso di controllo e / o potrebbero dover essere completamente rimossi dal bytecode generato in determinate condizioni (quest'ultimo si applica a print). import this era la unica eccezione a questa affermazione in Python 2; rimuovendolo dalla lista di istruzioni, Python 3 rimuove un'eccezione, fa l'asserzione generale " basta tenere " ;, e quindi è un linguaggio più regolare. I casi speciali non sono abbastanza speciali da infrangere le regole è da tempo un principio Pythonic (fare >>> al prompt sys.stdout di un interprete interattivo per vedere " lo Zen di Python " visualizzato) e questa modifica alla lingua rimuove una violazione di questo principio che è dovuto rimanere per molti anni a causa di una decisione di progettazione errata in anticipo.

  

Ai principianti, la stampa dell'operatore lo fa   non appartengono all'applicazione generale   logica. Per loro è il misterioso   operatore che è il culmine di   il loro programma. Si aspettano che appaia   in modo diverso.

Curare i principianti delle loro idee sbagliate non appena possibile è un'ottima cosa.

  

Tutti i libri per principianti che erano   la descrizione di base di Python 2.x è ora   garantito per essere rotto dal pugno   esempio. Certamente, le lingue   a volte cambia, ma i cambiamenti lo sono   di solito meno visibile ai novizi.

Le lingue raramente cambiano in modi profondamente incompatibili con le versioni precedenti (Python lo fa circa una volta ogni dieci anni) e poche funzionalità linguistiche sono " altamente visibile ai novizi " ;, quindi il numero totale di osservazioni è piccolo - ma anche all'interno di quella minuscola bussola possiamo facilmente trovare contro-esempi, in cui una funzione altamente visibile ai principianti è stata progettata così male che la rimozione è valsa la pena disturbare. Ad esempio, i dialetti moderni di Basic, come Visual Basic di Microsoft, non usano numeri di riga espliciti immessi dall'utente, una & Quot; feature & Quot; era sia terribile che altamente visibile a tutti, dato che era obbligatorio nei primi dialetti di Basic. Le moderne varianti di Lisp (dallo Scheme in poi) non usano lo scoping dinamico, un malfunzionamento che era tristemente altamente visibile (di solito manifestandosi come bug difficili da capire nel loro codice) per i principianti, fondamentalmente non appena hanno iniziato a scrivere funzioni in Lisp 1.5 (una volta ero un principiante in questo e posso testimoniare di quanto mi abbia morso).

  

Non è immediatamente ovvio per me   che può essere una funzionalità di stampa   duplicato a livello di applicazione.   Ad esempio, a volte vorrei   reindirizzare la stampa da una console come a   finestra di dialogo del sistema operativo modale.

Non sono sicuro di seguire questo " punto " ;. Basta cambiare 2to3 sul tuo oggetto pseudo-file preferito e reindirizzare al contenuto del tuo cuore - hai opzione di scimmia rattoppare la funzione integrata __print__ (che non hai mai avuto in Python 2), ma nessuno ti torce il braccio e ti obbliga a farlo.

  

Mentre la gente dice che è difficile riscrivere   tutte le istruzioni di stampa su una funzione,   hanno forzato ogni Python 2.x   lo sviluppatore deve fare esattamente questo per tutti   i loro progetti. Bene, non è difficile   con convertitore automatico.

Lo strumento >> myfile si prende davvero cura di tutte queste incompatibilità superficiali così facili - senza sudore (e deve essere eseguito comunque per occuparsene un po 'di più oltre a <=>, quindi le persone lo usano ampiamente) . Quindi, qual è il tuo & Quot; punto & Quot; qui?

  

Tutti quelli a cui piace avere un'abilità   per manipolare la funzione di stampa sarebbe   altrettanto ben servito se la stampa fosse a   funzione di a capo automatico stampa .

Un simile accordo non eliminerebbe di per sé una parola chiave non necessaria (e soprattutto una irregolarità ingiustificata , come ho spiegato sopra: un'affermazione che ha no motivo per essere una dichiarazione perché non è assolutamente necessario che il compilatore ne sia particolarmente consapevole in alcun modo, forma o forma!). Per me è tutt'altro che chiaro che avere una tale funzione sottostante aggiunga un valore reale, ma se hai casi d'uso reali puoi certamente proporre il caso nella mailing list di Python Ideas - una tale funzione sottostante, se dimostrata davvero preziosa , potrebbe essere adattato per essere utilizzato dall'istruzione <=> in Python 2.7 nonché dalla funzione <=> in Python 3.2.

Tuttavia, prendi in considerazione un caso tipico in cui potresti voler applicare una patch scimmia al <=> incorporato: aggiungere argomenti per parole chiave per consentire modifiche fantasiose. In che modo la funzione <=> che apparentemente ti viene proposta potrebbe mai generare quegli argomenti KW da un'istruzione <=>? Qualche sintassi più divertente ancora degli orrori di <=> e della virgola finale ...?! Con <=> come funzione, gli argomenti delle parole chiave seguono solo le regole perfettamente normali e ordinarie che si applicano a ogni funzione e chiamata di funzione - felicità!

Quindi, in sintesi, è più Pythonic per <=> essere una funzione perché rimuove anomalie, casi speciali e qualsiasi necessità di strana sintassi eccezionale: semplicità, regolarità e uniformità sono il marchio di Python.

Altri suggerimenti

Ecco il motivo per cui odio l'istruzione print in 2.x.

>>> something()
<something instance at 0xdeadbeef>
>>> print something()
<something instance at 0xdeadbeef>

l'oggetto senza valore non ha utili __str__, bene, posso occuparmene, guardalo ancora.

>>> dir(something())
['foo', 'bar', 'baz', 'wonderful']
>>> help(something().foo)
"foo(self, callable)"

hmm .. quindi quel callable accetta argomenti?

>>> something().foo(print)
    something().foo(print)
                        ^
SyntaxError: invalid syntax
>>> something().foo(lambda *args: print(*args))
    something().foo(lambda *args: print(*args))
                                      ^
SyntaxError: invalid syntax

Quindi ... Devo definire una funzione da usare

>>> def myPrint(*args): print *args
    def myPrint(*args): print *args
                              ^
SyntaxError: invalid syntax
>>> def myPrint(*args): print args
...
>>> myPrint(1)
(1,)

Shudder, o usa sys.stdout.write, che è quasi altrettanto maldestro, poiché ha un comportamento molto diverso da print. Inoltre sembra diverso, il che significa che non ricorderò quasi mai che esiste.

L'uso di <=> istruzioni in una funzione di tipo breve e una tantum e quindi migliorarlo per utilizzare la registrazione o qualcosa di meglio è semplicemente inelegante. Se la stampa funzionasse in questo modo, e in particolare potesse essere utilizzata con funzioni di ordine elevato, sarebbe meglio della cosa che usi quando non usi la registrazione reale o reale debugger.

L'istruzione print porta anche l'insolita sintassi >> per la stampa su un file specifico. In Python non esiste un'altra affermazione che abbia questa sintassi, quindi è insolito in questo modo.

Credo che tu abbia ragione, tuttavia, la maggior parte dei problemi con l'istruzione __print__ avrebbe potuto essere risolta con l'introduzione di una funzione <=>.

Ho trovato il " di GvR; print è l'unica funzionalità a livello di applicazione che ha una dichiarazione ad esso dedicata! " convincente. Python è un linguaggio generico e non dovrebbe avere un'istruzione per essere inviato a uno stream come operatore o parola chiave.

Non è pitonico perché la sintassi dovrebbe essere:

stdout.append("Hello World")

o

stdout += "hello world"

Dichiarazione di non responsabilità: mi piace davvero Python.

Su una nota seria ...

Penso che il modello a oggetti di Python e l'approccio 'Implementalo tu stesso' a cose come la visibilità degli attributi sia fantastico. Penso che questo approccio "tutto sia un oggetto" a OOP, e anche gli oggetti definiti come una raccolta di strutture di oggetti siano molto chiari.

Quello che temo che Python farà è diventare un linguaggio che non presenta le sue intenzioni in modo chiaro ... e odio vedere la bellezza dei principi impantanarsi nel pensare troppo alla presentazione della sintassi già non convenzionale . Un po 'come Lisp , bello nella sua struttura, torvo, imho nella sua sintassi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top