【发布时间】:2009-07-27 08:06:00
【问题描述】:
我经常使用 python 解释器进行快速数值计算,并希望使用指数符号等自动打印所有数值结果。有没有办法为整个会话设置这个?
例如,我想要:
>>> 1.e12
1.0e+12
不是:
>>> 1.e12
1000000000000.0
【问题讨论】:
我经常使用 python 解释器进行快速数值计算,并希望使用指数符号等自动打印所有数值结果。有没有办法为整个会话设置这个?
例如,我想要:
>>> 1.e12
1.0e+12
不是:
>>> 1.e12
1000000000000.0
【问题讨论】:
创建一个 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 网站或搜索有关如何使用它的更多详细信息)。
【讨论】:
很抱歉发布了 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".
嗯...这不是一个 100% 的解决方案,但我想到了这个...
如何定义一个 float 的子类,它有一个被覆盖的 __str__ 方法(使用 exp 表示法打印)。然后你必须用这个类的对象构造来包装所有表达式)。
它会比 Dave 的解决方案短一点,你可以定义一次类,然后编写如下内容:
>>> F(1.e12)
1.0e+12
>>> F(3.)
3.0e+0
>>> F(1.+2.+3.+4.)
1.0e+1
...
【讨论】:
如您所知,您可以使用the % operator 或str.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
【讨论】:
以 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'
【讨论】:
使用 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)))
【讨论】: