#python #python-3.x #argparse
#python #python-3.x #argparse
Вопрос:
для моей программы мне нужно разобрать один файл .xml и один файл .ttf. Я не хочу беспокоить пользователя, вводя идентификатор аргумента, но я бы предпочел принять проанализированные данные, а затем решить, какой файл какой на основе .extension . Возможно ли с помощью argparser сделать что-то вроде
py -3 file.py "C/documents/file.xml" "C/documents/font.ttf"
в неизвестном порядке и решить после получения путей к файлам? Мне просто нужно знать, как преобразовать такую информацию в программу Python, не прерывая ее. Спасибо
Комментарии:
1. О чем вы здесь спрашиваете? О каком «прерывании» вы говорите? Вы можете сделать
if param.endswith('xml')
, например.2. Другим вариантом может быть просто повторение
sys.argv
и проверка с помощью.endswith('.xml')
Ответ №1:
После получения входных данных от пользователя, предполагая, что их пути находятся в var1
и var2
, просто проверьте расширения, используя var1.split(".")[1]
и var2.split(".")[1]
(они возвращают строку после точки, которая является вашим расширением файла) и сделайте что-то вроде этого (предполагая, что пользователь не поместил два файла с одинаковым расширением)
if var1.split(".")[1] == "xml"
xml_file=var1
ttf_file=var2
else:
xml_file=var2
ttf_file=var1
Комментарии:
1. Я хотел знать, как его разобрать. Я не понимаю комментарий Дэниела Роземана, но Ральф любезно указал, что это можно сделать с помощью sys.argv, я был сосредоточен на поиске решения, связанного с argparse, но я не знаю, как это сделать с помощью этого модуля
2. Я бы рекомендовал для вашего кода использовать split(‘.’)[-1], вы не можете знать, сколько точек может быть в пути. Который совпадает с endswith. Если путь является C/master.on.xml/documents/file.xml тогда у вас проблема
Ответ №2:
Благодаря Ralf в комментариях под моим вопросом я пришел к решению
args = sys.argv[1:] #the first one is path of your python script
if len(args) > 3:
print('wrong')
for i in args:
if i.endswith('.xml'):
xml_path = i
if i.endswith('.ttf'):
font_path = i
Комментарии:
1. Обратите внимание, что если вы передадите более одного XML-имени, последнее выиграет, а остальные будут молча проигнорированы. Это легко исправить с помощью проверки на
xml_path is None
перед назначением и сигнализировать об ошибке.2. вы правы, спасибо. Я думал, что это можно было бы решить с помощью len (args), но two .xml может быть проанализирован, и он также пройдет через него.
Ответ №3:
Вы можете использовать пользовательское действие. Вызов delattr
кажется мне немного сомнительным, но сохраняет пространство имен чистым.
class InputFileAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values.endswith(".ttf"):
dest = "ttf_file"
elif values.endswith(".xml"):
dest = "xml_file"
else:
raise argparse.ArgumentTypeError("File must have .ttf or .xml extension")
setattr(namespace, dest, values)
delattr(namespace, self.dest)
p = argparse.ArgumentParser()
p.add_argument("input1", action=InputFileAction)
p.add_argument("input2", action=InputFileAction)
Несколько примеров:
>>> p.parse_args(["foo.ttf", "foo.xml"])
Namespace(ttf_file='foo.ttf', xml_file='foo.xml')
>>> p.parse_args(["foo.xml", "foo.ttf"])
Namespace(ttf_file='foo.ttf', xml_file='foo.xml')