argparse — запрашивает уже заданный аргумент

#python #command-line #argparse

#python #командная строка #argparse

Вопрос:

я пытаюсь запустить свой файл с помощью следующей команды:

 python3 file.py -p pony_counts num_words
 

где мой код argparse:

 parser = argparse.ArgumentParser()

parser.add_argument('pony_counts', type=str, help="output file for compute_pony_lang.py")    
parser.add_argument('num_words', type=int, help="num of words we want in the output list for each speaker")
parser.add_argument('-p', action='store_true')

args = parser.parse_args()

with open(args.pony_counts) as f:
    df = json.load(f)
    
df = pd.DataFrame(df) # convert json to df
df = df.drop([i for i in df.index if i.isalpha() == False]) # drop words that contain apostrophe

total_words_per_pony = df.sum(axis=0) # find total no. of words per pony
df.insert(6, "word_sum", df.sum(axis=1)) # word_sum = total occurrences of a word (e.g. said by all ponies), in the 7th column of df
tf = df.loc[:,"twilight":"fluttershy"].div(total_words_per_pony.iloc[0:6]) # word x (said by pony y) / word x (total occurrences)
    
ponies_tfidf = tfidf(df, tf)  
ponies_alt_tfidf = tfidf(df, tf)      

d = {}
ponies = ['twilight', 'applejack', 'rarity', 'pinky', 'rainbow', 'fluttershy']

if args.p:
   for i in ponies:
       d[i] = ponies_alt_tfidf[i].nlargest(args.num_words).to_dict()
else: # calculate tfidf according to the method presented in class 
   for i in ponies:
       d[i] = ponies_tfidf[i].nlargest(args.num_words).to_dict()

final = {}
for pony, word_count in d.items():
    final[pony] = list(word_count.keys())  

pp = pprint.PrettyPrinter(indent = 2)
pp.pprint(final)
 

мой код выполняется с помощью команды — однако блок else выполняется независимо от того, содержит ли команда аргумент -p или нет. был бы очень признателен за помощь, спасибо!

Комментарии:

1. ‘-p` получает строку ‘pony_counts’. затем ‘num_words’ присваивается ‘pony_counts’, ничего не оставляя для ‘num_words’. Поместите ‘-p’ последним, если вы не хотите, чтобы он захватывал следующую строку.

2. nargs='?' Необязательный параметр наиболее полезен, когда вы также предоставляете default const параметры и .

3. Это -p не имеет смысла. Почему это type=str так? Почему nargs='?' ? Почему длинное имя --optional вместо того, что лучше соответствует его описанию? Что это вообще значит? Похоже, что это должен быть просто флаг, а не то, что принимает параметр.

4. У нас недостаточно информации о том, что это должно было сделать, чтобы рассказать вам, как это сделать.

5. С этими изменениями я не думаю, что мы можем больше помочь. Я бы рекомендовал добавить a print(args) , чтобы убедиться, что синтаксические анализаторы сделали то, что вы хотите. Затем в if args.p блоке (блоках) и еще один print или 2, чтобы подтвердить, какой блок выполняется. Оценка, основанная только на d значениях, требует гораздо больше знаний о том, что должны делать вычисления.

Ответ №1:

Запуск команды:

 python3 file.py -p 10
 

эквивалентно:

 python3 file.py -p=10
 

В Bash (при условии, что вы используете Mac или Linux) пробелы обрабатываются так же, как знак равенства после флага. Итак, если вы хотите передать значение для -p флага, вам нужно будет структурировать его более похоже:

 python3 file.py -p <tfidf arg> <pony_counts> <num_words>
 

Просто читая ваш код, возможно, вы хотите -p использовать флаг true / false вместо ввода? Если это так, вы можете использовать action='store_true' или action='store_false' . В документах указано, как это сделать. Удаление примера из документации:

 >>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('--bar', action='store_false')
>>> parser.add_argument('--baz', action='store_false')
>>> parser.parse_args('--foo --bar'.split())
Namespace(foo=True, bar=False, baz=True)
 

Комментарии:

1. Пробелы / = эквивалентность — это не то, что делает Bash. Эта эквивалентность выполняется только в том случае, если программа, получающая аргументы, фактически рассматривает обе версии как эквивалентные. В данном случае это что-то argparse обрабатывает.

2. Извинения. Вы правы. Да, эквивалентность зависит от приложения, обрабатывающего входные данные, но это обычно справедливо для многих современных CLI.