问题
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