遇到:字符时,exec()引发'意外的EOF'错误

时间:2011-04-24 15:23:06

标签: python parsing exec eof

在我正在编写的程序(基于文本的RPG)中,我将包括“脚本”,为游戏添加交互功能的小块代码(例如,当你进入房间时NPC问候你)。编写我自己的脚本语言/解析器似乎是一项非常重要的任务,所以我认为我会使用Python代码本身。它可以完成我需要的所有脚本,所以我开始乱砍。对于简单的事情,如打印语句或数学,exec()工作正常。当我遇到麻烦时就会出现问题。这是在行动:

第一个 - 工作代码(来自交互式shell):

>>> 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 个答案:

答案 0 :(得分:4)

您使用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

你已经想通过一个特殊的char(@)来结束输入,但如果他需要编写多行语句,你也应该期望你的用户为Python提供正确的空格。

答案 1 :(得分:2)

从IDLE编辑窗口运行时,以下内容适用于2.7:

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

Shell窗口中的结果:

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

请注意,行需要与'\ n'连接,而不是''。此外,加入后,代码段不会以'\ n'结尾。我相信这可能是早期版本的Python的问题,其中exec可能需要一个终端'\ n'用于多行块。

也就是说,这是一种输入代码的AWFUL方式。我花了三次尝试进入上面没有错误!例如,对于初始输入和编辑来说,更好的是tkinter文本框小部件。