Quali sono alcune caratteristiche di Python che lo rendono unico come lingua propria? [chiuso]


12

Quali sono alcune caratteristiche di Python che lo rendono unico come lingua propria? Sto cercando qualsiasi tipo di caratteristiche che vanno da buone a cattive, utili a ostacoli, sintassi per l'uso nel mondo reale, ma osservazioni non oscure sarebbero le più utili per lo sviluppatore medio.

Sono un principiante qui, quindi potrebbe essere necessario spiegare cose intuitive .....


9
Python non è univoco, non contiene una singola funzione unica non visibile in nessun'altra lingua.
SK-logic,

10
È l'unica lingua che conosco che prende il nome da Monty Python ...
yannis il

@ SK-logic la domanda riguarda le caratteristiche, di cui le funzioni sono un sottoinsieme. Non ci sono caratteristiche uniche di Python?
Kojiro,

@kojiro, non ho mai visto una definizione formale di "caratteristica", quindi preferirei non indovinare.
SK-logic,

1
@kojiro, le funzionalità PL sono normalmente intese sia come sintassi che come semantica. Ed entrambi sono definiti formalmente.
SK-logic,

Risposte:


22

Avrai difficoltà a trovare funzionalità assolutamente uniche . La maggior parte delle caratteristiche linguistiche esistenti sono state adottate in più di una lingua sin dal loro inizio. Alcuni possono essere più rari, soprattutto perché sono nuovi o ancora nell'oscurità o sono morti per una buona ragione. Tuttavia, anche in questo caso sarebbe meglio guardare le combinazioni di funzionalità.

Detto questo, diverse funzionalità di Python dovrebbero creare una combinazione relativamente unica. Almeno non conosco le lingue da remoto come popolari (e pratiche) con un set di funzionalità per lo più sovrapposte. Come notato nei commenti, Ruby è piuttosto vicino, ma ci sono comunque numerose differenze.

  • Metaprogrammazione basata su metaclasse . Fondamentalmente, eseguendo il codice arbitrario sulla creazione della classe. Rende molto piacevole personalizzazione classe con molto poco lavoro sulla fine recieving - ad esempio per un object-relational mapping (ORM), le classi client possono essere scritte come al solito con poche righe extra come attr = SomeDataType()e una tonnellata di codice viene generato automaticamente. Un esempio di questo sono i "modelli" di Django .
  • Sei incoraggiato a usare iteratori per tutto . Ciò è particolarmente evidente in 3.x, dove la maggior parte delle alternative basate su elenchi con un equivalente basato su iteratore sono state abolite a favore di quest'ultima. Gli iteratori fungono anche da interfaccia quasi universale per le raccolte (sia quelle che hai effettivamente in memoria sia quelle che hai bisogno solo una volta e quindi creare con le funzionalità seguenti). Agnostico nella raccolta, efficiente O(1)nello spazio (lo spazio per i risultati intermedi spesso segue naturalmente, pochissime attività hanno effettivamente bisogno di tutti gli elementi in memoria contemporaneamente), lo scricchiolio dei dati compostabili non è mai stato più facile.
  • Espressioni del generatore, correlate a quanto sopra. Molti avranno sentito parlare della comprensione dell'elenco (creando un elenco da un altro iterabile, filtrando e mappando nel processo, con una sintassi molto conveniente). Dimenticati di loro, sono zucchero sintattico, un caso speciale. Le espressioni del generatore sono molto vicine in modo sintattico e alla fine portano alla stessa sequenza di elementi, ma producono pigramente risultati (e quindi occupano O(1)spazio a meno che non si mantengano esplicitamente i risultati).
  • yield, che rendono molto più piacevole la scrittura di iteratori (qui chiamati generatori). Sono il fratello maggiore di quanto sopra, supportando tutti i tipi di flusso di controllo. C # ha qualcosa di simile, con la stessa parola chiave. Ma yieldè anche sovraccarico di supportare un tipo limitato di coroutine (Lua ad esempio ha un supporto più elaborato) che è stato comunque sfruttato da persone intelligenti che lavorano su problemi difficili. Due esempi dalla parte superiore della mia testa: analisi di discesa ricorsiva con backtracing e nessun limite di stack e I / O asincroni (con sintassi conveniente).
  • Assegnazione multi-target e disimballaggio iterabile. Cessione su steroidi. Non solo puoi assegnare più valori contemporaneamente (anche per lo scambio di valori e durante l'iterazione - for key, value in mapping.items()), puoi decomprimere qualsiasi iterabile di lunghezza nota (onestamente, principalmente tuple) in più variabili. Dal 3.x è ancora pratico per le collezioni di lunghezza sconosciuta, come è possibile specificare alcune variabili prendendo elementi singoli e una presa di ciò che rimane: first, *everything_in_between, last = values.
  • Descrittori , probabilmente il più potente tra i vari modi per personalizzare l'accesso agli attributi. Ci sono proprietà (come in C #, ma senza supporto linguistico speciale), metodi statici, metodi di classe, ecc. Tutti implementati come descrittori. Sono anche oggetti di prima classe. Solo una settimana fa, ho dovuto affrontare codice ripetitivo e complicato nelle proprietà, quindi ho scritto una piccola funzione che genera la parte ripetitiva e la avvolge in un properyoggetto.
  • Regola puramente fuorigioco (indentaion per la delimitazione dei blocchi). L'ho messo intenzionalmente per ultimo. Mentre distingue Python, non si distingue nella programmazione quotidiana una volta che ci sei abituato (o almeno questa è la mia esperienza).

Sono ancora un po 'alle prime armi con Ruby ma penso che colpisca anche tutti tranne l'ultimo punto? Ad ogni modo, sono d'accordo che "unico" probabilmente non sarà trovato in Python, ma "non è comune tra le altre lingue principali".
Rig

@Rig: Non sono un esperto di Ruby, ma non ho visto né metaclassi (Ruby certamente altrettanto potente per quanto riguarda la metaprogrammazione, e potrei usarlo per scopi simili, ma la mia impressione è stata che sia ottenuto in modo diverso), né generatori né espressioni di generatori (anche se sembrano esserci coroutine), né disomogeneo disimballaggio (c'è comunque assegnazione multi-target) né descrittori in Ruby. Sì, Ruby e Python si sovrappongono. Ma ci sono differenze .

Buono, +1. Per me, "l'assegnazione su steroidi" è in realtà "corrispondenza del modello dei poveri", ma è incredibilmente utile comunque :) Noterei anche quanto sia flessibile il passaggio dei parametri nelle funzioni: *argse **kwargs, un modo indolore per mappare tuple e dadi a parametri, ecc. .
9000

Credo che il lisp comune con CLOS raggiunga tutti i punti tranne l'uso della sintassi basata sul layout. Haskell non è orientato agli oggetti (anche se ci sono estensioni OO) ma a parte il punto metaclasse credo che corrisponda a tutte queste funzionalità.
Jules

3

Immagino che l'unica cosa che rende Python unica sia la particolare combinazione di funzionalità che espone. Questo sarebbe vero per la maggior parte dei linguaggi di programmazione.

Oppure potrebbe esserci una piccola cosa: non ho visto il modo in cui Python passa esplicitamente selfcome parametro formale alle funzioni dei membri degli oggetti eseguite in qualsiasi altro linguaggio. È una cosa piccola e non vedo come questo cambi qualcosa in realtà.

Ma non sono molto fluente in Python, quindi ci potrebbero essere delle cose che mi mancano di sicuro!


@delnan: Ah, mi sono perso "passare esplicitamente come parametro formale" .. Immagino sia quello che ottengo leggendo alle 2 del mattino;)
Demian Brecht,

4
L'auto esplicita si verifica anche in Oberon, FWIW
grrussel

Un parametro auto esplicito viene utilizzato anche nel sistema a oggetti lisp comune. CLOS fornisce multi-metodi, tuttavia, il che significa che il parametro self non è in alcun modo speciale, come in Python.
Jules

1

L'elaborazione automatica di dotstring per diventare proprietà del loro proprietario. In generale, tutte le brillanti funzionalità di introspezione di Python lo rendono un linguaggio davvero unico, dalla capacità di usare help () alla capacità di usare __doc__come proprietà di prima classe di un oggetto. Per esempio:

>>> class DocStringException(Exception):
...     """Error message is the same as docstring"""
...     def __str__(self):
...         return repr(self.__doc__)
... 
>>> class ExampleException(DocStringException):
...     """An example happened"""
... 
>>> raise ExampleException
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.ExampleException: 'An example happened'

