如何解决我的argparse const = open选项总是创建空文件吗?
我是一名学生,为了练习,我正在创建一个小程序,将.fastq转换为.fasta文件(因此,它基本上删除了一些行)。
我正在尝试使用argparse库实现输入文件和输出文件的典型用户输入。对于输出,我正在尝试三种情况:
- 用户将-o outputfilename.fasta放入以自定义名称创建的输出文件
- 用户不输入参数,然后将输出打印到标准输出
- 用户放置-o而不进行后续操作,那么它应该自己创建一个文件,其名称来自输入.fasta。
#!/usr/bin/python3
import argparse
import re
import sys
c=1
parser = argparse.ArgumentParser()
parser.add_argument("--input","-i",required=True,dest="inputfile",type=argparse.FileType("r"))
parser.add_argument("--output","-o",dest="outfilename",type=argparse.FileType("w"),nargs="?",default=sys.stdout,const=open('{}.fasta'.format(sys.argv[2]),"w" ))
args = parser.parse_args()
for line in args.inputfile:
if c==1:
line=re.sub ("[@]",">",line)
args.outfilename.write (line)
c=c+1
elif c==2:
args.outfilename.write (line)
c=c+1
elif c==3:
c=c+1
else:
c=1
我正在为第三个选项而苦苦挣扎,因为我的代码现在总是创建额外的文件,但是却是空的。因此,基本上,它始终运行我的const =选项,即使根据手册,它也不应该。
(请注意:我键入-o outfilename.fasta,它会产生文件,再加上输入名称中的一个空文件。我不键入任何参数,而是在命令行中打印它并产生空的inputname文件。我键入-o并生成其中带有正确行的inputfilename.fasta文件)
nargs ='?'。如果可能,将从命令行使用一个参数,并将其作为单个项目产生。如果不存在命令行参数,则将生成默认值。请注意,对于可选参数,还有另外一种情况-选项字符串存在,但后面没有命令行参数。在这种情况下,将产生const的值。
因为我认为open命令可能有问题,所以我尝试了
parser.add_argument("--output",const=argparse.FileType('{}.fasta'.format(sys.argv[2]),"w" ))
(我只是想要另一种不用打开就可以写文件的方式) 而且很奇怪,它只给了我这个错误信息:
回溯(最近通话最近): 在第19行的文件“ ./fastqtofastaEXPANDED.py”中 args.outfilename.write(行) AttributeError:“ FileType”对象没有属性“ write”
当我使用-o参数时。因此,这将告诉我相反的事实,它确实仅在键入-o时才使用const选项,而在其他情况下则不使用(因为其他情况下工作正常,没有额外的文件,也没有错误消息)。 我对为什么使用open参数似乎一直使用const感到困惑。
我觉得解决问题的方法可能是在动作课中,但是我还不能解决这个问题。如果const只是按照手册中所说的:D的方式工作,那还是没有问题的,毕竟它是公开的吗?
感谢您的帮助!
编辑:由于const =可能无法按照我想要的方式工作,因此我创建了此变通方法。 基本上只是说如果值是None,它将打开一个新文件,其名称来自第一个输入的负后缀加上新后缀。 如果有人有更好的解决方案,我仍然愿意改变它:)
parser.add_argument("--output",default=sys.stdout)
args = parser.parse_args()
if args.outfilename==None:
i=sys.argv[2][:sys.argv[2].rfind(".")]
args.outfilename=open("{}.fasta".format(i),"w")
#then all the line reading jazz...
if args.outfilename==None:
args.outfilename.close()
#to close the file,if it was used.
解决方法
使用此脚本:
import argparse,sys
# testing the use of `sys.argv` to create a filename (so-so idea)
if sys.argv[1:]:
constname = f'foobar{sys.argv[1]}.txt'
else:
constname = 'foobar1.txt'
parser = argparse.ArgumentParser()
a2 = parser.add_argument('number',type=int)
a1 = parser.add_argument('-o','--output',nargs='?',default='foobar0.txt',const=constname,type=argparse.FileType('w'))
args = parser.parse_args()
print(args)
示例运行:
1253:~/mypy$ rm foobar*
1253:~/mypy$ python3 stack63357111.py
usage: stack63357111.py [-h] [-o [OUTPUT]] number
stack63357111.py: error: the following arguments are required: number
1253:~/mypy$ ls foobar*
foobar0.txt
即使argparse
发出错误并退出,它也会创建default
文件。这是因为output
默认值是在required
检查之前处理的。尝试根据const
中的某个数字创建一个sys.argv
值很笨拙,而且容易出错。
1253:~/mypy$ python3 stack63357111.py 2
Namespace(number=2,output=<_io.TextIOWrapper name='foobar0.txt' mode='w' encoding='UTF-8'>)
1254:~/mypy$ ls foobar*
foobar0.txt
argparse
创建默认值并将其保持打开状态供您使用。
1254:~/mypy$ python3 stack63357111.py 2 -o
Namespace(number=2,output=<_io.TextIOWrapper name='foobar2.txt' mode='w' encoding='UTF-8'>)
1254:~/mypy$ ls foobar*
foobar0.txt foobar2.txt
argparse
基于该const
位置创建number
1254:~/mypy$ python3 stack63357111.py 2 -o foobar3.txt
Namespace(number=2,output=<_io.TextIOWrapper name='foobar3.txt' mode='w' encoding='UTF-8'>)
1254:~/mypy$ ls foobar*
foobar0.txt foobar2.txt foobar3.txt
使用用户提供的名称制作文件。
总的来说,我认为最好简化FileType
的使用,并在解析后处理特殊情况。在解析器中做任何事情都是没有好处的。它的主要工作是确定用户的需求。您自己的代码执行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。