Colored Python Prompt in Windows?

☆樱花仙子☆ 提交于 2020-01-06 08:37:28

问题


Here's my script that currently sets up my prompts for all of my computers (whether they're Windows, Red Hat, or 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

On all systems this prints out the current time followed by the normal ">>>" prompt on the first line, and then if I have a multiline input it has the normal "..." prompt, but indented so that it aligns with the ">>>" prompt (remember that that prompt is prefixed by the current time).

Here's the question though: On every platform besides Windows, the current time prints in teal (and underlined), the prompts are in green, and whatever I type shows up in a normal color. How can I achieve this same thing in Windows? I've seen a few solutions suggested, but they rely on calling functions while the message is printing, which I don't think would work for me on account of the fact that the ps variables just call __repr__ on whatever is assigned to them, right?

(By the way, I got this time trick from here: python: display elapsed time on shell)


回答1:


On my machine (Windows 7) Python runs in the command prompt 'terminal' when executed and as far as I'm aware you can only change the colour for all text inside that terminal, as in all the text will be the same colour.

I recall someone talking about a library called 'clint' that should support MAC, Linux and Windows terminals. It would mean adding a bit extra to your existing script though.




回答2:


It occurred to me that there's no particular reason to limit myself to only finding the current time in my PS1 class, and in fact, why return the current time as the __repr__ when instead I could just print the time and prompt as a side-effect of the __repr__ function and instead return an empty string?

So I added the following code (with proper platform checks mixed in - I'm leaving those out just so I can show the meat and potatoes of making this work on 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 ""

So now I get the clock in teal and the prompt in green - I'd like to emphasis that THIS MUCH WORKED!

I tried to do a similar thing with 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 ""

THIS DID NOT WORK! When I tried doing this, I found that the interpreter would instantly print out PS1 and PS2 back to back and then not display PS2 on subsequent lines. It would seem that it normally gets all of the PS# __repr__s at the very start and stores the results to display later. But since this method relies on side effects, it's exposed as the hack that it is.

So for now I'm sticking with just a normal " ... " for sys.ps2.

I'd love to hear suggestions for making those ...'s in green (without also making anything I type green) but I suspect that it may not be possible. I'll be happy to accept any answer which proves me wrong - if none arrives within 2 days I'll probably just accept this one until someone else comes up with something better.



来源:https://stackoverflow.com/questions/23955991/colored-python-prompt-in-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!