-1

My program is like this:

filename=sys.argv[1]
print "filename is default?", (filename is "default")
if (filename is "default"):
  filename="..."
readfile(filename)

I type python ....py default in the command line. Then the output is:

filename is default? False

IOError:...No such file or directory 'default'.

I use pdb, and before the if statement excutes, p filename returns: 'default'.

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
dudu
  • 801
  • 1
  • 10
  • 32

3 Answers3

3

This is what you're looking for:

if filename == "default" :

The == operator is used for comparison, whilst the is operator tests if two variables point to the same object, not if two variables have the same value.

tombam95
  • 343
  • 2
  • 14
3

Use == two compare whether two strings are equal.

Use is to test whether it is the same string.

zvone
  • 18,045
  • 3
  • 49
  • 77
  • BTW, I doubt you will *ever* want to compare string identities using `is`. – zvone Dec 01 '15 at 09:17
  • Hmm, if I try `a = "foo"; b = "foo"; print (a is b), (a == b)` I get two times `True`, any ideas why? – adrianus Dec 01 '15 at 09:27
  • @adrianus to the interpreter, `"foo"` is a constant. Check out my answer for a more detailed explanation. – Daniel Hepper Dec 01 '15 at 10:04
  • @DanielHepper Aah, cool, thanks! I also just noticed that `a = "foo"; b = "foo"; print id(a), id(b)` returns the same value two times... – adrianus Dec 01 '15 at 10:08
  • @adrianus That is an optimization trick. Interpreter is using the same variable for a and b because it "knows" that they are the same. On the other hand, when you say `filename=sys.argv[1]`, interpreter does not optimize that, because it does not know beforehand what `sys.argv[1]` would be. – zvone Dec 01 '15 at 14:09
1

Short answer:

if filename == "default" :

Long answer:

is checks for object identity. To check for equality, use ==. Check the Python documentation on comparisons. In your case:

Note that comparing two string constants with is will actually return true.

def f():
    a = "foo"
    b = "foo"
    print(a is b)   # True, because a and b refer to the same constant
    x = "f" + "oo"
    print(a is x)   # True, because the addition is optimized away
    y = "f"
    z = y + "oo"    #
    print(a is z)   # False, because z is actually a different object

You can see what happens under the hood by disassembling the CPython byte code:

>>> import dis
>>> dis.dis(f)
2         0 LOAD_CONST               1 ('foo')
          3 STORE_FAST               0 (a)

3         6 LOAD_CONST               1 ('foo')
          9 STORE_FAST               1 (b)

4        ...

5        28 LOAD_CONST               4 ('foo')
         31 STORE_FAST               2 (x)

6        ...

7        50 LOAD_CONST               2 ('f')
         53 STORE_FAST               3 (y)

8        56 LOAD_FAST                3 (y)
         59 LOAD_CONST               3 ('oo')
         62 BINARY_ADD
         63 STORE_FAST               4 (z)

9        ...
Daniel Hepper
  • 28,981
  • 10
  • 72
  • 75