跳转到主要内容

终端着色、样式和定位的薄型实用包装

项目描述

使用祝福语编码看起来像这样...

from blessings import Terminal

t = Terminal()

print t.bold('Hi there!')
print t.bold_red_on_bright_green('It hurts my eyes!')

with t.location(0, t.height - 1):
    print 'This is at the bottom.'

或者,对于字节级别的控制,你可以降级并玩转原始终端功能

print '{t.bold}All your {t.red}bold and red base{t.normal}'.format(t=t)
print t.wingo(2)

完整API参考

卖点

Blessings消除了curses的一些限制性假设,并让你的代码更美观

  • 使用样式、颜色,可能还有一点定位,无需先清除整个屏幕。

  • 在程序退出后,在缓冲区中留下多于一个屏幕的滚动回显,就像一个表现良好的命令行应用应该那样。

  • 去除所有那些嘈杂的、类似C的tigetstrtparm调用,让你的代码不会被终端维护工作所占据。

  • 当有人将你的输出重定向到文件时,智能地处理,省略用户不想看到的终端控制代码(可选)。

前后对比

没有祝福,这就是如何在屏幕底部打印带下划线的文本的方法

from curses import tigetstr, setupterm, tparm
from fcntl import ioctl
from os import isatty
import struct
import sys
from termios import TIOCGWINSZ

# If we want to tolerate having our output piped to other commands or
# files without crashing, we need to do all this branching:
if hasattr(sys.stdout, 'fileno') and isatty(sys.stdout.fileno()):
    setupterm()
    sc = tigetstr('sc')
    cup = tigetstr('cup')
    rc = tigetstr('rc')
    underline = tigetstr('smul')
    normal = tigetstr('sgr0')
else:
    sc = cup = rc = underline = normal = ''
print sc  # Save cursor position.
if cup:
    # tigetnum('lines') doesn't always update promptly, hence this:
    height = struct.unpack('hhhh', ioctl(0, TIOCGWINSZ, '\000' * 8))[0]
    print tparm(cup, height - 1, 0)  # Move cursor to bottom.
print 'This is {under}underlined{normal}!'.format(under=underline,
                                                  normal=normal)
print rc  # Restore cursor position.

这太长了,充满了难以理解的东西!让我们再试一次,这次加上祝福

from blessings import Terminal

term = Terminal()
with term.location(0, term.height - 1):
    print 'This is', term.underline('pretty!')

好多了。

它提供了什么

祝福提供了一个顶级对象:Terminal。实例化一个Terminal会检查你是否真的在终端中,如果是的话,就会进行必要的终端设置。之后,你可以继续询问有关终端的各种问题。终端,终端,终端。

简单的格式化

许多方便的格式化代码(在底层术语中称为“功能”)可以作为Terminal上的属性使用。例如

from blessings import Terminal

term = Terminal()
print 'I am ' + term.bold + 'bold' + term.normal + '!'

虽然它们本质上都是字符串,但你也可以将它们用作可调用的包装器,这样你就不必在后面说normal

print 'I am', term.bold('bold') + '!'

或者,如果你想保持简短的同时又想有细粒度的控制,你可以将它与Python的字符串格式化结合使用,这使得属性很容易访问

print 'All your {t.red}base {t.underline}are belong to us{t.normal}'.format(t=term)

一些简单的有用功能包括...

  • 粗体

  • 反白

  • 下划线

  • no_underline(用于关闭下划线)

  • 闪烁

  • normal(用于关闭一切,包括颜色)

以下是一些不太可能在所有终端上工作的功能

  • 暗淡

  • italicno_italic

  • shadowno_shadow

  • standoutno_standout

  • subscriptno_subscript

  • superscriptno_superscript

  • flash(屏幕闪烁一次)

请注意,虽然下划线的反义词是no_underline,但关闭boldreverse的唯一方法是normal,这也会取消任何自定义颜色。这是因为没有通用的方法告诉终端撤销某些格式化,即使在最低级别也是如此。

你可能还会注意到,上面列出的并不是典型的难以理解的terminfo功能名称;我们对一些难以记住的名称进行了别名设置,以增强可读性。然而,你并不局限于这些:你可以通过“Cap-name”列下的名称引用terminfo手册页上列出的任何返回字符串的功能:例如,term.rum

颜色

前缀和背景色均可作为易于记忆的属性使用16种颜色

from blessings import Terminal

term = Terminal()
print term.red + term.on_green + 'Red on green? Ick!' + term.normal
print term.bright_red + term.on_bright_blue + 'This is even worse!' + term.normal

你也可以将它们用作包装器,这将在结束时将一切恢复到正常状态

print term.red_on_green('Red on green? Ick!')
print term.yellow('I can barely see it.')

可用的颜色是...

  • 黑色

  • 红色

  • 绿色

  • 黄色

  • 蓝色

  • 品红色

  • 青色

  • 白色

您可以通过在前面加上on_来设置背景色而不是前景色,例如on_blue。还有每种颜色的bright版本:例如,on_bright_blue

还有对颜色的数值接口,它接受0-15之间的整数

term.color(5) + 'Hello' + term.normal
term.on_color(3) + 'Hello' + term.normal

