在我正在编写的程序(基于文本的角色扮演游戏)中,我将包含“脚本”,即为游戏添加交互功能的小代码片段(例如当您进入房间时 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
如您所见,: 字符(选择 block 所需的)会导致 exec 出错。我能做些什么来解决这个问题吗?我已经尝试解决这个问题几个小时了,但我似乎无法弄清楚。这根本不可能吗?
非常感谢您阅读本文,并且感谢您给予我的所有帮助。
最佳答案
您使用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 提供正确的空格.
关于python - exec() 在遇到 : character 时引发 'unexpected EOF' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5771392/