Как работают логические операторы в операторе if с Python?
if "link?" or "Link?" in comment.body and comment.id not in comments_replied_to and comment.author != r.user.me():
print ("Link String found " + comment.id)
print(comment.body)
#comment.reply("Here you go!")
print ("Replied to comment ")
#time.sleep(600)
Когда я запускаю код, он пропускает первую "ссылку", или, скорее, он запускает код внутри оператора if независимо от того, "ссылка" или нет? находится в comment.body. Я пытаюсь запустить код как:
if (a or b) and c and d
Где он ищет строку "ссылка?" или строка "Ссылка?" в теле комментария. Если один из них найден, он будет запускать код в цикле for. В настоящее время работает, если у меня есть:
if "link?" in comment.body and comment.id not in comments_replied_to and comment.author != r.user.me():
Так что я знаю, что это "или" оператор, который не так. Просто я привык к программированию на Java, где операторы можно заключать в квадратные скобки.
1 ответ
Следующие:
if "link?" or "Link?" in comment.body and comment.id not in comments_replied_to and comment.author != r.user.me()
Становится что-то вроде этого:
bool("link") OR ("Link?" in comment.body) AND (comment.id not in...), etc.
Это первое значение "ссылка" всегда будет True
потому что только пустые строки False
-y.
Давайте разберемся!
Этот вопрос, кажется, часто возникает, и я думаю, что это хорошая возможность проверить дизассемблер Python!
In [1]: import dis
In [3]: def func(comment):
...: if "link?" or "Link?" in comment.body and comment.id not in comments_replied_to and comment.autho
...: r != r.user.me():
...: print ("Link String found " + comment.id)
...: print(comment.body)
...: #comment.reply("Here you go!")
...: print ("Replied to comment ")
...:
In [4]: dis.dis(func)
2 0 LOAD_CONST 1 ('link?')
3 POP_JUMP_IF_TRUE 60
6 LOAD_CONST 2 ('Link?')
9 LOAD_FAST 0 (comment)
12 LOAD_ATTR 0 (body)
15 COMPARE_OP 6 (in)
18 POP_JUMP_IF_FALSE 100
21 LOAD_FAST 0 (comment)
24 LOAD_ATTR 1 (id)
27 LOAD_GLOBAL 2 (comments_replied_to)
30 COMPARE_OP 7 (not in)
33 POP_JUMP_IF_FALSE 100
36 LOAD_FAST 0 (comment)
39 LOAD_ATTR 3 (author)
42 LOAD_GLOBAL 4 (r)
45 LOAD_ATTR 5 (user)
48 LOAD_ATTR 6 (me)
51 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
54 COMPARE_OP 3 (!=)
57 POP_JUMP_IF_FALSE 100
Посмотрите, как написано "LOAD CONST", а затем после этого "POP JUMP IF TRUE". Это означает, что больше ничего не оценивается в этой строке, потому что CONST
всегда будет правдой.
Для сравнения, ниже, вы получите это:
6 LOAD_CONST 2 ('Link?')
9 LOAD_FAST 0 (comment)
12 LOAD_ATTR 0 (body)
15 COMPARE_OP 6 (in)
18 POP_JUMP_IF_FALSE 100
Вот как выглядит реальное сравнение: оно использует бинарный оператор in
сравнить CONST
с загруженным ATTR
, Вопрос для тех, кто обращает внимание: почему этот POP_JUMP_IF_FALSE
и не POP_JUMP_IF_TRUE
как первый?
Вы можете попробовать это дома! Загрузите dis
и начать разборку!