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

#python #command-line #nltk #global

#python #командная строка #nltk #глобальный

Вопрос:

Я знаю, что существует много решений такого рода вопросов. Однако, похоже, ни один из них не помог в моем случае. Это код, на который я ссылаюсь:

 from nltk.book import text4

def length_frequency(length):
    '''
    Parameter: length as an integer
    '''
    # finds words in given length
    counter = 0
    word_in_length = {}
    for word in text4:
        if len(word) == length and word not in word_in_length:
            word_in_length[word] = text4.count(word)
    for key in word_in_length:
        if word_in_length[key] > counter:
            max = word_in_length[key]
            counter = max
            max_word = key
    print(f'The most frequent word with {length} characters is "{max_word}".nIt occurs {counter} times.')

length_frequency(7)

Output:
The most frequent word with 7 characters is "country".
It occurs 312 times.
  

Когда я пробую этот код в PyCharm, он работает без проблем. Однако, если я использую ее через вызов командной строки, она выдает эту ошибку:

 Traceback (most recent call last):
  File "program5.py", line 67, in <module>
    main()
  File "program5.py", line 60, in main
    length_frequency(input_length)
  File "program5.py", line 35, in length_frequency
    print(f'The most frequent word with {length} characters is "{max_word[0]}".nIt occurs {counter} times.')
UnboundLocalError: local variable 'max_word' referenced before assignment
  

Конечно, для вызова командной строки я импортирую sys и использую sys.argv в качестве аргумента для длины. Я попытался добавить глобальное max_word в начале функции, но это не работает. Я не назначал никакой переменной, такой как max_word, перед этой функцией.

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

1. Если word_in_length пустое, max_word никогда не будет назначено. Таким образом, разница в том, что в среде командной строки text4 пусто.

2. Поскольку присваивание переменной max_word происходит в любом месте функции, и поскольку она не объявлена глобальной, то по определению max_word является локальной переменной. И да, поскольку @Samwise указывает на то, что ей может никогда не присваиваться значение, тогда вы получаете ошибку.

3. @Samwise Почему она пуста?

4. Если значение if никогда не равно true, то max_word значение никогда не присваивается.

5. Держу пари, что вы каким-то образом передаете строку вместо целого числа для length параметра в нерабочем сценарии. Длина любого слова в тексте никогда не будет равна "7" , например.

Ответ №1:

Добавьте некоторую проверку ошибок в функцию, чтобы помочь вам отлаживать:

 def length_frequency(length: int) -> None:
    '''
    Parameter: length as an integer
    '''
    assert isinstance(length, int), f"{repr(length)} is not an int!"
    word_counts = {word: text4.count(word) for word in set(text4) if len(word) == length}
    assert word_counts, f"No words in corpus with length {length}!"
    max_word = max(word_counts.keys(), key=word_counts.get)
    print(f"The most frequent word with {length} characters is {max_word}")
  

(Я немного упростил реализацию только для собственной выгоды, чтобы упростить ее понимание — я почти уверен, что она делает то же самое с меньшей путаницей.)

Обратите внимание, что добавление аннотаций типов также означает, что если у вас была строка кода, например, скажем:

 length_frequency(sys.argv[1])
  

если бы вы запустили mypy ее, она сообщила бы вам об ошибке, не assert требуется:

 test.py:19: error: Argument 1 to "length_frequency" has incompatible type "str"; expected "int"