【发布时间】:2009-09-05 01:31:11
【问题描述】:
我正在使用 cmd 模块制作 Python 应用程序的原型。
给用户的一些消息会很长,我想给它们分页。 将显示消息的前 10 行(或可配置的数量),按空格键将显示下一页,直到消息结束。
我不想在这里重新发明一些东西,有没有简单的方法来实现这个功能?
【问题讨论】:
标签: python pagination cmd
我正在使用 cmd 模块制作 Python 应用程序的原型。
给用户的一些消息会很长,我想给它们分页。 将显示消息的前 10 行(或可配置的数量),按空格键将显示下一页,直到消息结束。
我不想在这里重新发明一些东西,有没有简单的方法来实现这个功能?
【问题讨论】:
标签: python pagination cmd
简单的事情就是在运行时通过“less”或类似的命令来管道你的脚本。
这里有一个简单的方法,可以大致完成您想要的操作:
def print_and_wait(some_long_message):
lines = some_long_message.split('\n')
i=0
while i < len(lines):
print '\n'.join(lines[i:i+10])
raw_input("press enter to read more...")
i += 10
你也可以考虑使用诅咒。
【讨论】:
正如 Yoni 上面所说的那样,正确的方法是提供一种打印方法,该方法可以在您正在运行的 cmd 实例中自动分页。 Cmd 的构造函数接受 stdin 和 stdout 参数。提供一个像标准输出一样工作并支持您的分页打印方法的对象。
class PagingStdOut(object):
def write(self, buffer, lines_before_pause=40):
# do magic paging here...
【讨论】:
我也有同样的问题。 pydoc module 内置了一个寻呼机。我就这样合并了它(我觉得这很老套而且不令人满意……不过我愿意接受更好的想法)。
我喜欢这样的想法,即如果有超过 x 个结果并且分页打开,它会自动分页,这是可以实现的,但在这里没有完成。
import cmd
from pydoc import pager
from cStringIO import StringIO
import sys
PAGER = True
class Commander(cmd.Cmd):
prompt = "> "
def do_pager(self,line):
global PAGER
line = line + " 1"
tokens = line.lower().split()
if tokens[0] in ("on","true","t", "1"):
PAGER = True
print "# setting PAGER True"
elif tokens[0] in ("off","false","f","0"):
PAGER = False
print "# setting PAGER False"
else:
print "# can't set pager: don't know -> %s" % tokens[0]
def do_demo(self,line):
results = dict(a=1,b=2,c=3)
self.format_commandline_results(results)
def format_commandline_results(self,results):
if PAGER:
ofh = StringIO()
else:
ofh = sys.stdout
for (k,v) in sorted(results.items()):
print >> ofh, "%s -> %s" % (k,v)
if PAGER:
ofh.seek(0)
pager(ofh.read())
return None
def do_EOF(self,line):
print "",
return True
if __name__ == "__main__":
Commander().cmdloop("# try: \n> pager off \n> demo \n> pager on \n> demo \n\n")
【讨论】:
分页子例程可以在IPython 的genutils.py 文件中找到(参见page 或page_dumb 以获得更简单的一个)。代码有点复杂,但如果你想移植到包括 Windows 和各种终端仿真器在内的系统上,这可能是不可避免的。
【讨论】: