Вы все верно поняли, вычисления происходят по укороченной схеме. Но ведь _or_ вычисляет свои аргументы до первого True, и может получить несколько False пока не наткнется на первый True или не вычислит все свои аргументы. Таким образом все сообщения False-условий и будут перечислены в отчете.
Как пример привожу фрагмент из тестов для либы:
def do_test(s):
return _and_(
lambda: (s, u"Empty string"),
lambda: _and_(
lambda: (3 <= len(s), u"Must be at least 3 characters long"),
lambda: (len(s) <= 10, u"Must be not more than 10 characters long"),
report=u"String length is incorrect"
),
lambda: _or_(
lambda: (s == "aaa", u"Is not 'aaa' string"),
lambda: (s == "bbb", u"Is not 'bbb' string"),
lambda: (s == "ccc", u"Is not 'ccc' string"),
lambda: _and_(
lambda: (s.startswith("_"), u"Does not start with '_' character"),
lambda: (s.endswith("_"), u"Does not end with '_' character"),
report="String must be enclosed with underscore characters"
),
report=u"Is not any of 'aaa', 'bbb' or 'ccc' string or not enclosed with '_' character"
),
report=u"Incorrect string",
)
...
result = do_test(u"_abc")
assert bool(result) == False
# default report
assert unicode(result) == u"Is not 'aaa' string, Is not 'bbb' string, Is not 'ccc' string, Does not end with '_' character"
# full report displaying hierarchy of messages
assert result.build_report() == u"Incorrect string(Is not any of 'aaa', 'bbb' or 'ccc' string or not enclosed with '_' character(Is not 'aaa' string, Is not 'bbb' string, Is not 'ccc' string, String must be enclosed with underscore characters(Does not end with '_' character)))"
# full report as html
assert result.build_html_report() == u"Incorrect string<ul><li>Is not any of 'aaa', 'bbb' or 'ccc' string or not enclosed with '_' character<ul><li>Is not 'aaa' string</li><li>Is not 'bbb' string</li><li>Is not 'ccc' string</li><li>String must be enclosed with underscore characters<ul><li>Does not end with '_' character</li></ul></li></ul></li></ul>"
33 result = _me("123","first") and _me(False, "second") or _me(calculate_me(),"calculated")
34 self.assertEqual(result.msg,"calculated")
Здесь мы ожидаем получить сообщение лишь одного условия "calculated", одного из тех, которые вычислились в False, а в своей либе я добивался результата, который бы в данном случае вернул "second, calculated", т.е. все условия вычислившиеся в False. К тому же у меня реализовано построение полного отчета, с возможностью вложенных сообщений. Как реализовать такие отчеты на вашем примере пока придумать не могу.
33 result = _me("123","first") and _me(False, "second") or _me(calculate_me(),"calculated")
34 self.assertEqual(result.msg,"calculated")
вот как раз в таких случаях я добивался от своей библиотеки возвращать в сообщении не просто "calculated", а "second, calculated", так как мне надо знать все условия, вычислившиеся в False — это дает больше полезной информации. А как добиться такого поведения используюя операторы питона, пока не могу придумать. По крайней мере, чтобы это выглядело более-менее красиво.
Намек на то что стандартные недо-тултипы надо заменить на продвинутую версию попапов? :) К стати, мне понравилось как на Хабре сделаны тултипы в правом верхнем углу для аяксовых действий. Что-то подобное встречали для jQuery?
Красивая, запись, и простая, как-то сам не додумался до такого варианта. Возможно мне стоит взять ее за основу и допилить чтобы она генерировала такие отчеты, как сейчас делает моя либа. Спасибо.
Пример конечно не претендует на идеал, конечно же есть случаи когда кнопку лучше спрятать, выбор делаем исходя из обстоятельств. А сообщение на кнопке в данном случае просто соответствует правилу. В реальной ситуации правило будет адекватным (насколько это возможно) и, соответственно, сообщение на кнопке тоже.
_or_
вычисляет свои аргументы до первогоTrue
, и может получить несколькоFalse
пока не наткнется на первыйTrue
или не вычислит все свои аргументы. Таким образом все сообщенияFalse
-условий и будут перечислены в отчете.Как пример привожу фрагмент из тестов для либы:
Здесь мы ожидаем получить сообщение лишь одного условия
"calculated"
, одного из тех, которые вычислились вFalse
, а в своей либе я добивался результата, который бы в данном случае вернул"second, calculated"
, т.е. все условия вычислившиеся вFalse
. К тому же у меня реализовано построение полного отчета, с возможностью вложенных сообщений. Как реализовать такие отчеты на вашем примере пока придумать не могу.вот как раз в таких случаях я добивался от своей библиотеки возвращать в сообщении не просто
"calculated"
, а"second, calculated"
, так как мне надо знать все условия, вычислившиеся вFalse
— это дает больше полезной информации. А как добиться такого поведения используюя операторы питона, пока не могу придумать. По крайней мере, чтобы это выглядело более-менее красиво.