Другим сценарием является то, что вы нанесли нулевой объект в тип значения . Например, код ниже:
object o = null;
DateTime d = (DateTime)o;
Он выкинет NullReferenceException
в роли. В приведенном выше примере это кажется совершенно очевидным, но это может произойти в более «поздних связующих» сложных сценариях, где нулевой объект был возвращен из некоторого кода, которого вы не являетесь, и приведение, например, генерируется некоторой автоматической системой.
Одним из примеров этого является этот простой фрагмент привязки ASP.NET с элементом управления календарем:
" />
Здесь SelectedDate
на самом деле является свойством - типа DateTime
- типа Calendar
Web Control, и привязка может отлично вернуть что-то null. Неявный генератор ASP.NET создаст кусок кода, который будет эквивалентен приведенному выше методу. И это поднимет NullReferenceException
, что довольно сложно определить, потому что он лежит в сгенерированном ASP.NET коде, который компилирует отлично ...
Самый верный ответ заключается в том, что он просто упрощает грамматику, не был камнем преткновения для принятия, и многие из них были довольны тем, что не должны были устранить сферу действия, к которой принадлежит имя, при назначении ей в конструкции цикла , Переменные не объявляются в пределах области действия, это подразумевается расположением операторов присваивания. Ключевое слово global
существует именно по этой причине (для обозначения того, что назначение выполняется в глобальной области).
Update
Вот хорошее обсуждение темы: http : //mail.python.org/pipermail/python-ideas/2008-October/002109.html
Предыдущие предложения, чтобы переменные for-loop, локальные в цикле, опрокинулись на проблему существующего кода, который полагается на переменную цикла, сохраняя ее значение после выхода из цикла, и кажется, что это считается желательной особенностью.
blockquote>Короче говоря, вы, вероятно, можете обвинить это в сообществе Python: P
Python не имеет блоков, как и другие языки (например, C / C ++ или Java). Таким образом, область видимости в Python является функцией.
Для начала, если переменные были локальными для циклов, эти циклы были бы бесполезны для большинства программ реального мира.
В текущей ситуации:
# Sum the values 0..9
total = 0
for foo in xrange(10):
total = total + foo
print total
дает 45
. Теперь рассмотрим, как назначение работает в Python. Если переменные цикла были строго локальными:
# Sum the values 0..9?
total = 0
for foo in xrange(10):
# Create a new integer object with value "total + foo" and bind it to a new
# loop-local variable named "total".
total = total + foo
print total
дает 0
, потому что total
внутри цикла после назначения не является той же переменной, что и total
вне цикла. Это не было бы оптимальным или ожидаемым поведением.
Действительно полезным для этого является использование enumerate
, и вы хотите, чтобы общее количество в конце:
for count, x in enumerate(someiterator):
dosomething(count, x)
print "I did something {0} times".format(count)
Это необходимо? Нет. Но это, безусловно, удобно.
Еще одна вещь, о которой нужно помнить: в Python 2 также распространяются переменные в списках:
>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> x
9
Но то же самое не относится к Python 3.
Одним из основных влияний для Python является ABC , язык, разработанный в Нидерландах для обучения концепций программирования начинающим. Создатель Питона, Гвидо ван Россум, работал в ABC в течение нескольких лет в 1980-х годах. Я почти ничего не знаю о ABC, но, как и для новичков, я предполагаю, что у него должно быть ограниченное количество областей, как ранние BASIC.