¿Por qué los generadores y funciones de Python comparten la palabra clave "def"?

10

Considera lo siguiente:

def some_function():
    return 1

def some_generator():
    yield 1

En el código anterior, some_functiones una función, mientras que some_generatores un generador. Se ven bastante similares.

¡El problema que tengo al leer el código es que necesito escanear cada línea en una "función" buscando la yieldpalabra clave antes de poder determinar si realmente es una función o un generador!

Simplemente me parece que usar una palabra clave diferente para generadores tendría más sentido, por ejemplo:

gen some_generator():
    yield 1

¿Cuáles son los méritos de usar la defpalabra clave tanto para generadores como para funciones? ¿Por qué no se ha introducido una nueva palabra clave para separar funciones y generadores?

Derek Kwok
fuente
No sé la respuesta real, pero a menudo empiezo escribiendo funciones que devuelven listas, luego las convierto en generadores cuando parece correcto. Tener la coincidencia de sintaxis lo hace más natural.
Gort the Robot
2
La sugerencia de @StevenBurnap Derek de usar algo como en genlugar de defno haría que la transformación sea significativamente más onerosa.
jamesdlin
2
En general, los diseñadores de idiomas generalmente intentan evitar agregar palabras clave innecesarias. Cada palabra clave que agregan es un identificador que los programas no pueden usar para otros fines.
jamesdlin
@jamesdlin: Pero la pregunta es argumentar que sería necesaria una nueva palabra clave .
Giorgio
1
@jamesdlin: Por supuesto, puede distinguir funciones y generadores observando su cuerpo, pero la pregunta argumenta que el uso de diferentes palabras clave haría que el código sea más legible.
Giorgio

Respuestas:

14

"¿Cuáles son las ventajas de utilizar la palabra clave def para generadores y funciones?"

Si bien son mecánicamente diferentes, en la práctica, cuando los uso, a menudo son efectivamente los mismos para mí conceptualmente (no pienso mucho en llamar range()vs xrange()).

Sin embargo, en términos de comprender de qué se trata la función rápidamente, estoy de acuerdo en que algo se pierde con el uso de def, pero las cosas no deberían ofuscarse demasiado dentro de la función para empezar.

Incluso un implícito return Nonepuede confundir el comportamiento previsto de una función después de un largo período de condicionales (como en, fue un return Nonecomportamiento final o un descuido en la lógica). Pero esas son solo mis creencias al respecto.

Sin embargo, no creo que mi argumento sea particularmente convincente, por lo que me limitaré a remitirme a PEP 255 :

Problema: introduzca otra nueva palabra clave (por ejemplo, "gen" o "generador") en lugar de "def", o modifique la sintaxis para distinguir las funciones generadoras de las funciones no generadoras.

Con: En la práctica (cómo piensa sobre ellos), los generadores son funciones, pero con el giro de que son reanudables. La mecánica de cómo se configuran es un problema técnico comparativamente menor, y la introducción de una nueva palabra clave enfatizaría demasiado la mecánica de cómo se inician los generadores (una parte vital pero pequeña de la vida de un generador).

Pro: en realidad (cómo piensas sobre ellos), las funciones generadoras son en realidad funciones de fábrica que producen iteradores generadores como por arte de magia. A este respecto, son radicalmente diferentes de las funciones que no son del generador, actuando más como un constructor que como una función, por lo que reutilizar "def" es, en el mejor de los casos, confuso. Una declaración de "rendimiento" enterrada en el cuerpo no es suficiente para advertir que la semántica es tan diferente.

BDFL: "def" se queda. Ningún argumento en ambos lados es totalmente convincente, por lo que he consultado la intuición de mi diseñador de idiomas. Me dice que la sintaxis propuesta en la PEP es exactamente la correcta: ni demasiado caliente ni demasiado fría. Pero, como el Oráculo de Delphi en la mitología griega, no me dice por qué, así que no tengo una refutación de los argumentos en contra de la sintaxis de PEP. Lo mejor que se me ocurre (aparte de estar de acuerdo con las refutaciones ... ya hechas) es "FUD". Si esto hubiera sido parte del lenguaje desde el primer día, dudo mucho que hubiera aparecido en la página "Verrugas de pitón" de Andrew Kuchling.

cuaspas
fuente
1
Vale la pena señalar que los nuevos await(y async withy async forconstrucciones sintácticas) añadidas en PEP 492 , que funcionan muy similar a yield from, requieren la función que están acostumbrados a ser declarada usando async defen lugar de un solo def.
Feuermurmel
2
  1. Agregar nuevas palabras clave corre el riesgo de romper los programas existentes. Los diseñadores de idiomas generalmente intentan evitar agregar nuevas palabras clave, especialmente para las características del idioma agregadas después de que el idioma ya haya ganado cierta popularidad. Cada palabra clave que agregan es un identificador que los programas no pueden usar para otros fines, por lo que agregar una palabra clave podría romper los programas existentes. Los diseñadores de idiomas deben sopesar los beneficios de una nueva palabra clave frente a los costos.

  2. Dudo que definir una palabra clave separada para generadores tenga muchos beneficios. Comprender si un símbolo corresponde al nombre de una función o al nombre de un generador es algo que les importa a las personas que llaman, y las personas que llaman no deberían tener que (y a veces no pueden) ver qué palabra clave se usó para implementarla. Esa es la responsabilidad de mejores convenciones de nombres y documentación.

jamesdlin
fuente
1

Los generadores son funciones que evalúan perezosamente. Dado que son lo mismo en la base, tiene sentido que usen la misma palabra clave. Una opción podría ser usar un comentario para identificar cuál es cuál para una instancia dada:

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

def some_generator(): #This is a generator.
    yield 1
Ingeniero mundial
fuente
0

Supongo que es porque es más Pythonic, pero ¿qué sé? ;)

Realmente no creo que importe tanto. Es más fácil de recordar para mí porque no es necesario memorizarlos a ambos.

EDITAR: El PEP podría decir, podría investigar allí.

XiKuuKy
fuente
¡Gracias! De hecho, ¡la PEP sí lo dice! Ver PEP-255 para los pros / contras y la decisión final con respecto a una nueva palabra clave para generadores.
Derek Kwok
Con significado Pythonic: "¿Cómo se hace en Python"?
Giorgio