【问题标题】:Colored Python Prompt in Windows?Windows 中的彩色 Python 提示符?
【发布时间】:2014-07-20 07:06:02
【问题描述】:

这是我目前为我的所有计算机(无论是 Windows、Red Hat 还是 OS X)设置提示的脚本:

import sys
import datetime
import platform

if platform.system() is 'Windows':
    tealUText   = ""
    tealText    = ""
    greenText   = ""
    defaultText = ""

else:
    tealUText   = "\001\033[4;36m\002"
    tealText    = "\001\033[0;36m\002"
    greenText   = "\001\033[0;32m\002"
    defaultText = "\001\033[0;0m\002"

class ClockPS1(object):
    def __repr__(self):
        now = datetime.datetime.now()
        clock = str(now.strftime("%H:%M:%S"))
        return tealUText + clock + greenText + " >>> " + defaultText

sys.ps1 = ClockPS1()
sys.ps2 = greenText + "         ... " + defaultText

在所有系统上,这会在第一行打印出当前时间,然后是正常的“>>>”提示,然后如果我有一个多行输入,它具有正常的“...”提示,但缩进以便它与“>>>”提示符对齐(请记住,该提示符以当前时间为前缀)。

但问题是:在除 Windows 之外的每个平台上,当前时间都以蓝绿色(并带下划线)打印,提示为绿色,而我输入的任何内容都以正常颜色显示。如何在 Windows 中实现同样的功能?我已经看到了一些建议的解决方案,但它们依赖于在消息打印时调用函数,我认为这对我不起作用,因为ps 变量只是调用__repr__分配给他们,对吧?

(顺便说一句,我从这里得到了这个时间技巧:python: display elapsed time on shell

【问题讨论】:

  • 不要硬编码颜色转义。使用像 termcolorcolorama 这样更便携的模块(colorama 的主页显示它可以在 Windows 上工作,尽管并非所有属性都受支持)。

标签: python windows-7 cmd command-prompt sys


【解决方案1】:

在我的机器(Windows 7)上,Python 在执行时在命令提示符“终端”中运行,据我所知,您只能更改该终端内所有文本的颜色,因为所有文本都是一样的颜色。

我记得有人在谈论一个名为“clint”的库,它应该支持 MAC、Linux 和 Windows 终端。不过,这意味着在您现有的脚本中添加一些额外的内容。

【讨论】:

  • 我非常愿意在我的脚本中添加更多内容。我只是希望在 Windows 上使用 Python 就像在我的其他系统上一样愉快。
【解决方案2】:

我突然想到,没有特别的理由将自己限制为仅在我的 PS1 类中查找当前时间,事实上,为什么将当前时间返回为 __repr__ 而我可以只打印时间并提示作为__repr__ 函数的副作用,而是返回一个空字符串?

所以我添加了以下代码(混合了适当的平台检查 - 我将这些排除在外,以便展示在 Windows 上进行这项工作的关键所在):

from ctypes import *
# ... Skipped a lot of code which is the same as before...
STD_OUTPUT_HANDLE_ID = c_ulong(0xfffffff5)
windll.Kernel32.GetStdHandle.restype = c_ulong
std_output_hdl = windll.Kernel32.GetStdHandle(STD_OUTPUT_HANDLE_ID)
textText    = 11
greenText   = 10
defaultText = 15
class PS1(object):
    def __repr__(self):
        # ... Skipping a lot of code which is the same as before ...
        windll.Kernel32.SetConsoleTextAttribute(std_output_hdl, tealText)
        sys.stdout.write(clock)
        windll.Kernel32.SetConsoleTextAttribute(std_output_hdl, greenText)
        sys.stdout.write(" >>> ")
        windll.Kernel32.SetConsoleTextAttribute(std_output_hdl, defaultText)
        return ""

所以现在我得到了蓝绿色的时钟和绿色的提示 - 我想强调 这很有效!

我尝试用 PS2 做类似的事情:

class PS2(object):
    def __repr__(self):
        windll.Kernel32.SetConsoleTextAttribute(std_output_hdl, greenText)
        sys.stdout.write("         ... ")
        windll.Kernel32.SetConsoleTextAttribute(std_output_hdl, defaultText)
        return ""

这不起作用!当我尝试这样做时,我发现解释器会立即背靠背打印出PS1PS2,然后不会在后续行中显示PS2 .看起来它通常在一开始就获取所有PS# __repr__s 并存储结果以供稍后显示。但由于这种方法依赖于副作用,因此它被暴露为 hack。

所以现在我坚持使用普通的" ... " 来代替sys.ps2

我很想听听有关将... 设为绿色的建议(也不要将我输入的任何内容设为绿色),但我怀疑这可能是不可能的。我很乐意接受任何证明我错了的答案 - 如果 2 天内没有答案,我可能会接受这个答案,直到其他人想出更好的答案。

【讨论】:

  • 我今天花了一些时间挖掘 Python 的源代码。它使用 C 函数将 sys.ps2 转换为 C 字符串并存储该 C 字符串,直到 PyOS_StdioReadline()(另一个 C 函数)使用它来向用户打印提示(使用 fprintf())。所以你不能在不修改解释器的源代码并重建它的情况下劫持它。工作太多,收益太少。
猜你喜欢
  • 2017-09-04
  • 1970-01-01
  • 2015-09-28
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 2011-03-03
  • 2021-05-28
  • 2019-10-12
相关资源
最近更新 更多