Почему делает присвоение Истинному/ложному не, работают, как я ожидаю?

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

print True                    # outputs true
True = False;    print True   # outputs false
True = True;     print True   # outputs false
True = not True; print True   # outputs true

Кто-либо может объяснить это странное поведение? Я думаю, что это имеет некоторое отношение к объектной модели Python, но я не уверен.

Это - версия 2.5.2 под Cygwin.

32
задан John Kugelman supports Monica 18 September 2017 в 20:31
поделиться

4 ответа

Python имеет эти два (среди прочих) встроенных объекта. Это всего лишь объекты; в начале у них пока нет имён, но чтобы узнать, к чему мы клоним, назовём их 0x600D и 0xBAD.

Перед началом выполнения скрипта Python (2.x), имя True привязывается к объекту 0x600D, а имя False привязывается к объекту 0xBAD, поэтому, когда программа обращается к True, она смотрит на 0x600D.

Поскольку 0x600D и 0xBAD знают, что они обычно используются под именами True и False, это то, что они выводят при печати, т.е. метод __str__ 0x600D возвращает 'True' и так далее. Теперь

True = False

привязывает имя True к другому объекту. Отныне оба имени True и False относятся к одному и тому же объекту 0xBAD, который при печати выдает False. На самом деле

True = True

ничего не делает: он принимает объект, на который ссылается имя True, и связывает новое (и старое) имя True с этим объектом. Так как (из-за предыдущего шага) True ссылается на 0xBAD до этого, он все еще ссылается на 0xBAD после этого. Таким образом, печать по-прежнему выдает False. Сначала

True = not True

получает объект, к которому привязано имя True, а именно 0xBAD. Он передает этот объект оператору , а не . не не заботит (или не знает), какое имя здесь используется для ссылки на 0xBAD, а просто знает, что при задании 0xBAD он должен вернуть 0x600D. Затем это возвращаемое значение передается оператору присваивания =, связывая имя True с этим объектом.

Так как имя True теперь снова ссылается на объект 0x600D, то при вызове выводится True True, и мир снова становится хорошим.

76
ответ дан 27 November 2019 в 19:41
поделиться

Можно попробовать такую программу, как Surfulater . Я не знаю, насколько хорошо это работает с образцами кода, но я знаю, что разработчик был (все еще?) активен на форумах Joel on Software, поэтому я уверен, что с ним можно связаться с любыми конкретными вопросами.

-121--3950614-

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

-121--1188022-

Можно проверить, является ли True/False ключевым словом:

>>> import keyword
>>> keyword.iskeyword('True')
False

Поскольку это не так (в моей версии), назначение True = False означает только «True» является другим именем переменной.

12
ответ дан 27 November 2019 в 19:41
поделиться

в 2.x, True и False не являются ключевыми словами, так что можно тенить встроенные встроенные в Таким образом.

18
ответ дан 27 November 2019 в 19:41
поделиться

Представьте, что это вместо этого:

A = True
B = False

print A           # true
A = B;  print A   # false
A = A;  print A   # false, because A is still false from before
A = not A; print A # true, because A was false, so not A is true

Точное то же самое происходит, но в вашей версии он сбивает с толку, потому что вы не ожидаете, что вы можете переопределить и ложь.

43
ответ дан 27 November 2019 в 19:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: