问题
This is probably a silly question, and I'll probably end up deleting it once I figure it out, but I swear I recall reading, in the Python 3.5 docs, how to change the >>>
on the Python interactive prompt, such as how calling help()
will change it to help>
. But for some reason, when I've gone back to try and remember, I just can't find the instructions to it. Does anyone know if this is possible, or am I just imagining things?
Thanks
回答1:
You remember correctly.
It's in the sys module (sys.ps1 & sys.ps2):
Strings specifying the primary and secondary prompt of the interpreter. These are only defined if the interpreter is in interactive mode. Their initial values in this case are '>>> ' and '... '. If a non-string object is assigned to either variable, its str() is re-evaluated each time the interpreter prepares to read a new interactive command; this can be used to implement a dynamic prompt.
For example:
>>> import sys >>> sys.ps1 = "3.5>>> " 3.5>>> sys.ps2 = "3.5... " 3.5>>>
回答2:
It's great to set it to either:
- a color for better visual aspect
- a blank or space for easier copy/paste operations
Paste this into your bash shell:
tee ~/.pyrc <<EOF
#!/usr/bin/env python3
import sys
sys.ps1='\x1b[1;49;33m>>>\x1b[0m ' # bright yellow
sys.ps2='\x1b[1;49;31m...\x1b[0m ' # bright red
#sys.ps1='\x1b[33m>>>\x1b[0m ' # dark yellow
#sys.ps2='\x1b[31m...\x1b[0m ' # dark red
# For easy copy/paste of proper code, use a blank or space:
#sys.ps1=' '
#sys.ps2=' '
EOF
# Then do this:
chmod 755 ~/.pyrc
Finally add this line to your ~/.bash_profile
:
export PYTHONSTARTUP=~/.pyrc
Enjoy!
回答3:
If you're on Windows (cmd.exe
) and you want a colored prompt, you can use colorama
, but there are some caveats. If you call colorama.init
in your PYTHONSTARTUP
and assign to sys.ps1
a string containing coloring escape codes, it won't work. However, colored output does work when you call print
with a string containing coloring escape codes.
Luckily, the Python people who came up with sys.ps1
were generous (or smart?) enough to let you use any object as ps1
, not only strings. The assigned object is then converted to string using its __str__
method. This means you can define your own class, eg. Prompt
, and do anything in its __str__
method, including writing to the colorama-wrapped stdout (which will work!). Then you simply return an empty string.
This fact brings you a nice bonus ‒ you can also use a non-constant prompt. Do you want a date in your Python shell like you have in bash? No problem.
import sys
import datetime
import colorama
colorama.init(autoreset=True)
class Prompt:
def __str__(self):
print(self.prompt, end='')
return ''
class PS1(Prompt):
@property
def prompt(self):
return '{brace_c}[{time_c}{time}{brace_c}]{prompt_c}>>> '.format(
brace_c = colorama.Fore.BLACK + colorama.Style.BRIGHT,
# style is preserved, so the following are also bright:
prompt_c = colorama.Fore.LIGHTYELLOW_EX,
time_c = colorama.Fore.BLACK,
time = datetime.datetime.now().strftime('%H:%M'),
)
sys.ps1 = PS1()
Although this works just fine, it is a rather hacky way as the intended purpose of the __str__
method is to return a str
instance. Because of this, it breaks when you do the same thing with sys.ps2
. The Python interpreter expects the __str__
method to have no side effects, and apparently evaluates both str(sys.ps1)
and str(sys.ps2)
when printing PS1, whereas when printing PS2 the already-evaluated (and saved) value of str(sys.ps2)
is used. The result is that, if you create a PS2
class similar to the PS1
above, you will see both PS1 and PS2 when you should only see PS1, and you will see nothing when you should see PS2. Another case in which this does not work well is when multiple threads / processes are writing to the console. Then the output from several threads is interleaved, and while this can happen with normal PS1 as well, this hack makes it even worse.
EDIT: Screenshot
In this simple example it's not so bad (no interleaving, only messed up colors), but if you get the timing "right", it can be worse.
来源:https://stackoverflow.com/questions/33683744/change-python-interactive-prompt