在我正在编写的程序(基于文本的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出错。有什么办法可以解决这个问题吗?我试图绕过这几个小时,但我似乎无法弄明白。这根本不可能吗?
非常感谢您阅读本文,并感谢所有给予我的帮助。
答案 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文本框小部件。