-
в один прекрасный день получил ошибку на строку типа:
a = b*c Exception: unsupported operand type(s) for *: 'float' and 'NoneType'Появлется эта ошибка, если одно из значений не определено.
Попробовал писать так:
a = float(b)*float(c)получил: Exception: float() argument must be a string or a number
b и c берутся из базы данных, где хранятся как IntegerField.
Мне нужно, чтобы они перемножались как числа, а если какое-то из них не определено, то оно превращалось бы в 0.
-
если решать ровно ту задачу, которую вы просите, то можно так:
а вообще, имхо, явное лучше неявного и если надо чтобы NoneType переходил в нуль, то это надо делать:try:
a = float(b)*float(c)
except:
a = 0def float_modified(a):
try:
return float(a)
except:
return 0
a = float_modified(b)*float_modified(c) -
Думаю, более явным было бы такое решение:
def float_modified(a): if a is None: return 0 else: return float(a)И лишние эксэпшены не будут проглочены.
-
try: a = float(b)*float(c) except: a = 0Никогда так не делайте. Это скрывает все ошибки, которые могут быть в этом коде. Спросите, какие ошибки в таком простом коде? Например переменных b и c может просто не быть: кто-то отрефакторил функцию, она перестала получать один из аргументов, но всё равно исправно возвращает ноль. Или в одном из аргументов может быть строка, например.
Возвращаясь к реальной задаче, я бы посоветовал в базе избавить это поле от хранения NULL'ов и прописать 0 по дефолту. NULL нужен только тогда, когда в коде где-то явно нужно отличать его от дефолтного пустого значения.
Если это по каким-то ещё причинам это всё таки захочется обходить в питоньем коде, то можно так:
def safe_float(value): return float(value) if value is not None else 0.0 a = safe_float(b) * safe_float(c)Но это всё равно коряво. Лучше просто не хранить ненужных данных.
-
Как раз хотел добавить вариант с IntegerField(default=0), чтобы вообще None'ов не было.
Но Иван опередил :)
-
Да, я подумал и решил, что и правда для чистоты лучше отказаться от NULL в данном случае и использовать IntegerField(default=0). Спасибо!
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.