term.color(5)('Hello')
term.on_color(3)('Hello')

如果某些颜色不受支持(例如,如果只有正常颜色,没有明亮颜色),那么尝试使用它将在大多数终端上没有任何效果:前景色和背景色将保持不变。您可以通过检查number_of_colors来确定支持的颜色的数量。

复合格式化

如果您想一次进行大量的疯狂格式化,只需将它们全部组合在一起即可

from blessings import Terminal

term = Terminal()
print term.bold_underline_green_on_yellow + 'Woo' + term.normal

或者,您可以使用新创建的属性作为包装器,这会在之后隐式地将一切恢复到正常状态

print term.bold_underline_green_on_yellow('Woo')

这种复合表示法在您想允许用户自定义应用程序的格式时非常有用:只需让他们在命令行上传递一个格式说明符,例如“bold_green”,然后在您进行格式化时快速执行 getattr(term, that_option)('您的文本')

如果不提一下couleur,我将犯了一个错误,我可能就是从这里得到了所有这些组合的想法。

移动光标

当您想将光标移动到特定位置输出文本时,您有几个选择。

临时移动

通常,您需要快速移动到某个位置,打印一些内容,然后返回:例如,在屏幕底部更新进度条时。Terminal提供了一个上下文管理器来简洁地执行此操作

from blessings import Terminal

term = Terminal()
with term.location(0, term.height - 1):
    print 'Here is the bottom.'
print 'This is back where I came from.'

location()的参数是 x 和然后 y,但您也可以只传递其中一个,留下另一个不变。例如…

with term.location(y=10):
    print 'We changed just the row.'

如果您正在执行一系列 move 调用(见下文),并且之后想将光标返回到原始位置,则无需参数调用 location(),它将只执行位置恢复

with term.location():
    print term.move(1, 1) + 'Hi'
    print term.move(9, 9) + 'Mom'

请注意,由于 location() 使用终端内置的位置记忆机制,您无法有效地嵌套多个调用。在外部最外围使用 location(),并在内部使用更简单的像 move 这样的操作。

永久移动

如果您只想移动而不担心返回,可以这样做

from blessings import Terminal

term = Terminal()
print term.move(10, 1) + 'Hi, mom!'
move

将光标定位在其他位置。参数是y坐标,然后是x坐标。

move_x

将光标移动到指定的列。

move_y

将光标移动到指定的行。

这一切是如何工作的?这些都是更简单的终端功能,被包装起来以提供更友好的名称。它们接受参数的附加特点也得到了很好的处理:我们不是让您不断地挖掘 tparm(),我们只是将这些功能变成了可调用的字符串。如果您只是打印它们,您会得到原始的功能字符串,但如果您将参数传递给它们,就像它们是函数一样,它们将是完全参数化的。

因此,您也可以通过“Cap-name”列下的名称引用 terminfo 手册页 中列出的任何其他字符串返回功能。

单点移动

最后,还有一些无需参数的移动功能,可以将光标在各个方向上移动一个字符

  • move_left

  • move_right

  • move_up

  • move_down

例如…

print term.move_up + 'Howdy!'

高度和宽度

简单地获取终端的高度和宽度(以字符为单位)是很容易的

from blessings import Terminal

term = Terminal()
height = term.height
width = term.width

每次您请求它们时,它们都会被更新,因此它们可以从 SIGWINCH 处理程序中安全使用。

清除屏幕

Blessings 在一些屏幕清除功能上提供了语法糖

clear

清除整个屏幕。

clear_eol

清除到行尾。

clear_bol

向后清除到行首。

clear_eos

清除到屏幕末尾。

全屏模式

可能您已经看到过全屏程序,如编辑器,在退出时恢复终端的精确先前状态,包括启动时所在的命令行提示符。Curses基本上会强制您这样做,但Blessings使这成为可选的。如果您想进行状态恢复操作,请使用以下功能

enter_fullscreen

切换到允许全屏输出的终端模式。在输出任何内容之前打印此命令。

exit_fullscreen

切换回正常模式,恢复使用enter_fullscreen之前的精确状态。

使用exit_fullscreen将清除程序输出的任何痕迹,因此请将其保留在滚动回溯中不留下任何内容的情况。

还有一个您可以使用的上下文管理器作为快捷方式

from blessings import Terminal

term = Terminal()
with term.fullscreen():
    # Print some stuff.

除了简洁之外,另一个优点是,即使在with块中引发异常,它也会切换回正常模式。

管道达人

如果您的程序未连接到终端,例如它被管道传输到另一个命令或重定向到文件,所有在Terminal上的能力属性都将返回空字符串。您将得到一个没有格式化代码干扰的漂亮文件。

如果您想覆盖此行为(例如,如果您预计程序将通过less -r管道传输,该工具可以很好地处理终端转义)请将force_styling=True传递给Terminal构造函数。

无论如何,Terminal上有一个does_styling属性,您可以通过它查看您的功能是否会返回实际的、可工作的格式化代码。如果它是假的,您应该避免绘制进度条和其他装饰,只需坚持内容即可,因为您显然要进入管道。

