Почему в Python нет операторов ++ и--?

почему нет ++ и -- операторы в Python?

17 ответов


это не потому, что это не имеет смысла; имеет смысл определить "x++" как "x += 1, оценивая предыдущую привязку x".

если вы хотите узнать первоначальную причину, вам придется либо пробираться через старые списки рассылки Python, либо спросить кого-то, кто был там (например. Guido), но это достаточно легко оправдать после того, как факт:

простое приращение и уменьшение не так необходимы, как на других языках. Вы не пишете такие вещи, как for(int i = 0; i < 10; ++i) в Python очень часто; вместо этого вы делаете такие вещи, как for i in range(0, 10).

так как это не нужно почти так часто, есть гораздо меньше причин, чтобы дать ему свой собственный специальный синтаксис; когда вам нужно увеличить,+= обычно просто отлично.

четыре операторы--postinc, postdec, preinc, predec и каждый из них должны иметь свои собственные перегрузки классов; все они должны быть указаны и протестированы; он добавит опкоды к языку (подразумевая больший и, следовательно, более медленный движок VM); каждый класс, поддерживающий логическое приращение, должен будет реализовать их (поверх += и -=).

это все избыточно с += и -=, так что это станет чистым убытком.


этот оригинальный ответ, который я написал, является мифом из фольклора вычислений: разоблачен Деннисом Ричи как "исторически невозможный", как отмечается в письмах к редакторам связь ACM июля 2012 doi: 10.1145 / 2209249.2209251


операторы инкремента/декремента C были изобретены в то время, когда компилятор C не был очень умным, и авторы хотели иметь возможность указать прямое намерение, что машина следует использовать оператор языка, который сохранил несколько циклов для компилятора, который может сделать

load memory
load 1
add
store memory

вместо

inc memory 

и PDP-11 даже поддерживал инструкции "autoincrement" и "autoincrement deferrement", соответствующие *++p и *p++, соответственно. См. раздел 5.3 руководство если ужасно любопытно.

поскольку компиляторы достаточно умны, чтобы обрабатывать трюки оптимизации высокого уровня, встроенные в синтаксис C, теперь это просто синтаксическое удобство.

Python не имеет трюков для передачи намерений ассемблеру, потому что он их не использует.


Я всегда предполагал, что это связано с этой строкой дзэн питона:

должен быть один - и, желательно, только один - очевидный способ сделать это.

x++ и x+=1 делают то же самое, поэтому нет причин иметь оба.


конечно, мы могли бы сказать: "Гвидо просто решил так", но я думаю, что вопрос действительно о причинах этого решения. Я думаю, есть несколько причин:

  • он смешивает заявления и выражения, что не является хорошей практикой. См.http://norvig.com/python-iaq.html
  • это обычно поощряет людей писать менее читаемый код
  • дополнительная сложность в реализации языка, которая не нужна в Python, как уже упоминалось

потому что в Python целые числа неизменяемы (int += фактически возвращает другой объект).

кроме того, с ++ / -- вам нужно беспокоиться о pre-versus post-increment / decrement, и для записи x+=1. Другими словами, это позволяет избежать потенциальной путаницы за счет очень небольшой выгоды.


ясность!

Python много о ясность и ни один программист, скорее всего, правильно не угадает значение --a Если только он не выучил язык с такой конструкцией.

Python также много о избегая конструкций, которые приглашают ошибки и ++ операторы являются богатыми источниками дефектов. Этих двух причин достаточно, чтобы не иметь этих операторов в Python.

решение, которое использует Python отступ для маркировки блоков чем синтаксические средства, такие как некоторая форма начала / конца брекетинга или обязательная маркировка конца основана в основном на тех же соображениях.

для иллюстрации, посмотрите на дискуссия вокруг введения условного оператора (на C: cond ? resultif : resultelse) в Python в 2005 году. Прочтите хотя бы первый и решение этой обсуждение (который имел несколько предшественников на та же тема ранее).

Общая информация: ОПТОСОЗ, часто упоминаемый в нем, является "предложением расширения Python"PEP 308. LC означает понимание, GE означает выражение генератор (и не волнуйтесь, если они смущают вас, они не являются одним из немногих сложных пятен Python).


Он был просто разработан таким образом. Операторы Increment и decrement - это просто ярлыки для x = x + 1. Python обычно принимает стратегию проектирования, которая уменьшает количество альтернативных средств выполнения операции. модифицированное задание ближе всего к операторам инкремента/декремента в Python, и они даже не были добавлены до Python 2.0.


Я очень новичок в python, но я подозреваю, что причина в акценте между изменяемыми и неизменяемыми объектами в языке. Теперь я знаю, что x++ можно легко интерпретировать как x = x + 1, но похоже, что вы увеличиваете на месте объект, который может быть неизменной.

просто моя догадка / чувство / догадка.


мое понимание того, почему python не имеет ++ оператор следующий: когда вы пишете это в python a=b=c=1 вы получите три переменные (метки), указывающие на тот же объект (значение 1). Вы можете проверить это с помощью функции id, которая вернет адрес памяти объекта:

