Почему генераторы и функции python используют ключевое слово «def»?


10

Учтите следующее:

def some_function():
    return 1

def some_generator():
    yield 1

В приведенном выше коде some_functionэто функция, а some_generatorявляется генератором. Они выглядят очень похоже.

Проблема, с которой я сталкиваюсь при чтении кода, заключается в том, что мне нужно просмотреть каждую строку в «функции» в поисках yieldключевого слова, прежде чем я смогу определить, является ли оно на самом деле функцией или генератором!

Мне просто кажется, что использование другого ключевого слова для генераторов имело бы больше смысла, например:

gen some_generator():
    yield 1

Каковы преимущества использования defключевого слова для генераторов и функций? Почему новое ключевое слово не было введено для разделения функций и генераторов?


Я не знаю реального ответа, но я часто начинаю писать функции, которые возвращают списки, а затем конвертируют в генераторы, когда это кажется правильным. Наличие совпадения синтаксиса делает это более естественным.
Gort the Robot

2
@ StevenBurnap Предложение Дерека использовать нечто подобное genвместо того, defчтобы сделать это преобразование значительно более обременительным.
Джеймсдлин

2
Обычно разработчики языка стараются избегать добавления ненужных ключевых слов. Каждое ключевое слово, которое они добавляют, является идентификатором, который программы не могут использовать для других целей.
Джеймсдлин

@jamesdlin: Но вопрос в том, что новое ключевое слово будет необходимо .
Джорджио

1
@jamesdlin: Конечно, вы можете различать функции и генераторы, глядя на их тело, но вопрос состоит в том, что использование разных ключевых слов сделает код более читабельным.
Джорджио

Ответы:


14

"Каковы преимущества использования ключевого слова def для генераторов и функций?"

Хотя они механически различны, на практике, когда я их использую, они часто концептуально для меня одинаковы (я не особо думаю о вызовах range()против xrange()).

С точки зрения понимания, что такое функция быстро, я согласен, что с использованием чего-то теряется def, но вещи не должны быть слишком запутанными внутри функции для начала.

Даже неявное return Noneможет привести к путанице в предполагаемом поведении функции после долгих условных return Noneвыражений (например, было задумано как конечное поведение или недосмотр в логике). Но это всего лишь мое мнение об этом.

Я не чувствую, что мой аргумент особенно убедителен, поэтому я просто отложу рассмотрение до 255 :

Проблема: введите другое новое ключевое слово (скажем, «gen» или «generator») вместо «def» или иным образом измените синтаксис, чтобы отличать функции генератора от функций, не являющихся генераторами.

Против: На практике (как вы к ним относитесь) генераторы - это функции, но с той неожиданностью, что они возобновимы. Механика их установки - сравнительно небольшая техническая проблема, и введение нового ключевого слова бесполезно переоценивает механику начала работы генераторов (жизненно важная, но крошечная часть жизни генератора).

Pro: На самом деле (как вы о них думаете), функции-генераторы на самом деле являются фабричными функциями, которые производят итераторы-генераторы, как по волшебству. В этом отношении они радикально отличаются от функций, не являющихся генераторами, и действуют скорее как конструктор, чем как функция, поэтому повторное использование «def» в лучшем случае сбивает с толку. Утверждение «yield», скрытое в теле, не является достаточным предупреждением о том, что семантика настолько различна.

BDFL: «def» остается. Никакие аргументы с обеих сторон не являются полностью убедительными, поэтому я обратился к интуиции моего дизайнера языков. Это говорит мне, что синтаксис, предложенный в PEP, абсолютно правильный - не слишком горячий и не слишком холодный. Но, как и Oracle в Delphi в греческой мифологии, он не говорит мне, почему, поэтому у меня нет опровержения аргументов против синтаксиса PEP. Лучшее, что я могу придумать (кроме того, что согласен с опровержениями ... уже сделано), это "FUD". Если бы это было частью языка с первого дня, я очень сомневаюсь, что это сделало бы страницу Эндрю Кучлинга "Python Warts".


1
Стоит отметить, что новые awaitasync withи async for) синтаксические конструкции, добавленные в PEP 492 , которые работают очень похоже yield from, требуют объявления функции, в которой они используются, async defа не просто def.
Feuermurmel

2
  1. Добавление новых ключевых слов рискует сломать существующие программы. Разработчики языка обычно стараются избегать добавления новых ключевых слов, особенно для языковых функций, добавленных после того, как язык уже приобрел некоторую популярность. Каждое ключевое слово, которое они добавляют, является идентификатором, который программам запрещено использовать для других целей, поэтому добавление ключевого слова может потенциально сломать существующие программы. Языковые дизайнеры должны сопоставить преимущества нового ключевого слова с затратами.

  2. Я сомневаюсь, что определение отдельного ключевого слова для генераторов принесло бы большую пользу. Понимание того, соответствует ли символ имени функции или имени генератора, является чем-то, что имеет значение для вызывающих, и вызывающие не должны (а иногда и не могут) смотреть, какое ключевое слово использовалось для его реализации. Это ответственность лучшего соглашения об именах и документации.


1

Генераторы - это функции, которые оценивают лениво. Учитывая, что в основе их лежит одно и то же, имеет смысл использовать одно и то же ключевое слово. Одним из вариантов может быть использование комментария для определения того, что есть для данного экземпляра:

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

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

0

Я предполагаю, что это потому, что это больше Pythonic, но что я знаю? ;)

Я не думаю, что это так важно. Мне легче запомнить, потому что не нужно запоминать их обоих.

РЕДАКТИРОВАТЬ: ОПТОСОЗ может сказать, вы могли бы расследовать там.


Спасибо! На самом деле, ОПТОСОЗ говорит! См. PEP-255 о плюсах и минусах и окончательном решении относительно нового ключевого слова для генераторов.
Дерек Квок

Что означает Pythonic: «Как это делается в Python»?
Джорджио
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.