1. master

    08.01.2010

    0 ↑
    0 ↓

    в один прекрасный день получил ошибку на строку типа:

    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.

  2. http://zw0rk.blogspot.com

    08.01.2010

    1 ↑
    1 ↓
    если решать ровно ту задачу, которую вы просите, то можно так:
    try:
    a = float(b)*float(c)
    except:
    a = 0
    а вообще, имхо, явное лучше неявного и если надо чтобы NoneType переходил в нуль, то это надо делать:
    def float_modified(a):
    try:
    return float(a)
    except:
    return 0

    a = float_modified(b)*float_modified(c)
  3. Думаю, более явным было бы такое решение:

    def float_modified(a):
        if a is None:
            return 0
        else:
            return float(a)
    

    И лишние эксэпшены не будут проглочены.

  4. Иван Сагалаев

    08.01.2010

    2 ↑
    0 ↓
    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)
    

    Но это всё равно коряво. Лучше просто не хранить ненужных данных.

  5. Как раз хотел добавить вариант с IntegerField(default=0), чтобы вообще None'ов не было.

    Но Иван опередил :)

  6. master

    08.01.2010

    0 ↑
    0 ↓

    Да, я подумал и решил, что и правда для чистоты лучше отказаться от NULL в данном случае и использовать IntegerField(default=0). Спасибо!

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.