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

    17.01.2010

    1 ↑
    0 ↓

    Наткнулся тут на существенную разницу между двумя вариантами кода:

    value = getattr(obj1, 'attr', obj2.attr)
    

    и

    value = getattr(obj1, 'attr', None) or obj2.attr
    

    Как думаете, в чём разница? :-)

  2. xcat

    17.01.2010

    1 ↑
    0 ↓
    Наверно в был приятно удивлен наличием None s в value?
    Или что то другое?
  3. Если вызов obj2.attr имеет сайд-эффект, то в первом случае он будет проявляться всегда, а во втором нет.

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

    17.01.2010

    0 ↑
    0 ↓

    Да, Саш, оно. Я хотел избежать вызова obj2.attr (потому что за ним оно в базу ходит), если у obj уже есть этот объект в собственном атрибуте.

  5. Виталий

    18.01.2010

    0 ↑
    0 ↓
    По-питоньи говоря, проявляется особенность логических операторов Python'а: в первом случае значение obj2.attr будет получено(вычислено) в любом случае, даже если не будет использовано, так как мы передаем его как аргумент в функцию getattr, тогда как во втором случае в логическом выражении его правая часть "or obj2.attr" по сути ленива, и не будет вычислена, если левая часть вернет True.
  6. Виталий

    18.01.2010

    0 ↑
    0 ↓
    Полезное решение, кстати, почти паттерн.
  7. Harut

    19.01.2010

    2 ↑
    0 ↓
    Не знаю, что понимается под словом "существенная", но есть ещё одна разница (наверное, занудствую, и всем это и так понятно):
    In [9]: obj1.attr = 0

    In [10]: getattr(obj1, 'attr', 0)
    Out[10]: 0

    In [11]: getattr(obj1, 'attr', 1)
    Out[11]: 0

    In [12]: getattr(obj1, 'attr', None) or 1
    Out[12]: 1

    In [13]: obj1.attr = None

    In [15]: getattr(obj1, 'attr', 0)

    In [16]: getattr(obj1, 'attr', None) or 1
    Out[16]: 1

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