exec () вызывает неожиданную ошибку EOF при обнаружении символа: - PullRequest
2 голосов
/ 24 апреля 2011

В программу, которую я пишу (текстовый рпг), я собираюсь включить «скрипты», небольшие кусочки кода, которые добавляют интерактивную функциональность в игру (например, приветствие NPC при входе в комнату). Написание собственного скриптового языка / парсера казалось довольно сложной задачей, поэтому я решил вместо этого использовать сам код Python. Он может делать все, что мне нужно из сценариев, поэтому я начал взламывать. Для простых вещей, таких как операторы print или math, exec () работает нормально. Когда у меня возникает блок, возникает проблема. Вот оно в действии:

Первый - рабочий код (из интерактивной оболочки):

>>> x = ''
>>> y = []
>>> while x != '@':
        y.append(x)
        x = raw_input(compile('''''', '<string>', 'exec'))

<code object <module> at 0000000002B1DBB0, file "<string>", line 1>name = 'Drew'
<code object <module> at 0000000002B1DBB0, file "<string>", line 1>print 'Hello, %s' % name
<code object <module> at 0000000002B1DBB0, file "<string>", line 1>@
>>> del x[0] # removes the empty field created by the first y.append(x)
>>> for line in y:
        exec line

>>> Hello, Drew

Теперь об ошибке (снова из интерактивного приглашения):

>>> x = ''
>>> y = []
>>> while x != '@':
        y.append(x)
        x = raw_input(compile('''''', '<string>', 'exec'))

<code object <module> at 0000000002B1DBB0, file "<string>", line 1>name = 'Drew'
<code object <module> at 0000000002B1DBB0, file "<string>", line 1>if name == 'Drew':
<code object <module> at 0000000002B1DBB0, file "<string>", line 1>print 'Hi, %s!' % name
<code object <module> at 0000000002B1DBB0, file "<string>", line 1>else:
<code object <module> at 0000000002B1DBB0, file "<string>", line 1>print 'Greetings, stranger.'
<code object <module> at 0000000002B1DBB0, file "<string>", line 1>@
>>> del y[0]
>>> for line in y:
        exec line

Traceback (most recent call last):
  File "<pyshell#308>", line 2, in <module>
    exec line
  File "<string>", line 1
    if name == 'Drew':
                     ^
SyntaxError: unexpected EOF while parsing

Итак, как вы видите, символ: (который требуется для блоков выбора) вызывает ошибку exec. Что я могу сделать, чтобы это исправить? Я пытался обойти это часами, но я не могу понять это. Это просто невозможно?

Большое спасибо за то, что прочитали это, и я ценю всю помощь, оказанную мне.

Ответы [ 2 ]

4 голосов
/ 24 апреля 2011

Вы используете exec для оценки одной строки. В этом коде:

if a == b:
  do_c()

Первая строка, оцененная сама по себе, является синтаксической ошибкой . Вышесказанное также можно сложить в одну строку как:

if a == b: do_c()

В более общем случае, разрешив несколько строк, вы можете собрать весь ввод в строку (с правильным пробелом), а затем вызвать exec для этого:

source = '''
name = "joe"
if name == "joe":
    print "hi joe"
else:
    print "hi stranger"
'''
exec source

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

2 голосов
/ 24 апреля 2011

Следующее работает в 2.7 при запуске из окна редактирования IDLE:

line=''
lines = []
print "Enter Python lines (@ to quit):"
while line != '@':
    line=raw_input()
    lines.append(line)
lines.pop() # delete '@' line
lines = '\n'.join(lines)
exec lines

Результат в окне оболочки:

>>> 
Enter Python lines (@ to quit):
name = 'Terry'
if name == 'Drew':
  print 'Hi Drew'
else:
  print 'Hi stranger'
@
Hi stranger

Обратите внимание, что строки должны быть соединены с '\ n ', а не' '.Кроме того, после объединения фрагмент не заканчивается на «\ n».Я полагаю, что это может быть проблемой с более ранними версиями Python, где exec, возможно, понадобился терминал '\ n' для многострочных блоков.

Тем не менее, это УДИВИТЕЛЬНЫЙ способ ввода кода.Мне потребовалось три попытки войти в вышесказанное без ошибок!Гораздо лучше как для первоначального ввода, так и для редактирования будет, например, виджет текстового поля tkinter.

...