PDA

View Full Version : Python thinks "a" isn't "a"?



xelapond
March 9th, 2008, 05:38 AM
Hello everyone,

I am writing a program in python to allow my AVR Development Board to send a piece of data to my computer over serial. I am going to pick this up with Python, and then process and act upon that specific piece of data. I wrote a simple check to test to concept, but it does now work, though it does not loot like there is anything wrong.

>>> SerialData = ser.read()
>>> print SerialData
a
>>> if SerialData is "a":
... print "hello"
...
>>>

Does anybody know why Python does not think A is A?

Thanks a ton,

Alex

ghostdog74
March 9th, 2008, 06:06 AM
use the "==" operator..

Martin Witte
March 9th, 2008, 01:35 PM
not knowing what your class does - it could be caused by something like this:


#!/usr/bin/env python
class NotWhatItSeemsToBe(object):
def __init__(self, arg):
self.content = arg

def __str__(self):
return str(self.content)


test = NotWhatItSeemsToBe('a')

if test == 'a':
print 'we have an a'

if str(test) == 'a':
print 'the string is an a'


You can fix that by adding a __eq__ method to your class


#!/usr/bin/env python
class NotWhatItSeemsToBe(object):
def __init__(self, arg):
self.content = arg

def __str__(self):
return str(self.content)

def __eq__(self, other):
if self.content == other:
return True
else:
return False

test = NotWhatItSeemsToBe('a')

if test == 'a':
print 'we have an a'

if str(test) == 'a':
print 'the string is an a'

xelapond
March 9th, 2008, 03:56 PM
Thanks both of you. Making it == worked.

Thanks again,

Alex

Smygis
March 15th, 2008, 12:56 PM
in python is does not check the content of the variable but its identety.



>>> aList = [0,1,2]
>>> otherList = aList
>>> aList is otherList
True
>>> otherList.append(10)
>>> aList is otherList
True
>>> aList
[0, 1, 2, 10]
>>> otherList = aList[:]
>>> aList is otherList
False
>>> otherList.pop()
10
>>> otherList
[0, 1, 2]
>>> aList
[0, 1, 2, 10]
>>>

Wybiral
March 15th, 2008, 10:16 PM
in python is does not check the content of the variable but its identety.

Exactly. Be VERY careful with this. "is" checks to see if two objects are a reference to the same object. Even if you don't assign the variable to the same object, sometimes Python will save memory by referencing the same object for multiple immutable variables, other times it will NOT. Don't rely on this unless you need to check if a variable is a reference to a certain object, for instance:


>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> c = a
>>> c is a
True
>>> c is b
False
>>> b is a
False


But as I said, it will sometimes reuse immutable objects, especially small integers. It is not reliable and will not usually work for larger integers, it's just a side effect of Pythons memory optimization. Here's an example:



>>> a = 1
>>> b = 1
>>> a is b
True
>>> a = 10000
>>> b = 10000
>>> a is b
False


The most common use is for things like "a is None" since "None" is an instance of an object that is referenced whenever you assign a variable to "None".

mssever
March 15th, 2008, 10:27 PM
The most common use is for things like "a is None" since "None" is an instance of an object that is referenced whenever you assign a variable to "None".

That makes me curious. Why do Python people frequently recommend a is None over a == None?

LaRoza
March 15th, 2008, 10:55 PM
That makes me curious. Why do Python people frequently recommend a is None over a == None?

I think there is only one None.

Wybiral
March 15th, 2008, 11:01 PM
Because "None" isn't just value, it's an instance. When you say "a = None" it's like saying "a = b" where "b" is some arbitrary object instance. You can still check if it equals "None", but technically you're still checking if the variables are the same object. Maybe it's just to clarify that you want to know if it IS "None", not if it has a value of "None".

mssever
March 15th, 2008, 11:02 PM
I think there is only one None.

I'm sure, as it would be silly to have more than one (ditto for True and False). But is is more efficient than ==? Or is it merely a convention?

LaRoza
March 15th, 2008, 11:14 PM
I'm sure, as it would be silly to have more than one (ditto for True and False). But is is more efficient than ==? Or is it merely a convention?

Is is probably more efficient, but I doubt it really matters (I think of it as a "pointer" type of deal)

Smygis
March 20th, 2008, 12:16 AM
I'm sure, as it would be silly to have more than one (ditto for True and False). But is is more efficient than ==? Or is it merely a convention?



>>> import timeit
>>> t = timeit.Timer()
>>> t.timeit(None is None)
9.059906005859375e-06
>>> t.timeit(None == None)
6.9141387939453125e-06
>>>


(Thats not a absolut truth)

Quikee
March 20th, 2008, 12:39 PM
>>> import timeit
>>> t = timeit.Timer()
>>> t.timeit(None is None)
9.059906005859375e-06
>>> t.timeit(None == None)
6.9141387939453125e-06
>>>


(Thats not a absolut truth)

For me it is. If I use multiple executions (10M) using '==' takes almost twice the time than 'is'.

>>> timeit.Timer('None == None').timeit(10000000)
1.034465517743854
>>> timeit.Timer('None is None').timeit(10000000)
0.65500147213109017

However this is so trivial that we should not even be discussing this as nobody will ever notice the 'performance boost'. ;)