Altre utili funzionalità di introspezione:

  • help / help () - aiuto con l'interprete / aiuto con un oggetto
  • parole chiave - parole chiave di Python
  • locals (): ottieni i nomi locali
  • globals (): ottieni i nomi globali
  • dir () - ottiene le proprietà e i metodi di un oggetto
  • il metodo .mro. , issubclass - comprensione dell'eredità
  • id () - ottiene l'indirizzo di memoria di un oggetto

Ruby ha praticamente lo stesso potere, così come Common Lisp, Clojure e molti altri linguaggi dinamici, credo.
Torbjørn,

@ Torbjørn quale potere? La documentazione automatica o le funzionalità di introspezione?
Kojiro,

Stavo pensando a entrambi. Non esattamente la parola, ma nello spirito. Non credo che Ruby abbia le stesse capacità di documentazione, ma sicuramente l'introspezione. CL e Clojure hanno entrambe le caratteristiche - e credo che l'introspezione vada ben oltre ciò che troverai in Python, dal momento che è omoiconico .
Torbjørn,

1
  1. Generator Expressions
  2. input()Lasciatemi spiegare, non ho visto una lingua (finora), in cui è possibile assegnare un valore a un'istruzione che stampa qualcosa, è come ruby print/gets, ma con un valore assegnato alla stampa, invece di:print "Foo" bar = gets
  3. yield
  4. Molti tipi di set di dati: ordereddict, namedtuple, array, list, tuple, dictionary

Le espressioni del generatore possono essere implementate in Haskell usando la comprensione degli elenchi (gli elenchi di Haskell sono pigri, a differenza degli elenchi di Python, quindi non è necessaria una sintassi specifica per questo). Per "input" suppongo che intendi la funzione python 3 con quel nome (poiché la funzione python 2 è pericolosa e non dovrebbe essere usata). È vero che questa è una combinazione insolita di comportamento (anche se è presente in javascript - window.prompt - e BASIC, che è il luogo in cui suppongo che Python lo abbia preso in prestito) ma può essere implementato banalmente dal programmatore ("input s = putStrLn s >> getStrLn "lo farà per haskell).
Jules

Un linguaggio pigro come Haskell non ha davvero bisogno di resa: può semplicemente restituire un elenco creato usando i soliti metodi e gli articoli saranno generati su richiesta. Nonostante ciò, la biblioteca include un'implementazione esplicita di coroutine. La libreria standard Haskell contiene tutte le strutture dati menzionate e molte altre.
Jules

-2

Il fatto è che Python è tra i pochissimi linguaggi con un sovraccarico sintattico estremamente basso che gli conferisce enormi poteri espressivi: comprensione di elenchi / set / dettati, resa, decoratori, valutazione, programmazione di meta classi, introspezione, strutture di dati integrate ottimizzate (elenchi, dicts, set), tutte queste cose cospirano in un modo molto carino per darti (lo sviluppatore) il potere di esprimere i tuoi pensieri in un codice conciso ed elegante quasi più velocemente che puoi pensare. Non riesco davvero a pensare ad altre lingue con questo set di funzionalità killer combinato.


1
Se pensi che Python abbia un basso sovraccarico sintattico (nonostante abbia una grammatica oscenamente complicata e una quantità relativamente grande di zucchero di sintassi), cosa pensi di Scheme?
Tikhon Jelvis,

Eval in realtà non dovrebbe essere usato per nessun programma di produzione (anche se concedo che può essere utile per trucchi veloci). Come mostrato nei commenti per altre domande, Python non è assolutamente unico nell'avere queste funzionalità. Credo, ad esempio, che il clojure abbia tutte le caratteristiche che elenchi, e la maggior parte può essere fatta con lisp comune.
Jules

-4

Direi che è uso del rientro per racchiudere dichiarazioni e cicli. Non l'ho visto in nessun'altra lingua.

Penso che sia molto utile perché rende significativamente più difficile offuscare il codice Python!

Sembra anche funzionare in maniera ordinata riga per riga, ad eccezione delle funzioni, e può essere interpretato come tale, il che è carino.


2
Wikipedia conosce anche uno schermo pieno di lingue. Si chiama la regola del fuorigioco .

3
Non capisco Sembra anche eseguire in modo ordinato riga per riga con l'eccezione delle funzioni, e può essere interpretato anche come tale, il che è bello. Cosa significa?
Kojiro,
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.