在 python 中使用 argparse 更改文件扩展名
Posted
技术标签:
【中文标题】在 python 中使用 argparse 更改文件扩展名【英文标题】:Changing file extensions using argparse in python 【发布时间】:2013-06-14 21:58:56 【问题描述】:我想将给定 csv 文件的文件扩展名更改为 xml 扩展名,反之亦然。在命令行,我可以输入以下内容
Boo a.csv. giving a.xml
Boo a.xml. giving a.csv
Boo a.csv -out shoes.xml giving shoes.xml
这是我更新的代码:
import os
import sys
import argparse
import csv
import indent
from xml.etree.ElementTree import ElementTree, Element, SubElement, Comment, tostring
def get_args(args):
parser = argparse.ArgumentParser(description = "Converts CSV to XML")
parser.add_argument('-v','--verbose',action='store_true',dest='verbose',help='Increases messages being printed to stdout')
parser.add_argument("inputfile", help="Please input the name of the CSV file")
parser.add_argument('-o','--outputfile',help='(optional) Output file name',nargs='?')
args = parser.parse_args()
ext = os.path.splitext(args.inputfile)[1].lower()
if args.outputfile is None:
if ext == ".csv":
args.outputfile = os.path.splitext(args.inputfile)[0] + '.xml'
elif ext == ".xml":
args.outputfile = os.path.splitext(args.inputfile)[0] + '.csv'
else:
sys.stderr.write('ERROR: Invalid extension %s\n' % ext)
sys.exit(1)
return args
def main(argv):
args = get_args(argv[0:])
if args is None:
return 1
reader = read_csv(args.inputfile)
if args.verbose:
print ('Verbose Selected')
if args.verbose:
print ('Convert to XML with set name')
generate_xml(reader, args.outputfile)
return 0
def read_csv(inputfile):
return list(csv.reader(inputfile))
def generate_xml(reader,outfile):
root = Element('Solution')
root.set('version','1.0')
tree = ElementTree(root)
head = SubElement(root, 'DrillHoles')
description = SubElement(head,'description')
current_group = None
i = 0
for row in reader:
if i > 0:
x1,y1,z1,x2,y2,z2,cost = row
if current_group is None or i != current_group.text:
current_group = SubElement(description, 'hole','hole_id':"%s"%i)
collar = SubElement (current_group, 'collar','':', '.join((x1,y1,z1))),
toe = SubElement (current_group, 'toe','':', '.join((x2,y2,z2)))
cost = SubElement(current_group, 'cost','':cost)
i+=1
head.set('total_holes', '%s'%i)
indent.indent(root)
tree.write(outfile)
if (__name__ == "__main__"):
sys.exit(main(sys.argv))
现在我在 x1,y1,z1,x2,y2,z2,cost = row 处收到一个错误,这是一个值错误,提示:需要多个值才能解包
【问题讨论】:
tree 变量是什么? 也不好说== None
使用is None
或更好if not args.outputfile:
使用 python 调试器,例如 idle、eric 或 komodo。只需几分钟的代码,答案就会一目了然!
【参考方案1】:
问题是您没有将扩展名分配给 ext。扩展名是 splitext 返回的第二项。对于 ext 既不是 .xml 也不是 .csv 的情况,您还应该有另一个 else 条件。此错误路径会向您显示问题。
编辑:您的代码还有其他问题,所以我添加了一些标记为 TODO 的 cmets。您不应该将参数解析与程序的实现混为一谈。所以,你调用 tree.whatever() 的地方应该在你清理了你的参数之后完成。你会发现你只需要在最后调用一次 tree.whatever()。
import argparse
import os
import sys
import csv
from xml.etree.ElementTree import ElementTree, Element, SubElement
parser = argparse.ArgumentParser(description = "Converts CSV to XML")
parser.add_argument("inputfile", help="Please input the name of the CSV file")
parser.add_argument('-o','--outputfile',help='(optional) Output file name',nargs='?')
args = parser.parse_args()
ext = os.path.splitext(args.inputfile)[1].lower()
if args.outputfile is None:
if ext == ".csv":
args.outputfile = os.path.splitext(args.inputfile)[0] + '.xml'
tree.write(args.outputfile) # TODO: There is no 'tree' defined
elif ext == ".xml":
args.outputfile = os.path.splitext(args.inputfile)[0] + '.csv'
tree.write(args.outputfile) # TODO: There is no 'tree' defined
else:
sys.stderr.write('ERROR: Invalid extension %s\n' % ext)
sys.exit(1)
# TODO: This should be removed completely
if args.outputfile:
args.outputfile = os.path.splitext(args.outputfile)[1] #handles the condition if there is an outputfile set by the user
# TODO: create tree and do the work here
【讨论】:
好的,谢谢,我已将树合并到其中,我可以向您展示我更新的代码吗? @Andy,您可以使用新代码更新您的帖子。就个人而言,如果您将其放在当前帖子的底部并附上您已更改的注释,我觉得不会那么混乱。 @Andy,由于 args.inputfile 是一个文件名,所以在传递给 csv.reader 之前需要打开它。将reader = read_csv(args.inputfile)
更改为reader = read_csv(open(args.inputfile))
以上是关于在 python 中使用 argparse 更改文件扩展名的主要内容,如果未能解决你的问题,请参考以下文章
ArgParse Python 模块:更改继承参数的默认参数值
使用 Python 模块 argparse 的单个选项的自定义值名称和多个属性