0

In Python 2.7.13

We have the following python code to take the command line argument:

import sys
import csv
import os
import sys, getopt
import pandas as pd
print('Python version ' + sys.version)
print('Pandas version ' + pd.__version__)


def main():

    SERVER_NAME=''

    PORT_NAME=''

    PASSWORD=''

    try:

        opts, args = getopt.getopt(sys.argv[1:],"hs:p:x:",["server=","port=","password="])

    except getopt.GetoptError:

        print 'help'

        sys.exit(2)

    for o, a in opts:

        if o == '-h':

            print '\n'+'-s / --server (required)'  

            print '\n'+'-p or --port (required)'

            print '\n'+'-x or --password (required)'

            sys.exit()

        elif o in ("-s", "--server"):

            SERVER_NAME = a

        elif o in ("-p", "--port"):

            PORT_NAME = a

        elif o in ("-x", "--password"):

            PASSWORD = a

        else:

            assert False, "No command line option.  To see the options, plese use -h"


if __name__ == "__main__":

    main()

print SERVER_NAME

dbServer=SERVER_NAME

However, when running the above code in the command line:

python test.py -s AAA -p BBB -x CCC

the following error will show up:

print SERVER_NAME
NameError: name 'SERVER_NAME' is not defined

Could any guru enlighten if anything is wrong here? Thanks.

Chubaka
  • 2,933
  • 7
  • 43
  • 58

1 Answers1

1

SERVER_NAME is defined as a variable local to the main() function, si it is not visible in the global scope (the lines at the bottom of your code.
You could either make SERVER_NAME a global variable or move the code after the call to main() into main(). My preference would be the latter; when I write code with a CLI like this, I don't have any code after calling main() (I often have global setup code before that call, but none of that depends on what happens in the main function)

Here is what I mean by 'moving code into main':

dbServer = ''

def main():
    global dbServer
    SERVER_NAME=''
    PORT_NAME=''
    PASSWORD=''
    try:
        opts, args = getopt.getopt(sys.argv[1:],"hs:p:x:", ["server=","port=","password="])
    except getopt.GetoptError:
        print 'help'
        sys.exit(2)

    for o, a in opts:
        if o == '-h':
            print '\n'+'-s / --server (required)'  
            print '\n'+'-p or --port (required)'
            print '\n'+'-x or --password (required)'
            sys.exit()
        elif o in ("-s", "--server"):
            SERVER_NAME = a
        elif o in ("-p", "--port"):
            PORT_NAME = a
        elif o in ("-x", "--password"):
            PASSWORD = a
        else:
            assert False, "No command line option.  To see the options, plese use -h"

    print SERVER_NAME
    dbServer=SERVER_NAME    

if __name__ == "__main__":
    main()
cco
  • 5,873
  • 1
  • 16
  • 21
  • Sorry I don't quite understand. So if I move "if __name__ == "__main__": main()" to the very bottom of the code (no more codes after this), it still returns "NameError: name 'SERVER_NAME' is not defined". Could you enlighten? – Chubaka Mar 07 '17 at 20:41
  • Thanks for enlightening me! Now I understand. Another question: global dbServer => is it a good practice to make dbServer a global variable? – Chubaka Mar 07 '17 at 21:56
  • That depends on how you're going to use it. If you drive the program from inside the `main` function (by creating objects & calling functions inside main), then you could pass it to those objects and functions that need it, or use it to create a database connection and pass that around; in that case, there is no reason for it to be a global (that's how I would do it). I only made it a global to more closely match your code in my example. – cco Mar 07 '17 at 23:05