from blessings import Terminal

term = Terminal()
if term.does_styling:
    with term.location(0, term.height - 1):
        print 'Progress: [=======>   ]'
print term.bold('Important stuff')

购物清单

终端交互中积累了数十年的遗留问题,因此在边缘情况下的注意细节和行为很重要。以下是Blessings如何支持您的几种方式

  • 使用terminfo数据库,因此它可以与任何终端类型一起使用

  • 提供最新的终端高度和宽度,以便您可以响应终端尺寸变化(SIGWINCH信号)。(大多数其他库查询COLUMNSLINES环境变量或colslines终端能力,这些并不总是及时更新,有时甚至不更新。)

  • 避免将输出管道传输到非终端时的混乱

  • 与标准的Python字符串模板配合使用效果很好

  • 提供方便的访问所有终端能力,而不仅仅是简化后的几个

  • 输出到任何文件对象,而不仅仅是stdout

  • 保持最小的内部状态,因此您可以自由地与curses或您喜欢的其他终端库的调用进行混合匹配

Blessings不提供...

  • Windows命令提示符上的本地颜色支持。然而,当与colorama一起使用时,它应该可以工作。

错误

有错误或建议?请访问问题跟踪器

Blessings的测试由Travis CI自动运行。

https://travis-ci.org/erikrose/blessings.svg?branch=master

许可证

Blessings采用MIT许可证。请参阅LICENSE文件。

版本历史

1.7
  • 取消对Python 2.6和3.3的支持,它们已达到生命周期的终点。

  • 从2to3切换到six库。

1.6.1
  • 当在非终端或does_styling不正确时调用number_of_colors()时,不要崩溃。

1.6
  • 添加 does_styling 属性。这考虑了 force_styling,并应替换大多数使用 is_a_tty 的场景。

  • is_a_tty 设为只读属性,类似于 does_styling。写入它从未做过任何有建设性的事情。

  • fullscreen()hidden_cursor() 添加到自动生成的文档中。

  • 回退到 LINESCOLUMNS 环境变量以查找高度和宽度。(jquast)

  • 支持使用字节 127-255 的转义序列的终端类型,如 kermit 和 avatar。(jquast)

1.5.1
  • 清理 fabfile,删除多余的 test 命令。

  • 添加 Travis 支持。

  • python setup.py test 在 2.6 上工作而不会出现虚假的错误。

  • 绕过 tox 配置文件中的解析错误。

  • 即使发生异常,也让上下文管理器清理自己。(Vitja Makarov)

  • 当没有 tty 时,不再因为参数化能力而导致崩溃。(Vitja Makarov)

1.5
  • enter_fullscreenexit_fullscreen 添加语法糖和文档。

  • 添加上下文管理器 fullscreen()hidden_cursor()

  • 现在可以通过传递 force_styling=None 来强制 Terminal 永不输出样式。

1.4
  • 为光标可见性和单空格移动能力添加语法糖。

  • 推荐使用 location() 习惯用语来恢复一系列手动移动后的光标位置。

  • 修复了一个在传递零值时 location() 不会执行任何操作的错误。

  • 允许使用 python setup.py test 运行测试。

1.3
  • 添加了 number_of_colors,它告诉您终端支持多少颜色。

  • 使 color(n)on_color(n) 可调用,可以包装字符串,就像命名颜色一样。同时,如果 ANSI setafsetab 不可用,它们都将回退到 setfsetb 功能(就像命名颜色一样)。

  • 允许 color 属性作为未参数化的字符串,而不仅仅是可调用的。

  • 在回退到 stdout 之前,heightwidth 会检查任何传入的流。(这很少影响实际行为;这更多是哲学上的。)

  • 使缓存更简单、更有效。

  • 消除了终端和格式化字符串之间的引用循环。

  • 更新文档以反映终端寻址(如 location())是以 0 为基数的。

1.2
  • 添加了对 Python 3 的支持!我们需要 3.2.3 或更高版本,因为 curses 库在那之前无法决定是接受 strs 还是 bytes(http://bugs.python.org/issue10570)。

  • 现在库输出的所有内容都是 unicode。这让我们能够在不弄乱代码的情况下支持 Python 3,并且 Python 2 应该继续工作,除非您在测试类型(并且做得很糟糕)。如果您因此遇到麻烦,请提交错误报告。

  • 改为使用 MIT 许可证以更好地实现世界霸权。

  • 添加了 Sphinx 文档。

1.1
  • 为颜色添加了有意义的属性名。

  • 引入了复合格式化。

  • 添加了风格和颜色的包装行为。

  • 允许您强制能力为非空,即使输出流不是终端。

  • 添加了 is_a_tty 属性,用于判断输出流是否是终端。

  • 简化了剩余的有趣字符串能力。

  • location() 仅在 x 或 y 坐标上操作。

1.0

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分发

blessings-1.7.tar.gz (28.2 kB 查看哈希值)

上传时间

构建分发

blessings-1.7-py3-none-any.whl (18.5 kB 查看哈希值)

上传时间 Python 3

blessings-1.7-py2-none-any.whl (26.6 kB 查看哈希值)

上传时间 Python 2

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面