I'm prototyping a Python app with the cmd module.
我正在使用cmd模块对Python应用程序进行原型设计。
Some messages to the user will be quite long and I'd like to paginate them. The first 10 (or a configurable number) lines of the message would appear, and pressing the SPACE bar would display the next page, until the end of the message.
给用户的一些消息会很长,我想对它们进行分页。将显示消息的前10行(或可配置数字)行,按空格键将显示下一页,直到消息结束。
I don't want to reinvent something here, is there a simple mean to implement this feature?
我不想在这里重新发明一些东西,有一个简单的意思来实现这个功能吗?
4 个解决方案
#1
The simple thing would just be to pipe your script through "less" or a similar command at runtime.
简单的事情就是在运行时通过“less”或类似命令来管理脚本。
Here's a simple method that does approximately what you want, though:
这是一个简单的方法,大致可以满足您的需求:
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
You could also look into using curses.
你也可以考虑使用curses。
#2
As Yoni said above the right way to do this is to provide a print method that pages automatically inside your running cmd instance. The constructor of Cmd takes stdin and stdout arguments. So simple provide an object that works like stdout and supports your paging print method.
正如Yoni所说,正确的方法是提供一种在运行的cmd实例中自动页面的打印方法。 Cmd的构造函数接受stdin和stdout参数。如此简单,提供一个像stdout一样工作的对象,并支持你的分页打印方法。
class PagingStdOut(object):
def write(self, buffer, lines_before_pause=40):
# do magic paging here...
#3
I had the same question. There is a pager built in to the pydoc module. I incorporated it thusly (which I find hackish and unsatisfying... I'm open to better ideas though).
我有同样的问题。 pydoc模块内置了一个寻呼机。我如此融入其中(我觉得这些都是黑客和不满意的......我虽然愿意接受更好的想法)。
I like the idea that it would autopage if there are more than x results and paging is on, which is possible to implement, but not done here.
我喜欢它的想法,如果有超过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")
#4
Paging subroutines can be found in the genutils.py file of IPython (see page
, or page_dumb
for a simpler one). The code is a little complicated, but that's probably unavoidable if you are trying to be portable to systems including Windows and the various kinds of terminal emulators.
分页子程序可以在IPython的genutils.py文件中找到(有关更简单的内容,请参阅page或page_dumb)。代码有点复杂,但如果你想要移植到包括Windows和各种终端仿真器在内的系统,这可能是不可避免的。
#1
The simple thing would just be to pipe your script through "less" or a similar command at runtime.
简单的事情就是在运行时通过“less”或类似命令来管理脚本。
Here's a simple method that does approximately what you want, though:
这是一个简单的方法,大致可以满足您的需求:
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
You could also look into using curses.
你也可以考虑使用curses。
#2
As Yoni said above the right way to do this is to provide a print method that pages automatically inside your running cmd instance. The constructor of Cmd takes stdin and stdout arguments. So simple provide an object that works like stdout and supports your paging print method.
正如Yoni所说,正确的方法是提供一种在运行的cmd实例中自动页面的打印方法。 Cmd的构造函数接受stdin和stdout参数。如此简单,提供一个像stdout一样工作的对象,并支持你的分页打印方法。
class PagingStdOut(object):
def write(self, buffer, lines_before_pause=40):
# do magic paging here...
#3
I had the same question. There is a pager built in to the pydoc module. I incorporated it thusly (which I find hackish and unsatisfying... I'm open to better ideas though).
我有同样的问题。 pydoc模块内置了一个寻呼机。我如此融入其中(我觉得这些都是黑客和不满意的......我虽然愿意接受更好的想法)。
I like the idea that it would autopage if there are more than x results and paging is on, which is possible to implement, but not done here.
我喜欢它的想法,如果有超过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")
#4
Paging subroutines can be found in the genutils.py file of IPython (see page
, or page_dumb
for a simpler one). The code is a little complicated, but that's probably unavoidable if you are trying to be portable to systems including Windows and the various kinds of terminal emulators.
分页子程序可以在IPython的genutils.py文件中找到(有关更简单的内容,请参阅page或page_dumb)。代码有点复杂,但如果你想要移植到包括Windows和各种终端仿真器在内的系统,这可能是不可避免的。