Другим сценарием является то, что вы нанесли нулевой объект в тип значения . Например, код ниже:
object o = null;
DateTime d = (DateTime)o;
Он выкинет NullReferenceException
в роли. В приведенном выше примере это кажется совершенно очевидным, но это может произойти в более «поздних связующих» сложных сценариях, где нулевой объект был возвращен из некоторого кода, которого вы не являетесь, и приведение, например, генерируется некоторой автоматической системой.
Одним из примеров этого является этот простой фрагмент привязки ASP.NET с элементом управления календарем:
" />
Здесь SelectedDate
на самом деле является свойством - типа DateTime
- типа Calendar
Web Control, и привязка может отлично вернуть что-то null. Неявный генератор ASP.NET создаст кусок кода, который будет эквивалентен приведенному выше методу. И это поднимет NullReferenceException
, что довольно сложно определить, потому что он лежит в сгенерированном ASP.NET коде, который компилирует отлично ...
Использовать разрыв:
while True:
i = sys.stdin.read(1)
if i == "\n":
break
# etc...
Вы можете выполнить это, используя встроенную функцию iter()
, используя метод вызова с двумя аргументами:
import functools
for i in iter(fuctools.partial(sys.stdin.read, 1), '\n'):
...
Документация для этого:
< blockquote> iter(o[, sentinel])
... Если задан второй аргумент sentinel , то o должен быть вызываемым объектом. Созданный в этом случае итератор вызовет o без аргументов для каждого вызова его метода next()
; если возвращаемое значение равно sentinel , будет поднят StopIteration
, в противном случае значение будет возвращено.
Одно полезное приложение второго форма iter()
- читать строки файла до тех пор, пока не будет достигнута определенная линия. Следующий пример читает файл, пока метод readline()
не возвращает пустую строку:
with open('mydata.txt') as fp:
for line in iter(fp.readline, ''):
process_line(line)
Версия без functools
:
for i in iter(lambda: sys.stdin.read(1), '\n'):
Лично мне нравятся ответы от Imm и Marks с помощью break
, но вы также можете сделать:
a = None
def set_a(x):
global a
a = x
return a
while set_a(sys.stdin.read(1)) != '\n':
print('yo')
, хотя я бы не рекомендовал его.