Perché i generatori e le funzioni 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 quando leggo il codice è che ho bisogno di scansionare ogni riga di una "funzione" cercando la parola chiave yield prima di poter determinare se si tratta effettivamente di una funzione o di un generatore!

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

gen some_generator():
    yield 1

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

    
posta Derek Kwok 28.01.2015 - 04:13
fonte

4 risposte

13

"Quali sono i vantaggi dell'uso della parola chiave def per entrambi i generatori e le funzioni?"

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

Per quanto riguarda la comprensione della funzione, però, concordo che qualcosa è andato perso con l'uso di def , ma le cose non dovrebbero essere troppo offuscate all'interno della funzione per cominciare.

Anche un% implicito% co_de può confondere il comportamento previsto di una funzione dopo un lungo bit di condizionali (come in, era un return None inteso come un comportamento finale o una svista nella logica). Ma quelli sono solo le mie credenze al riguardo.

Non ritengo che la mia argomentazione sia particolarmente convincente, quindi mi limiterò a PEP 255 :

Issue: Introduce another new keyword (say, "gen" or "generator") in place of "def", or otherwise alter the syntax, to distinguish generator-functions from non-generator functions.

Con: In practice (how you think about them), generators are functions, but with the twist that they're resumable. The mechanics of how they're set up is a comparatively minor technical issue, and introducing a new keyword would unhelpfully overemphasize the mechanics of how generators get started (a vital but tiny part of a generator's life).

Pro: In reality (how you think about them), generator-functions are actually factory functions that produce generator-iterators as if by magic. In this respect they're radically different from non-generator functions, acting more like a constructor than a function, so reusing "def" is at best confusing. A "yield" statement buried in the body is not enough warning that the semantics are so different.

BDFL: "def" it stays. No argument on either side is totally convincing, so I have consulted my language designer's intuition. It tells me that the syntax proposed in the PEP is exactly right - not too hot, not too cold. But, like the Oracle at Delphi in Greek mythology, it doesn't tell me why, so I don't have a rebuttal for the arguments against the PEP syntax. The best I can come up with (apart from agreeing with the rebuttals ... already made) is "FUD". If this had been part of the language from day one, I very much doubt it would have made Andrew Kuchling's "Python Warts" page.

    
risposta data 28.01.2015 - 04:49
fonte
2
  1. I progettisti di lingue cercano in genere di evitare l'aggiunta di nuove parole chiave, in particolare per le funzionalità linguistiche aggiunte dopo che la lingua ha già acquisito una certa popolarità. Ogni parola chiave che aggiungono è un identificatore che i programmi non sono autorizzati a utilizzare per altri scopi, quindi l'aggiunta di una parola chiave potrebbe potenzialmente interrompere i programmi esistenti. I progettisti di linguaggi devono valutare i vantaggi di una nuova parola chiave rispetto ai costi.

  2. Per capire se un simbolo corrisponde al nome di una funzione o al nome di un generatore è qualcosa che interessa ai chiamanti, e chi chiama non dovrebbe (a volte non può) guardare quale parola chiave è stato utilizzato per implementarlo. Questa è la responsabilità di migliori convenzioni di denominazione e documentazione.

risposta data 17.01.2016 - 21:49
fonte
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 è per una determinata istanza:

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

def some_generator(): #This is a generator.
    yield 1
    
risposta data 28.01.2015 - 04:19
fonte
0

Direi che è perché è più Pythonic ma cosa so? ;)

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

EDIT: il PEP potrebbe dire che puoi investigare lì.

    
risposta data 28.01.2015 - 04:27
fonte

Leggi altre domande sui tag