ejemplo - Cómo llamar al módulo escrito con argparse en el cuaderno iPython
arguments parser python (5)
Estoy tratando de pasar secuencias de BioPython a la implementación de Ilya Stepanov del algoritmo del árbol de sufijos de Ukkonen en el entorno de notebook de iPython. Estoy tropezando con el componente argparse.
Nunca he tenido que lidiar directamente con argparse antes. ¿Cómo puedo usar esto sin volver a escribir main ()?
Por cierto , este repaso del algoritmo de Ukkonen es fantástico .
Me enfrento a un problema similar al invocar argsparse, la cadena ''-f'' estaba causando este problema. Simplemente eliminando eso de sys.srgv hace el truco.
import sys
if __name__ == ''__main__'':
if ''-f'' in sys.argv:
sys.argv.remove(''-f'')
main()
Si usa iPython para realizar pruebas, transformar argparse en un formato de clase puede ser una solución rápida. Este script transforma el módulo argparse en un formato de clase, por lo que no es necesario editar el código interno. Se requiere Python3.
python3 [arg2cls.py] [argparse_script.py]
luego copie y pegue el formato de clase para reemplazar las funciones argparse.
#!/usr/bin/env python3
from collections import OrderedDict
import sys
import re
DBG = False
#add_argument, set_defaults only available.
ListPatt = re.compile(''(/[.*)'')
GbgPatt = re.compile(''(.*)/)[A-z0-9*]'')
LpRegex = re.compile(''/({1,}/s{0,}'')
RpRegex = re.compile(''/s{0,}/){1,}'')
PrRegex = re.compile(''/((.*)(/))(?!.*/))'') # from /( to last /)
CmRegex = re.compile(''/s{0,},/s{0,}'')
StrRegex = re.compile(''/'(.*?)/''')
# Argument dict : store {arg_name : value}
argDct=OrderedDict()
# Remove empty line & Concatenate line-separated syntax.
def preprocess(fname):
try :
with open(fname, ''r'', encoding=''UTF8'') as f:
txt = f.read()
t = txt.splitlines(True)
t = str_list = list( filter(None, t) )
# remove empty line
t = [x for x in t if not re.match(''/s{0,}/n'',x)]
# concatenate multiple lined arguments.
empl = []
for i in range(len(t)-1, 0, -1):
if not re.search(''add_argument|set_defaults'', t[i]):
t[i-1] += t[i]
t[i-1]=re.sub(''/s{0,}/n{0,}/s{0,}'','''',t[i-1])
empl.append(t[i])
for d in empl:
t.remove(d)
for i, line in enumerate(t):
t[i] = line.replace(''/"'', ''/''')
return t
except IOError:
print(''IOError : no such file.'', fname)
# Handling add_argument()
def add_argument(arg_line):
global argDct
arg_line = arg_line
if DBG:
print(''in add_argument : **Pr regex : '' + str(arg_line))
#argname = DdRegex.split(arg_line)[1] # Dash or regex for arg name.
argname = re.search(''/'--(.*?)/''',arg_line)
if not argname:
argname = re.search(''/'-+(.*?)/''',arg_line)
if argname:
argname = argname.group(1).replace(''-'', ''_'')
else :
argname = StrRegex.search(arg_line).group(1)
if not argname:
return # no argument name
argDct[argname]=''''
dtype = re.search('',/s*type/s*=(.*)'', arg_line)
if dtype:
dtype = dtype.group(1)
dtype = CmRegex.split(dtype)[0]
else :
dtype = ''''
dfult = re.search('',/s*default/s*=(.*)'',arg_line)
rquird = re.search('',/s*required/s*=(.*)'',arg_line)
action = re.search('',/s*action/s*=(.*)'',arg_line)
tval = ''''
if dfult:
if DBG:
print(''default exist'')
# type exist
if re.search(''int|float|long|bool|complex'', dtype):
tval = dfult.group(1)
if DBG:
print(''type exist tval :'' +str(tval))
# if not list, use comma as separator.
tval = CmRegex.split(tval)[0]
if ListPatt.search(tval):
tval = ListPatt.search(tval).group(1)
if DBG:
print(''list patt exist tval : '' + str(tval))
else :
if DBG:
print(''no list tval :'' +str(tval))
if not re.search(''int|float|long|bool|complex'', tval) and not LpRegex.search(tval):
tval = re.split(''/s{0,}/){1,}'',tval)[0]
gbg = re.search(GbgPatt, tval)
if gbg:
tval = gbg.group(1)
# type not specified str() assumed.
else:
if DBG:
print(''no type exist'')
tval = dfult.group(1)
regres = StrRegex.match(tval) #help printed?
if regres:
tval = regres.group(0)
else:
tval = CmRegex.split(tval)[0]
if ListPatt.search(tval):
tval = ListPatt.search(tval).group(1)
if DBG:
print(''list patt exist tval : '' + str(tval))
else:
tval = CmRegex.split(tval)[0]
if DBG:
print(''no list tval : '' +str(tval))
if DBG:
print(''value determined : '' + str(tval) +''/n'')
# action or required syntax exist
elif action or rquird :
if DBG:
print(''in action handling'')
msg_str = ''''
if action:
tval = action.group(1)
msg_str = ''action''
else : #required.
tval = rquird.group(1)
msg_str = ''required''
regres = StrRegex.search(tval)
if regres:
tval = regres.group(0)
else :
tval = CmRegex.split(tval)[0]
tval = ''## '' + msg_str + '' '' + tval + '' ##''
else :
argDct[argname] = ''## default None ##''
if tval:
argDct[argname] = tval
# Handling set_default()
def set_defaults(arg_line):
global argDct
if DBG:
print(''Set_defaults : '' + str(arg_line))
dfult = re.split(''/s{0,}=/s{0,}'', arg_line)
tn = dfult[0] # arg name
tv = RpRegex.split(dfult[1])[0] #arg value
argDct[tn]=tv
def transform(fname):
# t : list() contains add_argument|set_defaults lines.
arg_line_list = preprocess(fname)
for i, arg_line in enumerate(arg_line_list):
t = PrRegex.search(arg_line)
if t:
t = t.group(1) # t: content of add_argument Parentheses.
else :
continue # nothing to parse.
if re.search(''add_argument/s*/('', arg_line):
add_argument(t)
elif re.search(''set_defaults/s*/('',arg_line):
set_defaults(t)
else :
# Nothing to parse.
continue
print(''/nclass args:'')
for i in argDct:
print('' '',i, ''='', argDct[i])
print()
def main():
if len(sys.argv) <2:
print(''Usage : python arg2cls.py [target.py] [target2.py(optional)] ...'')
sys.exit(0)
sys.argv.pop(0)
#handling multiple file input.
for fname in sys.argv:
transform(fname)
# TODO : choices=, multiple keywords occurence fix.
if(__name__ == "__main__"):
main()
Github page repo también ofrece una rápida transformación en línea. http://35.192.144.192:8000/arg2cls.html
Espero que sea útil para su prueba. Actualizado - 8 de noviembre, 18 muchos errores son corregidos.
Terminé usando BioPython para extraer las secuencias y luego editar la implementación de Ilya Steanov para eliminar los métodos 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)
Para el algoritmo, hice que main()
tomara un argumento, sus strings
variables, pero esto le envía al algoritmo una lista de objetos especiales de secuencia de BioPython , que no le gustan al módulo re. Así que tuve que extraer la secuencia de la secuencia
suffix_tree.append_string(s)
a
suffix_tree.append_string(str(s.seq))
que parece un poco frágil, pero eso es todo lo que tengo por ahora.
Una alternativa para usar argparse en los cuadernos Ipython es pasar una cadena a:
args = parser.parse_args()
(línea 303 del repositorio git al que hizo referencia.)
Sería algo como:
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''
)
y
args = parser.parse_args("AAA --file /path/to/sequences.txt".split())
Edit: funciona
He tenido un problema similar antes, pero usando optparse
lugar de argparse
.
No necesita cambiar nada en el script original, solo asigne una nueva lista a sys.argv
así:
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()