【问题标题】:Change Python interactive prompt ">>>"更改 Python 交互提示 >>>"
【发布时间】:2015-11-13 00:05:34
【问题描述】:

我记得在 Python 3.5 文档中阅读过如何在 Python 交互式提示上更改 >>>,例如调用 help() 将如何将其更改为 help>。

但由于某种原因,当我回去尝试记忆时,我就是找不到它的说明。有谁知道这是否可能?

【问题讨论】:

    标签: python python-3.x command-line command-line-interface


    【解决方案1】:

    你没记错。

    在sys 模块(sys.ps1 & sys.ps2)中:

    指定解释器的主要和次要提示的字符串。这些仅在解释器处于交互模式时才定义。在这种情况下,它们的初始值为 '>>> ' 和 '... '。如果将非字符串对象分配给任一变量,则每次解释器准备读取新的交互式命令时,都会重新评估其 str() ;这可以用来实现动态提示。

    例如:

    >>> 导入系统 >>> sys.ps1 = "3.5>>> " 3.5>>> sys.ps2 = "3.5..." 3.5>>>

    【讨论】:

    • 完美!谢谢你。我不记得我在哪里读到的了,但我很高兴我没有疯。
    • 也适用于 Python 2.7.12。
    • 在空闲时对我不起作用,无论是 3.5.0 还是 2.7.10。但它确实在 Windows 控制台中工作。
    • @MarkRansom:我从未考虑过空闲。不过,它确实适用于 linux 和 windows 控制台。
    • 随机很酷的想法:定义 sys.ps1="" 和 sys.ps2="" 以便可以轻松地将粘贴输出从终端复制到编辑器,而无需 >>> 和 ...
    【解决方案2】:

    最好将其设置为:

    1. 颜色以获得更好的视觉效果
    2. 空白或空格,便于复制/粘贴操作

    将其粘贴到您的 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"                                                        
    

    享受吧!

    【讨论】:

    • 遗憾的是,这在 Windows 上不起作用(使用 colorama 包)。另请注意,不需要使~/.pyrc 可执行,因为您不会直接从终端执行它。
    • YMMV 因为 Windows 在支持 ANSI 颜色代码方面很糟糕。因此,这取决于控制台、您的 powershell 版本、您的 Windows 版本以及哪个 python 版本(本机 Windows、Cygwin、WSL)非常具体的事情。也就是说,对我来说,colorama 在不同的 Python 版本中从未像预期的那样工作。因此,只需尝试您自己的 ANSI 代码。以上是TRUECOLOR 支持的终端,AFAICR。也尝试使用 ConEmu。
    • 当我使用 print 或以其他方式从我的代码写入标准输出时,Colorama 实际上对我来说在 Windows 上工作得很好。问题仅在于sys.ps1 ‒ 出于某种原因,即使我将sys.stdin 和sys.__stdin__ 都替换为AnsiToWin32 包装器,它也会将转义字符打印到终端。我认为 CPython 交互式解释器写入 ps1 的流以某种方式在启动时进行了硬编码或保存,而忽略了 sys.stdout 的后续更改。
    • 由于 windows 下的转义序列问题,我已更新答案以包含正确的 RL_PROMPT_START_IGNORE (\x01) 和 RL_PROMPT_END_IGNORE (\x02) 特殊序列,由 使用readline,当它们包含转义序列时跟踪字符串长度。解决方案详情已找到here。
    【解决方案3】:

    如果您使用的是 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 使情况变得更糟。

    编辑:截图

    在这个简单的例子中,它并没有那么糟糕(没有交错,只有混乱的颜色),但如果你“正确”地把握时机,情况可能会更糟。

    【讨论】:

    • 不错的一个!但请添加屏幕截图,以便我们更好地了解它的外观。 interleave 的问题可能是缓冲问题。 Python 解释器喜欢缓冲输出,因此您应该确保打印的任何内容都没有缓冲。
    • 从图片上看你激活的颜色在使用后并没有被禁用。确保您还提供 ANSI 序列以在选择并打印颜色后禁用颜色。
    • 我不确定你的意思。我使用colorama.init(autoreset=True),所以不需要禁用颜色。正如您在屏幕截图中看到的,我在终端中写入的文本(例如from threading import Thread)是白色的,这是我的正常文本颜色。启动线程写入的文本test 也是白色的。问题是右括号之前的提示部分,即 not 应该是白色的,是白色的。所以问题实际上是颜色没有启用,而不是禁用。
    • 我的意思是您可能需要将 style 重新设置为 NORMAL 或 RESET_ALL。由于您使用的是线程,因此您可能需要更早地和其他地方定义这些(例如brace_c 等)项目。为什么在不再使用它们时还要定义它们?
    • 另外,请添加如何实现上述脚本的描述。放在哪里,怎么执行的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    相关资源
    最近更新 更多