【问题标题】:Python3 importing module with command line args [duplicate]带有命令行参数的Python3导入模块[重复]
【发布时间】:2022-10-02 02:53:24
【问题描述】:

我有一个没有类的 train.py 文件,只是一个函数列表。在导入语句之后的开头有几行:

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

我将此文件放在第二个 py 文件 app.py 的文件夹中,并希望从 app.py 运行它

import train as train

通常从命令行调用 train.py 为:

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

但我应该从 app.py 调用这个文件。如何导入这个 train.py 文件并在 app.py 中设置参数?

  • 您为参数设置了一堆默认值,然后在 if __name__ == \"__main__\": 块中(将在文件单独运行时执行),设置 argparse 选项。如果文件被导入,则忽略 argparse 选项。
  • 此外,import train as train 是多余的。
  • 我不想再次重写train.py,就用它。但是通过导入,我觉得我应该改变接收论点的逻辑。

标签: python import command-line module arguments


【解决方案1】:

train.py 中使用if __name__ == "__main__":

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

您不必重写整个文件,只需添加类似上面的内容(包括将解析器参数分配给变量的部分),然后您就可以使用参数从命令行运行train.py , 并使用默认参数从app.py 导入它。

【讨论】:

  • 谢谢,如果我必须从调用 py 文件中更改参数值?
  • 您是直接运行train.py,还是导入它以便运行其中定义的函数?如果您只是打算将import train 放入app.py 并让它在导入时运行(这不是最好的主意),除了定义默认值之外您无能为力。但是,如果您要在 app.py 中访问 import train,然后在您的代码中调用 train.my_func(arg1, arg2),您可以在那里传递正确的值。但是,最好的方法是将train.py 重写为一个类或一系列类,并让您的参数成为类属性。
  • 不过,作为一个类重写应该不会太难。
  • 所以我认为除了将这个模块作为一个类重新编写之外别无选择,如果我想安全地走下去......谢谢你的详尽解释!
【解决方案2】:

由于此脚本是为从命令行使用而编写的, 我会在app.py 内部做:

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

就像是:

os.system("train.py --model-dir="sdcsdc" --batch-size=333 .... path_to_datafolder")

【讨论】:

  • 不,Python 已经有了处理这种情况的工具 - 请参阅我上面的评论以获取一个示例。
  • 不,这会打开一个全新的兔子洞。最好使用__main__ 守卫,这是最好的做法
  • 啊抱歉我误会了。我认为存在一个完整的脚本train.py。仅仅将 argparse 命令放到一个额外的文件中当然不是一个好主意。
  • 我想对 train.py 进行最小的更改。如果我按照这种方式,我应该改变train.py吗?
  • @IlgarRasulov 这不是正确的方法,这就是 cmets 和否决票的重点。请参阅我的示例以了解处理这种情况的正确方法。您可能需要更改它以适应您的情况,但整体 if __name__ == "__main__" 方法是正确的方法。
猜你喜欢
  • 2018-12-04
  • 1970-01-01
  • 2018-10-06
  • 2014-03-29
  • 2021-05-30
  • 2018-12-14
  • 2018-05-18
  • 1970-01-01
  • 2014-04-27
相关资源
最近更新 更多