如何在python解释器中控制数字格式?

时间:2009-07-27 08:06:00

标签: python ipython

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

例如,我想:

>>> 1.e12
1.0e+12

>>> 1.e12
1000000000000.0

6 个答案:

答案 0 :(得分:4)

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

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

然后,在交互式会话中:

C:\temp>set PYTHONSTARTUP=mystartup.py

C:\temp>python
ActivePython 2.5.2.2 (ActiveState Software Inc.) based on
Python 2.5.2 (r252:60911, Mar 27 2008, 17:57:18) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> _(1e12)
1.000000e+012
>>> _(14)
14
>>> _(14.0)
1.400000e+001
>>>

当然,您可以将要调用的函数定义为您想要的whaetver,并且可以根据需要正确地工作。

比使用IPython更好。这很棒,您可以使用result_display.when_type(some_type)(my_print_func)设置数字格式(请参阅IPython网站或搜索有关如何使用此内容的更多详细信息)。

答案 1 :(得分:1)

如您所知,您可以使用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

答案 2 :(得分:1)

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

如何定义一个浮点的子类,它将具有重写的__str__方法(使用exp表示法打印)。然后你必须用这个类的对象构造包装所有表达式)。 它会比Dave的解决方案短一些,你可以定义一次类,然后编写类似的东西:

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

答案 3 :(得分:1)

基于Dave Webb的上述提示。您当然可以根据需要设置精度(“%。3e”),如果需要也可以覆盖writelines。

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'

答案 4 :(得分:0)

在使用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

答案 5 :(得分:0)

很抱歉,您可能无法进行尸检,但是这个话题出现在相关的google搜索中,我相信这里缺少令人满意的答案。

我相信正确的方法是使用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格式显示的答案。