Как часть ответа на другой вопрос, я написал следующий код, поведение которого кажется причудливым на первый взгляд:
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.
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
, и мир снова становится хорошим.
Можно попробовать такую программу, как Surfulater . Я не знаю, насколько хорошо это работает с образцами кода, но я знаю, что разработчик был (все еще?) активен на форумах Joel on Software, поэтому я уверен, что с ним можно связаться с любыми конкретными вопросами.
-121--3950614-Не то, как люди используются для работы в браузере, не следует изменять поведение по умолчанию. Пользователи не ожидают, что что-то произойдет, если щелкнуть правой кнопкой мыши.
-121--1188022-Можно проверить, является ли True/False ключевым словом:
>>> import keyword
>>> keyword.iskeyword('True')
False
Поскольку это не так (в моей версии), назначение True = False означает только «True» является другим именем переменной.
в 2.x, True и False не являются ключевыми словами, так что можно тенить встроенные встроенные в Таким образом.
Представьте, что это вместо этого:
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
Точное то же самое происходит, но в вашей версии он сбивает с толку, потому что вы не ожидаете, что вы можете переопределить и ложь.