tags:

views:

84

answers:

3

As part of a large python program I have the following code:

for arg in sys.argv:
    if "name=" in arg:
            name = arg[5:]
            print(name)
    elif "uname=" in arg:
            uname = arg[6:]
            print(uname)
    elif "password=" in arg:
            password = arg[9:]
            print(password)
    elif "bday=" in arg:
            bday = arg[5:]
            print(bday)
    else:
            pass

The program expects something like:

python prog.py "name=Kevin" "uname=kevin" "password=something" "bday=01/01/01"

When I try to use "uname" later, the program fails, claiming "uname is not defined" I added the "print()" lines to try and debug and the "print(uname)" always shows "=kevin" regardless of the index number I put there (here "6:"). The other statements seem to work fine. Is this a bug in python? I am very confused.

Thanks in advance.

+11  A: 

The elif "uname=" is never run because the string "name=" is in "uname=". Essentially, you are overwriting your name variable.

>>> "name=" in "uname="
True

You could reorder your ifs so that so that the uname occurs before the name one.

Mark
Thank you Mark! I didn't see that. Wow. That explains a lot.
Skyler
@user428582, a quick fix would be to do `if arg.startswith('whatever'):`, though using a more robust way of parsing args (e.g. optparse) would be better still...
Joe Kington
Just printing the contents of a variable is not very helpful for debugging when you are doing it for multiple variables. Had you done `print "uname", uname` you would have seen that the "=kevin" was in the wrong variable.
unholysampler
A: 

Also, I think that uname is local to the if statement. Try initializing the variables to some default before the if:

unamne=""
name=""
#etc
Sean
Scoping in Python does not work like that; the local variable is available anywhere in function scope.
dash-tom-bang
+4  A: 

Let's look closely at this.

if "name=" in arg:
        name = arg[5:]
        print(name)
elif "uname=" in arg:
        uname = arg[6:]
        print(uname)

When I apply this to "name=Kevin", which rule works? Just the first one, right?

When I apply this to "uname=kevin", which rule works? First one? Second one? Both? Interestingly, the first one works. I see name=kevin inside uname=kevin. Not what you wanted, was it?

S.Lott