Позиционный arg начинается с дефиса в argparse [duplicate]

Вы не можете установить атрибут xlink: href с помощью setAttribute, вам нужно использовать setAttributeNS

var svgElt = document.getElementById('svg_box');
var newUse = document.createElementNS("http://www.w3.org/2000/svg", 'use');
newUse.setAttribute('x', '150px');
newUse.setAttribute('y', '10px');
newUse.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#b');
svgElt.appendChild(newUse);
<!doctype html>
<body>
    <svg
     id="svg_box"
     width="200px"
     height="100px"
     viewBox="0 0 200 100"
     style="background-color:pink"
    >
        <defs>
            <g id="b">
                <path d="m 4.23,7.7400001 0,-7.14000002 C 4.23,0.18000008 3.96,7.6293944e-8 3.39,7.6293944e-8 l -2.22,0 C 0.39000002,7.6293944e-8 1.9073486e-8,0.36000008 1.9073486e-8,1.0500001 c 0,0.75 0.420000000926514,1.02 1.349999980926514,1.02 0.21,0 0.45,0.03 0.66,0.03 L 2.01,17.1 c -0.12,0 -0.21,0 -0.3,0 C 0.51000002,17.1 1.9073486e-8,17.28 1.9073486e-8,18.12 1.9073486e-8,18.81 0.39000002,19.17 1.17,19.17 l 2.67,0 c 0.45,0 0.6,-0.24 0.6,-0.75 l 0,-1.17 c 0.99,1.47 2.52,2.19 4.56,2.19 3.93,0 6.93,-3.09 6.93,-6.9 0,-3.8699999 -2.94,-6.8999999 -6.87,-6.8999999 -2.07,0 -3.72,0.72 -4.83,2.1 z M 8.79,17.13 c -2.73,0 -4.62,-1.98 -4.62,-4.68 0,-2.7299999 1.92,-4.6799999 4.62,-4.6799999 2.73,0 4.62,2.01 4.62,4.6799999 0,2.79 -1.89,4.68 -4.62,4.68 z" />
            </g>
        </defs>
        <use x="130px" y="10px" xlink:href="#b" /> 
    </svg>

</body>

35
задан hpaulj 19 February 2014 в 21:59
поделиться

3 ответа

Вы можете запустить аргумент с пробелом python tst.py -e ' -e blah' как очень простой способ обхода. Просто lstrip() возможность вернуть его в нормальное состояние, если хотите.

Или, если первый «вспомогательный аргумент» также не является допустимым аргументом для исходной функции, тогда вам не нужно вообще ничего не делать. То есть единственная причина, по которой python tst.py -e '-s hi -e blah' не работает, состоит в том, что -s является допустимой опцией tst.py.

Кроме того, модуль optparse , теперь устаревший , работает без каких-либо проблем.

