【问题标题】:How do I control number formatting in the python interpreter?如何在 python 解释器中控制数字格式?
【发布时间】:2009-07-27 08:06:00
【问题描述】:

我经常使用 python 解释器进行快速数值计算,并希望使用指数符号等自动打印所有数值结果。有没有办法为整个会话设置这个?

例如,我想要:

>>> 1.e12
1.0e+12

不是:

>>> 1.e12
1000000000000.0

【问题讨论】:

    标签: python ipython


    【解决方案1】:

    创建一个 Python 脚本,可以任意命名(比如 mystartup.py),然后将环境变量 PYTHONSTARTUP 设置为该脚本的路径。然后,Python 将在交互式会话启动时加载此脚本(但在运行脚本时不会)。在这个脚本中,定义一个类似这样的函数:

    def _(v):
        if type(v) == type(0.0):
            print "%e" % v
        else:
            print v
    

    然后,在交互式会话中:

    C:\temp>设置 PYTHONSTARTUP=mystartup.py C:\临时>蟒蛇 ActivePython 2.5.2.2 (ActiveState Software Inc.) 基于 Python 2.5.2 (r252:60911, Mar 27 2008, 17:57:18) [MSC v.1310 32 位 (Intel)] 开启 win32 输入“帮助”、“版权”、“信用”或“许可”以获取更多信息。 >>> _(1e12) 1.000000e+012 >>> _(14) 14 >>> _(14.0) 1.400000e+001 >>>

    当然,您可以根据需要定义要调用的函数,并按照您的需要完全工作。

    比这更好的是使用IPython。太好了,您可以使用 result_display.when_type(some_type)(my_print_func) 设置您想要的数字格式(请参阅 IPython 网站或搜索有关如何使用它的更多详细信息)。

    【讨论】:

      【解决方案2】:

      很抱歉发布了 necroposting,但这个主题出现在相关的谷歌搜索中,我相信这里缺少令人满意的答案。

      我相信正确的方法是使用sys.displayhook。例如,您可以在 PYTHONSTARTUP 文件中添加如下代码:

      import builtins
      import sys
      import numbers
      
      
      __orig_hook = sys.displayhook
      
      def __displayhook(value):
          if isinstance(value, numbers.Number) and value >= 1e5:
              builtins._ = value
              print("{:e}".format(value))
          else:
              __orig_hook(value)
      
      sys.displayhook = __displayhook
      

      这将使用 exp 语法显示足够大的值。随意修改您认为合适的阈值。

      或者,您可以以两种格式打印大数的答案:

      def __displayhook(value):
          __orig_hook(value)
          if isinstance(value, numbers.Number) and value >= 1e5:
              print("{:e}".format(value))
      

      或者你可以给自己定义一个除了默认的_之外的另一个答案变量,比如__(这样的创意,我知道):

      builtins.__ = None
      __orig_hook = sys.displayhook
      
      def __displayhook(value):
          if isinstance(value, numbers.Number):
              builtins.__ = "{:e}".format(value)
          __orig_hook(value)
      
      sys.displayhook = __displayhook
      

      ...然后只需键入 __ 即可显示 exp 格式的答案。

      【讨论】:

      • 这正是我想要的。这可以很容易地应用于很多事情。你想要一个二进制表示来轻松按位有趣吗?试试"{:b}"!十六进制? "{:x}" 想要点颜色? "\033[91m {:e}\033[00m".
      【解决方案3】:

      嗯...这不是一个 100% 的解决方案,但我想到了这个...

      如何定义一个 float 的子类,它有一个被覆盖的 __str__ 方法(使用 exp 表示法打印)。然后你必须用这个类的对象构造来包装所有表达式)。 它会比 Dave 的解决方案短一点,你可以定义一次类,然后编写如下内容:

      >>> F(1.e12)
      1.0e+12
      >>> F(3.)
      3.0e+0
      >>> F(1.+2.+3.+4.)
      1.0e+1
      ...
      

      【讨论】:

        【解决方案4】:

        如您所知,您可以使用the % operatorstr.format 来格式化字符串:

        例如:

        >>> "%e" % 1.e12
        '1.000000e+12'
        

        我想知道你是否可以 monkey patch 内置的 float 类来更改格式,但似乎 Python 不会让你:

        >>> 1.e12.__class__.__repr__ = lambda x: "%e" % x
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        TypeError: can't set attributes of built-in/extension type 'float'
        

        所以我唯一能想到的另一件事是编写您自己的类似文件的对象,该对象捕获输出、重新格式化并将其发送到标准输出。然后将解释器的标准输出重定向到这个对象:

        sys.stdout = my_formatting_object
        

        【讨论】:

        • 是的,但我不想在每次输入时都输入这个。由于我希望整个会话使用相同的格式,因此我想设置一次,不再打扰它。
        • 哎呀。抱歉,没有正确阅读您的问题。已尽我所能扩展答案以正确涵盖您的问题。
        【解决方案5】:

        以 Dave Webb 的上述提示为基础。您当然可以根据需要设置精度 ("%.3e") 并在需要时覆盖写入行。

        import os
        import sys
        
        class ExpFloatFileObject:
            def write(self, s):
                try:
                    s = "%e"%float(s)
                except ValueError:
                    pass
                sys.__stdout__.write(s)
        
            def __getattr__(self, name):
                return getattr(sys.__stdout__, name)
        
        sys.stdout = ExpFloatFileObject()  
        

        及用法:

        >>> 14000    
        1.400000e+04  
        >>> "text"
        'text'
        

        【讨论】:

          【解决方案6】:

          使用 IPython/Jupyter-console 时,“魔术”命令 %precision %e 将更改以指数表示法显示的原始浮点数。 https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-precision

          更多的格式化控制,可以注册一个格式化程序:

          excited_floats = lambda val: "{:e}!!!".format(val)
          console_formatter = get_ipython().display_formatter.formatters['text/plain']
          console_formatter.for_type(float, lambda val, p, c: p.text(excited_floats(val)))
          

          https://ipython.readthedocs.io/en/stable/api/generated/IPython.core.formatters.html#IPython.core.formatters.PlainTextFormatter

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-08-23
            • 2010-10-05
            • 1970-01-01
            • 2014-03-10
            • 1970-01-01
            • 2021-10-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多