【发布时间】:2015-11-13 00:05:34
【问题描述】:
我记得在 Python 3.5 文档中阅读过如何在 Python 交互式提示上更改 >>>,例如调用 help() 将如何将其更改为 help>。
但由于某种原因,当我回去尝试记忆时,我就是找不到它的说明。有谁知道这是否可能?
【问题讨论】:
标签: python python-3.x command-line command-line-interface
我记得在 Python 3.5 文档中阅读过如何在 Python 交互式提示上更改 >>>,例如调用 help() 将如何将其更改为 help>。
但由于某种原因,当我回去尝试记忆时,我就是找不到它的说明。有谁知道这是否可能?
【问题讨论】:
标签: python python-3.x command-line command-line-interface
你没记错。
在sys 模块(sys.ps1 & sys.ps2)中:
指定解释器的主要和次要提示的字符串。这些仅在解释器处于交互模式时才定义。在这种情况下,它们的初始值为 '>>> ' 和 '... '。如果将非字符串对象分配给任一变量,则每次解释器准备读取新的交互式命令时,都会重新评估其 str() ;这可以用来实现动态提示。
例如:
>>> 导入系统 >>> sys.ps1 = "3.5>>> " 3.5>>> sys.ps2 = "3.5..." 3.5>>>【讨论】:
最好将其设置为:
将其粘贴到您的 Bash 外壳中:
tee ~/.pyrc <<EOF
#!/usr/bin/env python3
import sys
# You also need \x01 and \x02 to separate escape sequence, due to:
# https://stackoverflow.com/a/9468954/1147688
sys.ps1='\x01\x1b[1;49;33m\x02>>>\x01\x1b[0m\x02 ' # bright yellow
sys.ps2='\x01\x1b[1;49;31m\x02...\x01\x1b[0m\x02 ' # bright red
EOF
最后将此行添加到您的~/.bash_profile:
export PYTHONSTARTUP=~/.pyrc
如果您使用的是 Windows,请使用以下其中一种:
# Set it Temperarily (for this session)
$env:PYTHONSTARTUP="C:\Users\<USERNAME>\.pyrc"
# Set it Locally: HKEY_CURRENT_USER
[Environment]::SetEnvironmentVariable("PYTHONSTARTUP", 'C:\Users\<USERNAME>\.pyrc', 'User')
# Set it Globaly: HKEY_LOCAL_MACHINE
[Environment]::SetEnvironmentVariable("PYTHONSTARTUP", 'C:\Users\<USERNAME>\.pyrc', 'Machine')
# Set it Globaly: HKEY_LOCAL_MACHINE (also in CMD)
setx /m PYTHONSTARTUP "%HOME%\.pyrc"
享受吧!
【讨论】:
colorama 包)。另请注意,不需要使~/.pyrc 可执行,因为您不会直接从终端执行它。
TRUECOLOR 支持的终端,AFAICR。也尝试使用 ConEmu。
print 或以其他方式从我的代码写入标准输出时,Colorama 实际上对我来说在 Windows 上工作得很好。问题仅在于sys.ps1 ‒ 出于某种原因,即使我将sys.stdin 和sys.__stdin__ 都替换为AnsiToWin32 包装器,它也会将转义字符打印到终端。我认为 CPython 交互式解释器写入 ps1 的流以某种方式在启动时进行了硬编码或保存,而忽略了 sys.stdout 的后续更改。
RL_PROMPT_START_IGNORE (\x01) 和 RL_PROMPT_END_IGNORE (\x02) 特殊序列,由 使用readline,当它们包含转义序列时跟踪字符串长度。解决方案详情已找到here。
如果您使用的是 Windows (cmd.exe) 并且需要彩色提示,则可以使用 colorama,但有一些注意事项。如果你在你的PYTHONSTARTUP 中调用colorama.init 并分配给sys.ps1 一个包含着色转义码的字符串,它将不起作用。但是,当您使用包含着色转义码的字符串调用 print 时,彩色输出确实有效。
幸运的是,提出 sys.ps1 的 Python 人员非常慷慨(或聪明?),足以让您将任何对象用作 ps1,而不仅仅是字符串。然后使用其 __str__ 方法将分配的对象转换为字符串。这意味着您可以定义自己的类,例如。 Prompt,并在其 __str__ 方法中执行任何操作,包括写入 colorama-wrapped 标准输出(这将起作用!)。然后你只需返回一个空字符串。
这个事实给你带来了一个很好的好处——你也可以使用非常量提示。你想在你的 Python shell 中像在 bash 中一样有一个日期吗?没问题。
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()
虽然这工作得很好,但这是一种相当老套的方法,因为__str__ 方法的预期目的是返回一个str 实例。因此,当您对sys.ps2 执行相同操作时,它会中断。 Python 解释器希望 __str__ 方法没有副作用,并且在打印 PS1 时显然会同时评估 str(sys.ps1) 和 str(sys.ps2),而在打印 PS2 时使用已经评估(并保存)的值 str(sys.ps2)。结果是,如果你创建一个类似于上面的PS1 的PS2 类,当你应该只看到 PS1 时,你会看到 PS1 和 PS2,而当你应该看到时你什么也看不到见 PS2。另一种效果不佳的情况是当多个线程/进程正在写入控制台时。然后来自多个线程的输出被交错,虽然这也可能发生在普通 PS1 上,但这种 hack 使情况变得更糟。
在这个简单的例子中,它并没有那么糟糕(没有交错,只有混乱的颜色),但如果你“正确”地把握时机,情况可能会更糟。
【讨论】:
colorama.init(autoreset=True),所以不需要禁用颜色。正如您在屏幕截图中看到的,我在终端中写入的文本(例如from threading import Thread)是白色的,这是我的正常文本颜色。启动线程写入的文本test 也是白色的。问题是右括号之前的提示部分,即 not 应该是白色的,是白色的。所以问题实际上是颜色没有启用,而不是禁用。
NORMAL 或 RESET_ALL。由于您使用的是线程,因此您可能需要更早地和其他地方定义这些(例如brace_c 等)项目。为什么在不再使用它们时还要定义它们?