10
ответ дан William 22 August 2018 в 17:50
поделиться
  • 1
    Я не думаю, что это происходит, потому что -s является допустимым вариантом для подпарамера. Я попробовал его с python Application.py queue -e & quot; -notarealoption & quot; и получил ту же ошибку. Мне нравится использовать lstrip немного лучше, чем заменять +, - как это предполагал SethMMorton, но, похоже, должен быть способ процитировать строку, так что ничто внутри нее не заменяется / изменено / не читается argparse. – sfendell 23 April 2013 в 18:17
  • 2
    Да неужели? Я только что основал это предположение от моего короткого тестирования прямо сейчас. Я сделал сценарий, который принял один аргумент, -a, и просто отправил его -a '-b hello', и он работал отлично. Но я использую другую версию Python, я думаю. – William 23 April 2013 в 18:27
  • 3
    Я редактировал свой оригинальный вопрос. По-видимому, это известная ошибка в argparse в & gt; 2.7 :( Я закончил изменение sys.argv до того, как я вызвал parser.parse_args (), чтобы добавить фиктивный символ в начало -env-опции и впоследствии отключить его. Это хаки и неряшливо, но я, наконец, получил то, что хотел. – sfendell 23 April 2013 в 18:50
  • 4
    Я успел использовать строку в кавычках, которая начинается с пробела. Таким образом, мой парсер потерпел неудачу при многозначном вводе аргумента -10:a 10:b, но работал для ' -10:a' 10:b. – J.B. Brown 30 October 2013 в 10:15

Этот вопрос подробно обсуждается в http://bugs.python.org/issue9334 . Большая часть активности была в 2011 году. Я добавил патч в прошлом году, но есть довольно отставание от патчей argparse.

Проблема заключается в потенциальной двусмысленности в строке, такой как '--env' или "-s WHATEVER -e COOL STUFF", когда она следует за опцией, которая принимает аргумент.

optparse выполняет простой анализ слева направо. Первый --env - это флаг опции, который принимает один аргумент, поэтому он потребляет следующий, независимо от того, как он выглядит. argparse, с другой стороны, дважды проходит строки. Сначала он классифицирует их как «O» или «A» (флаг или аргумент опций). Во втором цикле он потребляет их, используя сопоставление типа re, подходящее для обработки значений переменной nargs. В этом случае мы видим, что у нас есть OO, два флага и никаких аргументов.

Решение при использовании argparse состоит в том, чтобы убедиться, что строка аргумента не будет путаться для флажка параметра. Возможности, которые были показаны здесь (и в проблеме с ошибкой), включают в себя:

--env="--env"  # clearly defines the argument.

--env " --env"  # other non - character
--env "--env "  # space after

--env "--env one two"  # but not '--env "-env one two"'

Сам по себе '--env' выглядит как флаг (даже при цитировании, см. sys.argv), но затем следуют другие строк это не так. Но "-env one two" имеет проблемы, поскольку он может быть проанализирован как ['-e','nv one two'], флаг `-e ', за которым следует строка (или даже больше параметров).

-- и nargs=argparse.PARSER также могут используется для принудительного [[22]) для просмотра всех последующих строк в качестве аргументов. Но они работают только в конце списков аргументов.

В вопросе 9334 есть исправление, добавляющее режим args_default_to_positional=True. В этом режиме анализатор только классифицирует строки как флаги опций, если он может четко соответствовать им с определенными аргументами. Таким образом, «-one» в «--env -one» будет классифицирован как аргумент. Но второй '--env' в '--env --env' по-прежнему будет классифицироваться как флаг опции.


Расширение в соответствующем случае в

Использование аргумента argparse с аргументами, начинающимися с тире («-»)

parser = argparse.ArgumentParser(prog="PROG")
parser.add_argument("-f", "--force", default=False, action="store_true")
parser.add_argument("-e", "--extra")
args = parser.parse_args()
print(args)

производит

1513:~/mypy$ python3 stack16174992.py --extra "--foo one"
Namespace(extra='--foo one', force=False)
1513:~/mypy$ python3 stack16174992.py --extra "-foo one"
usage: PROG [-h] [-f] [-e EXTRA]
PROG: error: argument -e/--extra: expected one argument
1513:~/mypy$ python3 stack16174992.py --extra "-bar one"
Namespace(extra='-bar one', force=False)
1514:~/mypy$ python3 stack16174992.py -fe one
Namespace(extra='one', force=True)

Случай «-foo one» терпит неудачу, потому что -foo интерпретируется как флаг -f плюс неуказанные дополнения. Это то же самое действие, которое позволяет -fe интерпретироваться как ['-f','-e'].

Если я изменю nargs на REMAINDER (не PARSER), все после -e интерпретируется как аргументы для этого флага:

parser.add_argument("-e", "--extra", nargs=argparse.REMAINDER)

Все дела работают. Обратите внимание, что это список. И кавычки не нужны:

1518:~/mypy$ python3 stack16174992.py --extra "--foo one"
Namespace(extra=['--foo one'], force=False)
1519:~/mypy$ python3 stack16174992.py --extra "-foo one"
Namespace(extra=['-foo one'], force=False)
1519:~/mypy$ python3 stack16174992.py --extra "-bar one"
Namespace(extra=['-bar one'], force=False)
1519:~/mypy$ python3 stack16174992.py -fe one
Namespace(extra=['one'], force=True)
1520:~/mypy$ python3 stack16174992.py --extra --foo one
Namespace(extra=['--foo', 'one'], force=False)
1521:~/mypy$ python3 stack16174992.py --extra -foo one
Namespace(extra=['-foo', 'one'], force=False)

argparse.REMAINDER похож на '*', за исключением того, что он принимает все, что следует, независимо от того, выглядит он как флаг или нет. argparse.PARSER больше похож на «+», поскольку он сначала ожидает такой же positional аргумент. Это nargs, который использует subparsers.

Это использование REMAINDER задокументировано, https://docs.python.org/3/library/argparse.html#nargs

11
ответ дан hpaulj 22 August 2018 в 17:50
поделиться
  • 1
    Большое спасибо: nargs=argparse.PARSER помог мне. – guettli 3 April 2014 в 08:33
  • 2
    Я не совсем уверен, что изменилось, но теперь python Application.py queue -env "-s WHATEVER -e COOL STUFF" работает. queue -env "-foo" все еще вызывает ошибку, потому что автономный «-foo» (или «-foo») по-прежнему интерпретируется как флаг. Пространства после знака ученика имеют значение. – hpaulj 7 August 2017 в 16:58

Обновленный ответ:

Вы можете поместить знак равенства, когда вы его назовете:

python Application.py -env="-env"

Оригинальный ответ:

У меня тоже есть у вас были проблемы, которые вы делаете, но есть способ обхода в argparse, который является методом parse_known_args . Это позволит всем аргументам, которые вы не определили, пройти через парсер с предположением, что вы будете использовать их для подпроцесса. Недостатки в том, что вы не будете получать сообщения об ошибках с плохими аргументами, и вам нужно будет убедиться, что между вашими параметрами и параметрами вашего подпроцесса нет конфликта.

Другой способ может заключаться в том, чтобы заставить пользователя для использования плюса вместо минуса:

python Application.py -e "+s WHATEVER +e COOL STUFF"

, а затем вы меняете «+» на «-» в пост-обработке перед тем, как перейти к вашему подпроцессу.

36
ответ дан SethMMorton 22 August 2018 в 17:50
поделиться
  • 1
    Я не думаю, что parse_known_args помогает мне. Я вообще не хочу читать аргументы в кавычках; Я бы хотел, чтобы строка с кавычками передавалась как один объект в -env. Я подумал о том, чтобы идти по пути обработки сообщений, и, вероятно, буду, если не получу лучшего ответа отсюда, но он чувствует себя взломанным, и это означает, что + символы в строке изменены на -. Я действительно хотел бы передать строку с любыми символами в ней вообще. – sfendell 23 April 2013 в 18:11
  • 2
    Я вижу, что вы спрашиваете ... Если вы хотите читать в нескольких строках без кавычек, используйте nargs='+', который сообщает -env читать в одной или нескольких строках. – SethMMorton 23 April 2013 в 18:21
  • 3
    Но мне также хотелось бы, чтобы некоторые из этих строк имели тире в них, даже, возможно, с теми же именами, что и аргументы в моем подпараллеле. Что-то вроде python Application.py queue -env & quot; -env blah & quot; должно сработать. – sfendell 23 April 2013 в 18:23
  • 4
    Извините, у меня нет идей. Я попытался сделать то же самое, но в конечном итоге решил просто переопределить параметры в своем парсере, чтобы передать подпроцесс, потому что я не мог получить то, что вы пытаетесь сделать, чтобы работать. Удачи! Надеюсь, кто-то придумает хорошие предложения, которые мы можем попробовать. – SethMMorton 23 April 2013 в 18:28
  • 5
    @sfendel Попробуйте использовать знак равенства: python Application.py -env="-env" – SethMMorton 23 April 2013 в 21:11
Другие вопросы по тегам:

Похожие вопросы: