Perché i generatori e le funzioni di Python condividono la parola chiave "def"?


10

Considera quanto segue:

def some_function():
    return 1

def some_generator():
    yield 1

Nel codice sopra, some_functionè una funzione, mentre some_generatorè un generatore. Sembrano abbastanza simili.

Il problema che ho durante la lettura del codice è che ho bisogno di scansionare ogni riga in una "funzione" cercando la yieldparola chiave prima di poter determinare se è effettivamente una funzione o un generatore!

Mi sembra che usare una parola chiave diversa per generatori avrebbe più senso, ad esempio:

gen some_generator():
    yield 1

Quali sono i vantaggi dell'utilizzo della defparola chiave sia per i generatori che per le funzioni? Perché non è stata introdotta una nuova parola chiave per separare funzioni e generatori?


Non conosco la vera risposta, ma spesso inizio a scrivere funzioni che restituiscono elenchi, per poi convertirli in generatori quando sembra giusto. Avere la corrispondenza della sintassi rende tutto più naturale.
Gort il robot il

2
@StevenBurnap Il suggerimento di Derek di usare qualcosa del genere geninvece di defrendere questa trasformazione significativamente più onerosa.
Jamesdlin,

2
In generale, i progettisti di lingue di solito cercano di evitare l'aggiunta di parole chiave non necessarie. Ogni parola chiave che aggiungono è un identificatore che i programmi non possono utilizzare per altri scopi.
Jamesdlin,

@jamesdlin: Ma la domanda è sostenere che sarebbe necessaria una nuova parola chiave .
Giorgio,

1
@jamesdlin: Ovviamente puoi distinguere funzioni e generatori guardando il loro corpo, ma la domanda sostiene che l'uso di parole chiave diverse renderebbe il codice più leggibile.
Giorgio,

Risposte:


14

"Quali sono i vantaggi dell'utilizzo della parola chiave def sia per i generatori che per le funzioni?"

Mentre sono meccanicamente diversi, in pratica quando li uso sono spesso ugualmente concettualmente uguali per me (non penso molto a chiamare range()vs xrange()).

In termini di comprensione della funzione rapida, però, sono d'accordo che qualcosa si perde con l'uso di def, ma le cose non dovrebbero essere troppo offuscate all'interno della funzione per cominciare.

Anche un implicito return Nonepuò confondere il comportamento previsto di una funzione dopo un lungo po 'di condizionali (come in, era return Noneinteso come un comportamento finale o una svista nella logica). Ma quelli sono solo le mie convinzioni al riguardo.

Non credo che il mio argomento sia particolarmente convincente, quindi rimanderò al PEP 255 :

Problema: introdurre un'altra nuova parola chiave (ad esempio "gen" o "generatore") al posto di "def", o modificare in altro modo la sintassi, per distinguere le funzioni del generatore dalle funzioni non del generatore.

Contro: in pratica (come ci pensi), i generatori sono funzioni, ma con la svolta che sono riprendibili. La meccanica di come sono configurati è un problema tecnico relativamente minore e l'introduzione di una nuova parola chiave avrebbe inutilmente enfatizzato la meccanica di come i generatori iniziano (una parte vitale ma minuscola della vita di un generatore).

Pro: In realtà (come ci pensi), le funzioni del generatore sono in realtà funzioni di fabbrica che producono generatori-iteratori come per magia. A questo proposito sono radicalmente diversi dalle funzioni non generatrici, comportandosi più come un costruttore che come una funzione, quindi riutilizzare "def" è nella migliore delle ipotesi confuso. Un'affermazione "resa" sepolta nel corpo non è sufficiente per avvertire che la semantica è così diversa.

BDFL: "def" rimane. Nessun argomento su entrambi i lati è del tutto convincente, quindi ho consultato l'intuizione del mio designer linguistico. Mi dice che la sintassi proposta nel PEP è esattamente giusta - non troppo calda, non troppo fredda. Ma, come l'Oracolo di Delfi nella mitologia greca, non mi dice perché, quindi non ho una confutazione per gli argomenti contro la sintassi del PEP. Il meglio che posso inventare (oltre a concordare con le confutazioni ... già fatte) è "FUD". Se questo fosse stato parte del linguaggio fin dal primo giorno, dubito fortemente che avrebbe reso la pagina "Python Warts" di Andrew Kuchling.


1
Vale la pena notare che i nuovi await(e async withe async for) costrutti sintattici aggiunti nel PEP 492 , che funzionano molto simile a yield from, richiedono la funzione sono abituati a essere dichiarati utilizzando async defal posto di un solo def.
Feuermurmel,

2
  1. L'aggiunta di nuove parole chiave rischia di rompere i programmi esistenti. I progettisti di lingue generalmente cercano di evitare l'aggiunta di nuove parole chiave, in particolare per le funzionalità linguistiche aggiunte dopo che la lingua ha già guadagnato una certa popolarità. Ogni parola chiave che aggiungono è un identificatore che i programmi non possono utilizzare per altri scopi, quindi l'aggiunta di una parola chiave potrebbe potenzialmente interrompere i programmi esistenti. I progettisti linguistici devono valutare i vantaggi di una nuova parola chiave rispetto ai costi.

  2. Dubito che la definizione di una parola chiave separata per i generatori avrebbe molti vantaggi. Capire se un simbolo corrisponde al nome di una funzione o al nome di un generatore è qualcosa che conta per i chiamanti e i chiamanti non dovrebbero (e talvolta non possono) guardare quale parola chiave è stata utilizzata per implementarlo. Questa è la responsabilità di convenzioni e documentazione sui nomi migliori.


1

I generatori sono funzioni che valutano pigramente. Dato che sono la stessa cosa alla base, ha senso che userebbero la stessa parola chiave. Un'opzione potrebbe essere quella di utilizzare un commento per identificare quale è quale per una determinata istanza:

def some_function(): #This is a function.
    return 1

def some_generator(): #This is a generator.
    yield 1

0

Immagino che sia perché è più Pythonic ma cosa ne so? ;)

Non penso davvero che sia così importante. È più facile da ricordare per me perché non è necessario memorizzarli entrambi.

EDIT: il PEP potrebbe dire, potresti indagare lì.


Grazie! In effetti, dice il PEP! Vedi PEP-255 per i pro / contro e la decisione finale riguardo a una nuova parola chiave per generatori.
Derek Kwok il

Con significato Pythonic: "Il modo in cui è fatto in Python"?
Giorgio,
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.