0

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?
3
  • 3
    import A won't execute the code in the if __name__ == '__main__': block, so there's no point passing arguments. It looks like you want to run A.py, not import it. Commented May 7, 2019 at 7:08
  • Oh. you are right. Is there any workaround for this situation? Commented May 7, 2019 at 7:09
  • What is the best way to call a script from another script? Commented May 7, 2019 at 7:14

3 Answers 3

3

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()
Sign up to request clarification or add additional context in comments.

Comments

1
# 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?

Comments

1

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'])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.