Oli
Oli

Reputation: 1393

Call a module containing command line arguments from another module

Consider a following python files, is there any way to pass cl arguments toother module on import? (calling os.system is not desired)

# A.py
if __name__ == "__main__":
    # -- resolve command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--name', type=str, required=True)
    parser.add_argument('--out_file', type=str, required=True)
    args = parser.parse_args()

    # -- do some operations
    # -- save results in `out_file`


#B.py
import A
# how to pass `name` and `out_file` in main?

Upvotes: 0

Views: 1244

Answers (3)

Serge Ballesta
Serge Ballesta

Reputation: 148890

The correct way is of course to change A.py to have a main function taking arguments as parameters as you were suggested in other answers.

So you really should use:

A.py:

# A.py
def main(args):
    # -- resolve command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--name', type=str, required=True)
    parser.add_argument('--out_file', type=str, required=True)
    args = parser.parse_args(args)

    # -- do some operations
    # -- save results in `out_file`

if __name__ == "__main__":
    main(sys.argv)

B.py:

import A
import sys

A.main([sys.argv[0], '--name', 'NAME_X', '--out_file', 'FILE.YY'])

That being said, sys.argv is mutable, so it is possible to change it before calling ArgumentParser.parse_args.

So this is possible (even if a bit more hacky):

A.py:

# A.py
def main():
    # -- resolve command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--name', type=str, required=True)
    parser.add_argument('--out_file', type=str, required=True)
    args = parser.parse_args()                # always use sys.argv

    # -- do some operations
    # -- save results in `out_file`

if __name__ == "__main__":
    main()

B.py:

import A
import sys

sys.argv = [sys.argv[0], '--name', 'NAME_X', '--out_file', 'FILE.YY'])
A.main()

Upvotes: 3

Teemu
Teemu

Reputation: 286

In a.py you need to move the main stuff to a function, for example a def main(). I also added an arguments=None parameter to main() that receives the args from b.py.

# a.py
import argparse

def main(arguments=None):
    # -- resolve command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--name', type=str, required=True)
    parser.add_argument('--out_file', type=str, required=True)
    args = parser.parse_args(arguments)

    # -- do some operations
    # -- save results in `out_file`

if __name__ == "__main__":
    main()

And then you can pass arguments to that function in b.py like so

#b.py
from a import main

main(['--name', 'some_name', '--out_file', 'file.txt'])

Upvotes: 1

Waket Zheng
Waket Zheng

Reputation: 6331

# A.py
def main():
    # -- resolve command line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--name', type=str, required=True)
    parser.add_argument('--out_file', type=str, required=True)
    args = parser.parse_args()

    # -- do some operations
    # -- save results in `out_file`
    return out_file

if __name__ == "__main__":
   main()

#B.py
import A
def main():
    out_file = A.main()
# how to pass `name` and `out_file` in main?

Upvotes: 1

Related Questions