In [19]: id(a)
Out[19]: 34019256

In [20]: id(b)
Out[20]: 34019256

In [21]: id(c)
Out[21]: 34019256

все три переменные (надписи) указывают на один и тот же объект. Теперь увеличьте одну из переменных и посмотрите, как она влияет на адреса памяти:

In [22] a = a + 1

In [23]: id(a)
Out[23]: 34019232

In [24]: id(b)
Out[24]: 34019256

In [25]: id(c)
Out[25]: 34019256

вы можете увидеть, что переменная a теперь указывает на другой объект в качестве переменных b и c. Потому что вы использовали a = a + 1 это явно понятно. Другими словами, вы назначаете совершенно другой объект label a. Представьте, что вы можете написать a++ это предполагает, что вы не назначили переменной a новый объект, но ratter увеличить старый. Все это имхо для минимизации путаницы. Для лучшего понимания посмотрите, как работают переменные python:

In Python, почему функция может изменять некоторые аргументы, воспринимаемые вызывающим, но не другие?

это Python вызов по значению и вызов по ссылке? Ни.

проходит ли Python по значению или по ссылке?

это Python передача по ссылке или по значению?

Python: как передать переменную по ссылке?

Понимание Python переменные и управление памятью

эмуляция поведения pass-by-value в python

Python функции вызова по ссылке

код, как Pythonista: идиоматический Python


Я считаю, что это связано с кредо Python, что "явное лучше, чем неявное".


во-первых, Python только косвенно зависит от C; на него сильно влияет ABC, который по-видимому, не имеет этих операторов, поэтому не должно быть большим сюрпризом не найти их в Python.

во-вторых, как уже говорили другие, инкремент и декремент поддерживаются += и -= уже.

в-третьих, полная поддержка ++ и -- набор операторов обычно включает поддержку как префикса, так и постфиксные версии их. В C и C++ это может привести ко всем видам "прекрасных" конструкций, которые кажутся (мне) противоречащими духу простоты и прямолинейности, который охватывает Python.

например, в то время как оператор C while(*t++ = *s++); может показаться простым и элегантным опытному программисту, кому-то, кто его изучает, это что угодно, но не просто. Добавьте смесь префиксных и постфиксных приращений и уменьшений, и даже многим профессионалам придется остановиться и немного подумать.


Это может быть потому что @GlennMaynard смотрит на этот вопрос, как по сравнению с другими языками, но в Python вы делаете вещи так, как python. Это не вопрос "почему". Это там, и вы можете делать вещи с тем же эффектом с x+=. В Дзен питона, дано: "должен быть только один способ решить проблему."Множественный выбор велик в искусстве (свобода выражения), но паршивый в технике.


Как я понял, так что вы не считаете, что значение в памяти меняется. в c при выполнении x++ значение x в памяти изменяется. но в python все числа неизменяемы, поэтому адрес, на который указал x, по-прежнему имеет x не x+1. когда вы пишете x++, вы думаете, что x изменяет то, что на самом деле происходит, что X refrence изменяется на место в памяти, где x+1 хранится или воссоздает это место, если doe не существует.


на ++ класс операторов-это выражения с побочными эффектами. Это то, что обычно не встречается в Python.

по той же причине назначение не является выражением в Python, что предотвращает общее if (a = f(...)) { /* using a here */ } идиома.

наконец, я подозреваю, что оператор не очень согласуется с семантикой ссылок Pythons. Помните, что Python не имеет переменных (или указателей) с семантикой, известной из C/C++.


возможно, лучшим вопросом было бы спросить, почему эти операторы существуют в C. K&R вызывает операторы инкремента и декремента "необычные" (раздел 2.8 стр. 46). Во введении они называются "более краткими и часто более эффективными". Я подозреваю, что тот факт, что эти операции всегда возникают в манипуляции указателем, также сыграл свою роль в их введении. В Python, вероятно, было решено, что нет смысла пытаться оптимизировать приращения (на самом деле я только что сделал тест в C, и кажется что сборка, сгенерированная gcc, использует addl вместо incl в обоих случаях), и нет арифметики указателя; поэтому это был бы еще один способ сделать это, и мы знаем, что Python ненавидит это.


чтобы завершить уже хорошие ответы на этой странице:

предположим, что мы решили сделать это, префикс (++i) это нарушило бы унарные + и - операторы.

сегодня, начинаются с ++ или -- ничего не делает, потому что он включает унарный плюс оператор дважды (ничего не делает) или унарный минус дважды (дважды: отменяет себя)

>>> i=12
>>> ++i
12
>>> --i
12

так что это потенциально нарушит эту логику.


++ оператор не совсем то же самое + = оператор. По сути результат такой же, но имеют некоторые отличия. Например, вы можете использовать оператор ++ в троичном условном, для цикла и т. д., Но не можете использовать +=. По сути, мы чувствуем потребность в этом.