【问题标题】:python: stop imported module from parsing command line argumentspython:阻止导入的模块解析命令行参数
【发布时间】:2015-10-23 01:56:02
【问题描述】:

我正在使用一个外部 python 模块,它不是由我编写的,因此无法更改。这个名为 magnum (http://micromagnum.informatik.uni-hamburg.de) 的模块处理所有可选的命令行参数。这里有一个例子来说明行为:

script1.py

#!/usr/bin/env python
import magnum

执行脚本产生:

>>> ./script1.py -h
[WARNING] - Python Imaging Library not found!
[WARNING] - -> This means that the ImageShapeCreator and related classes are not available!
[   INFO] - Imported FFTW wisdom from file
Usage: scipt1.py [options]

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit

  Hardware options:
    Options that control which hardware is used.

    -g GPU_ID           enable GPU processing (using 32-bit accuracy) on cuda
                    device GPU_ID. The simulator will fall back to CPU
                    mode if it was not compiled with CUDA support or when
                    no CUDA capable graphics cards were detected.
    -G GPU_ID           enable GPU processing (using 64-bit accuracy) on cuda
                    device GPU_ID. TODO: Describe fallback behaviour.
    -t NUM_THREADS, --threads=NUM_THREADS
                    enable CPU multithreading with NUM_THREADS (1..64)
                    threads. This parameter instructs the fftw library to
                    use NUM_THREADS threads for computing FFTs.

  Logging options:
    Options related to logging and benchmarking.

    -l LEVEL, --loglevel=LEVEL
                    set log level (0:Debug, 1:Info, 2:Warn, 4:Error,
                    5:Critical), default is Debug (0).
    --prof              Log profiling info at program exit.

  Parameter sweep options:
    These options have only an effect when the simulation script uses a
    Controller object to sweep through a parameter range.

    -p RANGE, --param-range=RANGE
                    select parameter set to run, e.g. --param-range=0,64
                    to run sets 0 to 63.
    --print-num-params  print number of sweep parameters to stdout and exit.
    --print-all-params  print all sweep parameters to stdout and exit.

  Miscellanous options:
    --on_io_error=MODE  Specifies what to do when an i/o error occurs when
                    writing an .omf/.vtk file. 0: Abort (default), 1:
                    Retry a few times, then abort, 2: Retry a few times,
                    then pause and ask for user intervention

现在我想编写一个小脚本,它接受自己的命令行参数,然后使用 magnum 模块执行一些小计算。我想使用 argparse 来解析参数。但是,argparse 的优先级似乎比这个外部模块的参数处理低,并且我自己的参数无法被识别:

script2.py

#!/usr/bin/env python
import argparse
import magnum
parser = argparse.ArgumentParser(
        description='TEST')
parser.add_argument('--x',
        help='test_arg')
args = parser.parse_args()
print args.x

调用它:

>>>./scrip2.py --x 3
[WARNING] - Python Imaging Library not found!
[WARNING] - -> This means that the ImageShapeCreator and related classes are not available!
[   INFO] - Imported FFTW wisdom from file
Usage: test.py [options]

test.py: error: no such option: --x

我在 magnum 之前或之后导入 argparse 都没有关系。如果我不导入 magnum,则 argparse 有效:

script3.py

#!/usr/bin/env python
import argparse
parser = argparse.ArgumentParser(
        description='TEST')
parser.add_argument('--x',
        help='test_arg')
args = parser.parse_args()
print args.x

执行它会产生:

>>>./scrip2.py --x 3
3

我的问题是:如何在不编辑 magnum 的情况下阻止 magnum 处理我的命令行参数?

【问题讨论】:

  • 坦率地说,我认为你做不到。如果它试图解析 import 上的参数,它的架构似乎很糟糕。
  • argparse 在导入时什么也不做,因为它应该这样做,这就是顺序无关紧要的原因。 使用 argparse (parse_args) 后导入 magnum 并将 sys.argv 设置为 [] 或任何 magnum 需要
  • 看起来magnum 不是要导入的。它可能是可导入模块的脚本前端吗?
  • 不,确实是要导入的。至少他们所有的文档和示例都这么说。
  • micromagnum.informatik.uni-hamburg.de/pydoc2/cmdargs.html 说:Any script that loads MicroMagnum using the ‘import magnum’ command is subject to these command line arguments:。所以这个import是用来搭建一个计算环境的。

标签: python argparse


【解决方案1】:

虽然我不认为有任何“好的”解决方案,但您可以通过猴子补丁 argparse 使其变为 nop:

class EmptyParser():
    def parse_args():
        return
    ... (more redirects for add_argument)
argparse.ArgumentParser = EmptyParser
import magnum

或者,您可以将导入 magnum 包装在一个函数中,并通过该函数创建一个接口,并在 magnum 解析它们之前创建参数。

def magnum(param1, param2):
    sys.argv = [param1, '--x', param2]
    import magnum

不过,这两种方法都非常 hacky。

【讨论】:

  • magnum 可能不使用 argparse(从错误信息来看,它没有)
  • 对不起,之前的评论有误。更改 sys.argv 后导入 magnum 有效。
【解决方案2】:

为了将来参考,这里是基于上述 cmets / 答案的工作解决方案:

script3.py

#!/usr/bin/env python
import argparse
import sys
parser = argparse.ArgumentParser(
    description='TEST')
parser.add_argument('--x',
    help='test_arg')
args = parser.parse_args()
sys.argv = [sys.argv[0]]
import magnum
print args.x

执行脚本表明 magnum 被正确导入,而且参数已被解析并存储在 args 变量中:

>>>./script3.py --x 3
[WARNING] - Python Imaging Library not found!
[WARNING] - -> This means that the ImageShapeCreator and related classes are not available!
[   INFO] - Imported FFTW wisdom from file
[   INFO] - ----------------------------------------------------------------------
[   INFO] - MicroMagnum 0.2rc3
[   INFO] - Copyright (C) 2012 by the MicroMagnum team.
[   INFO] - This program comes with ABSOLUTELY NO WARRANTY.
[   INFO] - This is free software, and you are welcome to redistribute it under
[   INFO] - certain conditions; see the file COPYING in the distribution package.
[   INFO] - ----------------------------------------------------------------------
[   INFO] - FFTW using 1 threads from now on
[   INFO] - CUDA GPU support: no
3

此解决方案不会将任何参数转发给 magnum,这是我想要实现的。

【讨论】:

    【解决方案3】:

    看github源码,https://github.com/MicroMagnum

    import magnum
    

    导入一个包 (magnum/__init__.py)。 init 中的关键操作是

    config.cfg.initialize(sys.argv)
    

    这定义并创建了一个cfg = MagnumConfig()。那检查环境。它还定义并运行optparse 解析器。

    因此,没有明显的方法可以绕过其解析器并仍然设置计算环境。在import magnum 之前进行自己的解析和调整sys.argv 似乎是唯一的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-25
      • 2020-01-01
      • 2013-03-21
      • 2022-10-02
      相关资源
      最近更新 更多