Google App Engine shell中的Python raw_input
我有一个Python程序,它是在命令行上运行的。这个程序使用raw_input()来从用户的键盘读取字符串。我想把这个程序放到Google App Engine上,并且想用App Engine Shell,因为它有一个命令提示符。
不过,这个shell似乎提供了一个“假”的提示符,当我在程序中使用raw_input()时,它只是返回了EOF(文件结束符)。
你有没有什么建议,可以用什么代替raw_input(),或者有什么其他方法可以让交互式的Python控制台应用可用?(不需要太复杂的东西,只要能读取缓冲字符串就行。)
补充说明:这个程序是一个在线冒险游戏,类似于Zork http://thcnet.net/error/index.php
3 个回答
我通过把程序改成生成器解决了这个问题。
你可以在这里找到示例代码:https://github.com/larsr/consoleapp
你也可以在这里试用一下:http://pyconsoleapp.appspot.com/
这个程序存放在prog.py文件里,稍微做了一些修改;把raw_input()
替换成了yield,把打印的部分换成了一个修改过的打印方式。App Engine的处理程序会通过generator.send(input)把HTML表单中的输入传给生成器,而这个输入是通过yield语句“返回”的。
while True:
print "What's your name?"
name = raw_input()
print "Hello "+name+"!"
print
需要修改成
from appconsole import myprint, printoutput
def prog_gen(namn=""):
while True:
myprint("What's your name?")
name = yield printoutput()
myprint("Hello "+name+"!")
myprint()
看起来,App Engine的命令行工具并不能和浏览器之间的AJAX连接进行直接的输入输出,也就是说,你不能通过这个方式来实现你的目标。
与其把命令行界面直接放到网上(这听起来并不是个好主意),我建议你可以做一个简单的表单,作为一个前端,来和下面的命令行程序进行交互。
这个应用的Python源代码可以在Google Code上找到,你可以去看看,或者拿来用。为了安全起见,raw_input()可能被禁用了,所以它总是返回EOF(文件结束符)。
这个命令行界面使用了AJAX技术,简单来说就是从输入区域获取代码并进行解析。你可以在这个库里查看shell.js:
/**
* This is the prompt textarea's onkeypress handler. Depending on the key that
* was pressed, it will run the statement, navigate the history, or update the
* current statement in the history.
*
* @param {Event} event the keypress event
* @return {Boolean} false to tell the browser not to submit the form.
*/
shell.onPromptKeyPress = function(event) {
var statement = document.getElementById('statement');
if (this.historyCursor == this.history.length - 1) {
// we're on the current statement. update it in the history before doing
// anything.
this.history[this.historyCursor] = statement.value;
}
// should we pull something from the history?
if (event.ctrlKey && event.keyCode == 38 /* up arrow */) {
if (this.historyCursor > 0) {
statement.value = this.history[--this.historyCursor];
}
return false;
} else if (event.ctrlKey && event.keyCode == 40 /* down arrow */) {
if (this.historyCursor < this.history.length - 1) {
statement.value = this.history[++this.historyCursor];
}
return false;
} else if (!event.altKey) {
// probably changing the statement. update it in the history.
this.historyCursor = this.history.length - 1;
this.history[this.historyCursor] = statement.value;
}
// should we submit?
if (event.keyCode == 13 /* enter */ && !event.altKey && !event.shiftKey) {
return this.runStatement();
}
};