I am writing a script and I have a function, call it f(), that needs one of the command line arguments (a filename it needs to open). However, f() is not called directly in the main function.

I was wondering if it was bad coding convention to call sys.argv[1] straight from f()? If I don't I would have to pass it as an argument to all of the functions that eventually call f().

+4  A: 

It is bad form to access sys.argv from anywhere other than your main routine since it couples that code to the command line, making it difficult to use from other Python scripts.

Ignacio Vazquez-Abrams
+6  A: 

It would be a bad practice to always assume that the arguments that your function needs are available on the command-line - what if this code was invoked in some other manner?

A function should declare input parameters for the data it needs to access.

At the very least, passing the necessary argument into f() rather than accessing sys.argv helps make f() much more re-usable.

matt b
+3  A: 

You should pass the file name into f(). This way, if you want to use that function later (as a module function, perhaps), you aren't bound to use sys.argv.

You could always make a wrapper to f() (if you are lazy or want to keep your 'main' code clean), that does something like:

def wrapperf():
    return f(sys.argv[1])

You could define wrapperf inside of main() if you want to keep it away from other scripts importing your module.

+1  A: 

Yes, it would be bad practice to access sys.argv from f.

I would suggest passing the neccessary arguments into f. But since f won't neccessarily be called from main...maybe use a global variable? I normally try to avoid them, but in your case... >.>

I guess it would help to know a little more info about the way the program is setup. :P


You definitely don't want to parse sys.argv in some low-level function. To avoid lots of parameter-passing, you could provide a helper-function called by main() that simply stores the filename into a static variable for later use by f().

Marcelo Cantos
+1  A: 

I would recommend setting the file name once, from sys.argv[1] if it exists, or demand user input if it doesn't. Then store it as part of an object, or a global variable. That will prevent having to pass what is essentially a static string all over the place, once it is set.


I would generally advise against it, but BaseHttpServer in python actually uses sys.argv[1] to determine which port to listen on. Convenience maybe.