I am trying to test a basic premise in python and it always fails and I can’t figure out why.
My sys.argv looks like this:
['test.py', 'test']
And my code looks like this:
if len(sys.argv) > 1 and sys.argv[1] is 'test':
print 'Test mode'
But the test is never true. I am sure that I am missing something really simple here, but I can’t figure out what it is.
As mentioned above, the main reason is your
testcomparison. Usingisis different than using==as it compares if two objects are equal. In this case, you can verify that they are not equal by checking their ids:My output:
As they point to different objects, they will not be equal when using
is(but using==will compare the strings themselves, which will returnTrue).The issue at work here is the concept of interning. When you hardcode two identical strings into your source, the strings are interned and the two will share an object ID (this explains @SamMussmann’s very valid point below). But when you pass a string in via
argv, a new object is created, thereby making the comparison to an identical hardcoded string in your code returnFalse. The best explanation I have found so far is in here, where both Alex Martelli and Jon Skeet (two very reputable sources) explain interning and when strings are interned. From these explanations, it does seem that since the data fromargvis external to the program, the values aren’t interned, and therefore have different object IDs than if they were both literals in the source.One additional point of interest (unrelated to the issue at hand but pertinent to the
isdiscussion) is the caching that is done with numbers. The numbers from -5 to 256 are cached, meaning thatiscomparisons with equal numbers in that range will be True, regardless of how they are calculated: