Помимо того, что отступы отпечатка отключаются (помните, что в отступе python входит часть синтаксиса, поэтому будьте осторожны при публикации фрагментов), ваша основная проблема связана с глобальным пространством имен vs.
Глобальное пространство имен содержит имена «верхнего уровня» (имена, определенные на верхнем уровне вашего сценария/модуля, IOW вне функции), локальное пространство имен («локальное» в теле функции) содержит имена, определенные в функции body и аргументы функции, если они есть.
Когда имя используется , но не определено внутри тела функции, оно просматривается в глобальном пространстве имен, поэтому функция может обращаться к именам, которые явно не определены в локальном пространстве имен.
НО - и вот идет сложная часть: «определено в теле функции» означает, есть присвоение этого имени в функции (с помощью одного из «=», «+ =», «- =» , "/ =" и т. д.) в любом месте в теле функции - тот факт, что есть синоним в глобальном пространстве имен, не волшебным образом делает имя глобальным, поэтому, если вы действительно хотите назначить глобальное имя внутри функции (которая почти всегда очень плохая идея, Google «глобалам зло» для получения дополнительной информации), вы должны явно сказать Python это имя следует считать глобальным использованием global
заявления, а именно:
bar = 42
def foo():
global bar
bar = "baaz"
Попытка назначить глобальное имя, не объявляя его глобальным, всегда будет иметь локальное имя. Если вы не пытаетесь получить доступ к этому имени до назначения, у вас не будет явной ошибки (программа технически корректна), но у вас может не быть ожидаемого результата, поскольку глобальное имя не будет затронуто (что логическая ошибка, и обычно труднее отладка), то есть:
>>> baaz = 42
>>> def foo():
... baaz = 84
...
>>> print(baaz)
42
>>> foo()
>>> print baaz
42
>>>
Но если вы пытаетесь получить доступ к имени перед строкой, где она определена, вы получите эту UnboundLocalError
, потому что (по определению) до назначения (локальное) имя не связан с какой-либо ценности:
>>> baaz = 42
>>> def foo():
... print(baaz) # wont print the global 'baaz' but raise an UnboundLocalError
... baaz = 84 # because this line defines `baaz` as a local
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in foo
UnboundLocalError: local variable 'baaz' referenced before assignment
Теперь вы можете проверить свой код и найти, по меньшей мере, три места, где вы do имеют этот шаблон (подсказка: в заданиях правая сторона символа =
выполняется до само назначение).
Вы могло (технически) «решить» это с помощью global
заявления, но это определенно не правильной вещь, чтобы сделать, по крайней мере, если вы надеетесь, чтобы научиться писать хороший (т.е. читаемого, ремонтопригоден) код ,
Хорошей новостью является то, что на самом деле вам практически не нужно изменять глобальную переменную (и я говорю об этом с многолетнего опыта написания/поддержки реальных приложений с полной реализацией) - вам просто нужно 1/передать соответствующие аргументы к вашим функциям и 2/вернуть соответствующие значения из ваших функций. Код верхнего уровня ваших скриптов/модулей должен содержать только индексы импорта и функций/классов/констант, а если это скрипт, это «основная» функция и вызов этой функции.
В качестве примера здесь быстро переписать ваш скрипт без единой глобальной переменной - есть еще много возможностей для улучшения, но по крайней мере это работает, и работает без глобалов:
import random
def intro(tries, size):
print ('the size of your word is {}'.format(size))
print ('you have {} tries'.format(tries))
def guesses(word, tries, output):
guess = ('it')
while len(guess) > 1:
guess = str(raw_input('pick a letter '))
if guess not in word:
print('incorrect')
tries = tries - 1
print('you have {} tries'.format(tries))
else:
print('correct!!')
tries = tries - 1
print('you have {} tries'.format(tries))
position = word.index(guess)
output = output[:position] + guess + output[position+1:]
return tries, output
def main():
print ('this is a game of hangman where you get a word')
print ('that you have to guess letter by letter')
print ('')
print ('')
word_list = ['jazz', 'whale', 'surgery', 'love']
word = random.choice(word_list)
size = len(word)
output = '*' * size
tries = 12
intro(tries, size)
while not (output == word or tries == 0):
tries, output = guesses(word, tries, output)
print(output)
main()
как новичок, его очень неудобно научиться публиковать полную статистику стека при задании вопросов – e4c5
Добро пожаловать в Stack Overflow! См. [Ask] и [mcve]. – Mat
http://stackoverflow.com/questions/370357/python-variable-scope-error –