如何在 iPython notebook 中调用用 argparse 编写的模块

How to call module written with argparse in iPython notebook

我正在尝试在 iPython 的笔记本环境中将 BioPython 序列传递给 Ilya Stepanov's implementation of Ukkonen's suffix tree algorithm。我在 argparse 组件上绊倒了。

我以前从来没有直接与 argparse 打过交道。如何在不重写 main() 的情况下使用它?

顺便说一句,this writeup of Ukkonen's algorithm is fantastic

我最终使用 BioPython 提取序列,然后编辑 Ilya Steanov 的实现以删除 argparse 方法。

import imp
seqs = []
lcsm = imp.load_source('lcsm', '/path/to/ukkonen.py')
for record in SeqIO.parse('/path/to/sequences.txt', 'fasta'):
    seqs.append(record)
lcsm.main(seqs)

对于算法,我让 main() 接受一个参数,即他的 strings 变量,但这会向算法发送一个特殊的 BioPython Sequence objects 列表,re 模块不会这样做像。所以我不得不提取序列字符串

suffix_tree.append_string(s)

suffix_tree.append_string(str(s.seq))

这看起来有点脆弱,但这就是我现在所拥有的。

我有 a similar problem before, 但使用 optparse 而不是 argparse

您无需更改原始脚本中的任何内容,只需将新列表分配给 sys.argv,如下所示:

if __name__ == "__main__":
    from Bio import SeqIO
    path = '/path/to/sequences.txt'
    sequences = [str(record.seq) for record in  SeqIO.parse(path, 'fasta')]
    sys.argv = ['-f'] + sequences
    main()

在 Ipython 笔记本中使用 argparse 的替代方法是将字符串传递给:

args = parser.parse_args() (您引用的 git 存储库的第 303 行。)

会是这样的:

parser = argparse.ArgumentParser(
        description='Searching longest common substring. '
                    'Uses Ukkonen\'s suffix tree algorithm and generalized suffix tree. '
                    'Written by Ilya Stepanov (c) 2013')

parser.add_argument(
        'strings',
        metavar='STRING',
        nargs='*',
        help='String for searching',
    )

parser.add_argument(
        '-f',
        '--file',
        help='Path for input file. First line should contain number of lines to search in'
    )

args = parser.parse_args("AAA --file /path/to/sequences.txt".split())

编辑:有效

使用args = parser.parse_args(args=[])可以解决执行问题。

或者您可以将其声明为 class 格式。

class Args:
  data = './data/penn'
  model = 'LSTM'
  emsize = 200
  nhid = 200

args=Args()

我在调用 argsparse 时遇到了类似的问题,字符串“-f”导致了这个问题。只需将其从 sys.srgv 中删除即可。

import sys
if __name__ == '__main__':
    if '-f' in sys.argv:
        sys.argv.remove('-f')
    main()

清洁 sys.argv

import sys; sys.argv=['']; del sys

https://github.com/spyder-ide/spyder/issues/3883#issuecomment-269131039

如果所有参数都有默认值,那么将其添加到笔记本顶部就足够了:

import sys
sys.argv = ['']

(否则,只需添加必要的参数而不是空字符串)

如果您不想更改您编写或复制的原始 argparse 函数的任何参数和工作机制。

为了让程序正常运行,有一个大多数情况下都有效的简单解决方案。

您可以使用以下命令安装 jupyter-argparser

pip install jupyter_argparser

由于包的维护者,代码无需任何更改即可工作。

这是我的代码,运行良好,我不会担心环境发生变化。

import sys
temp_argv = sys.argv

try:
    sys.argv = ['']
    print(sys.argv)
    args = argparse.parser_args()
finally:
    sys.argv = temp_argv
    print(sys.argv)

假设你在python中有这个小代码:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="increase output verbosity",
                    action="store_true")
parser.add_argument("-v_1", "--verbose_1", help="increase output verbosity",
                    action="store_true")
args = parser.parse_args()

要在 Jupyter notebook 中编写此代码,请这样写:

import argparse

args = argparse.Namespace(verbose=False, verbose_1=False)

注意: 在python中,您可以在运行时传递参数,但在 Jupyter notebook 中则不会case 所以要小心你的参数的数据类型。