简体   繁体   中英

Python: If is running even when condition is not met

import imaplib, re
import os

while(True):
    conn = imaplib.IMAP4_SSL("imap.gmail.com", 993)
    conn.login("xxx", "xxxx")
    unreadCount = re.search("UNSEEN (\d+)", conn.status("INBOX", "(UNSEEN)")[1][0]).group(1)
    print unreadCount

    if unreadCount > 10:
      os.system('ls')

Even when unreadCount is < 10, it runs the command 'ls'. Why?

You might want to coerce that value to an integer, as per:

unreadCount = int (re.search (blah, blah, blah).group (1))

The call to re.search is returning a string and, if you have a look at the following transcript:

>>> x = "7"
>>> if x > 10:
...     print "yes"
... 
yes

>>> if int(x) > 10:
...     print "yes"
... 

>>> x = 7
>>> if x > 10:
...     print "yes"
... 
>>> 

you'll see why that's not such a good idea.

The reason you're seeing this (what you might call bizarre) behaviour can be gleaned from the manual at the bottom of 5.3 :

CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don't support proper comparison are ordered by their address.

Since the type of "7" is str and the type of 10 is int , it's simply comparing the type names ( "str" is always greater than "int" in an alpha order), leading to some interesting things like:

>>> "1" > 99999999999999999999999
True
>>> "1" == 1
False

That implementation detail was still in effect up until at least 2.7.2. It may have changed in the Python 3000 stream (the clause has certainly been removed from the relevant documentation section), but the documentation there still states:

Most other objects of built-in types compare unequal unless they are the same object; the choice whether one object is considered smaller or larger than another one is made arbitrarily but consistently within one execution of a program.

So it's probably not something you should rely on.

Try this:

if int(unreadCount) > 10:
    os.system('ls')

You're comparing a string to an integer:

>>> '10' > 10
True

This may be shocking; whether the string is coerced to an integer or the integer is coerced to a string, in both cases the result should have been False . The truth is that neither happens, and the ordering is arbitrary. From the language reference :

Most other objects of built-in types compare unequal unless they are the same object; the choice whether one object is considered smaller or larger than another one is made arbitrarily but consistently within one execution of a program.

This will solve your problem:

unreadCount = int(re.search(...).group(1))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM