-1

I have train.py file without a class, just a list of functions. In the beginning after the import statements there are lines:

parser = argparse.ArgumentParser(description='PyTorch ImageNet Training')

parser.add_argument('data', metavar='DIR',
                    help='path to dataset')
parser.add_argument('--model-dir', type=str, default='', 
    help='path to desired output directory for saving model '
     'checkpoints (default: current directory)')
parser.add_argument('-a', '--arch', metavar='ARCH', default='resnet18',
                    choices=model_names,
                    help='model architecture: ' +
                        ' | '.join(model_names) +
                        ' (default: resnet18)')

I placed this file in the folder of the second py file app.py and want to run it from app.py

import train as train

Usually train.py is called from command line as:

train.py --model-dir="sdcsdc" --batch-size=333 .... path_to_datafolder

but i should call this file from app.py. How can i import this train.py file and set arguments inside app.py?

  • 1
    You set a bunch of default values for your arguments, then in a `if __name__ == "__main__":` block (which would be executed when the file is run on its own), you set the `argparse` options. If the file is imported, the argparse options are ignored. – MattDMo Nov 19 '21 at 23:49
  • Also, `import train as train` is redundant. – MattDMo Nov 19 '21 at 23:49
  • related: https://stackoverflow.com/questions/419163/what-does-if-name-main-do – DeepSpace Nov 19 '21 at 23:52
  • i dont't want to rewrite train.py again, just use it. But with import I feel that I should change logic of receiving arguments. – Ilgar Rasulov Nov 19 '21 at 23:54

2 Answers2

0

Use if __name__ == "__main__": in train.py:

import os

...

data = "default_path_to_data"
model_dir = os.getcwd()
arch = "resnet18"

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='PyTorch ImageNet Training')

    parser.add_argument('data', metavar='DIR',
                        help='path to dataset')
    parser.add_argument('--model-dir', type=str, default='', 
        help='path to desired output directory for saving model '
         'checkpoints (default: current directory)')
    parser.add_argument('-a', '--arch', metavar='ARCH', default='resnet18',
                        choices=model_names,
                        help='model architecture: ' +
                            ' | '.join(model_names) +
                            ' (default: resnet18)')

# continue with program logic

You don't have to rewrite the entire file, you just add something like the above (including a part where you assign the parser arguments to variables), then you'll be able to both run train.py from the command line with arguments, and import it from app.py using default arguments.

MattDMo
  • 100,794
  • 21
  • 241
  • 231
  • thanks, vhat if i have to change the argument value from the calling py file? – Ilgar Rasulov Nov 20 '21 at 00:09
  • Are you running `train.py` as-is straight through, or are you importing it so you can run the functions defined in it? If you're just planning on putting `import train` in `app.py` and letting it run through at import time (which isn't the greatest idea), there's not much you can do except define defaults. However, if you're going to `import train` in `app.py`, then later on call `train.my_func(arg1, arg2)` in your code, you can just pass the correct values there. But, the *best* way is to rewrite `train.py` as a class or series of classes, and have your arguments be class properties. – MattDMo Nov 20 '21 at 00:15
  • Rewriting as a class shouldn't be too hard, though. – MattDMo Nov 20 '21 at 00:16
  • so i see there is no option either than revriting this module as a class, if i vant to go the safe vay... thank you for thorough explanation! – Ilgar Rasulov Nov 20 '21 at 00:20
-2

Since this script is written for usage from the Command line, I would do from within app.py:

import os
os.system("your command line command")

Something like:

os.system("train.py --model-dir="sdcsdc" --batch-size=333 .... path_to_datafolder")
Gwang-Jin Kim
  • 9,303
  • 17
  • 30
  • No, Python already has tools for dealing with this kind of situation - see my comment above for an example of one. – MattDMo Nov 19 '21 at 23:51
  • No, this opens an entirely new rabbit hole. Better to use `__main__` guard which is the best practice anyway – DeepSpace Nov 19 '21 at 23:51
  • Ah sorry I misunderstood. I thought there exist a full fledged script `train.py`. Just to place argparse commands to an extra file is of course not a good idea. – Gwang-Jin Kim Nov 19 '21 at 23:57
  • i vant to go the vay of minimal change to train.py. hov should i change the train.py if i follov this vay? – Ilgar Rasulov Nov 20 '21 at 00:01
  • @IlgarRasulov this is not the correct way to go, that's the point of the comments and the down votes. See my example for the correct way to handle this situation. You may need to alter it to fit your situation, but the overall `if __name__ == "__main__"` method is the correct way to go. – MattDMo Nov 20 '21 at 00:04