这里有两个问题。
第一个比__future__
语句更通用:至少在我的测试中,ipython 1.0.0 及更早版本根本不处理PYTHONSTARTUP
环境变量。你可以很容易地看到这一点:
$ echo -e 'print "PYTHONSTARTUP!"\n' > pythonstartup.py
$ PYTHONSTARTUP=./pythonstartup.py ipython
没有额外的东西被打印出来。
#2706建议它应该这样做,#3569对其进行了修补,并且 1.1.0 似乎是第一个更改的版本。
因此,修复是升级到 1.1.0。或者,如果您坚持使用旧版本,请执行 #2706 中的建议,并将其添加到您的第一个$IPYTHONDIR/profile_default/startup/*py
文件中:
import os
if os.environ['PYTHONSTARTUP']:
execfile(os.environ['PYTHONSTARTUP'])
但是,这仍然不能解决问题。
运行方式$PYTHONSTARTUP
(由您显式运行或由 iPython 隐式运行)等效于exec
. 它确实明确地为 提供了适当globals
的exec
,这确保您最终得到print_function
可用的元组……但这不会影响解析器。(比较在交互式 shell 中键入exec('from __future__ import print_function
)`。)
对于上述启动文件、向后兼容ipython.rc
文件(如果您启用了该文件)以及任何其他应该在您的交互式环境中执行的文件也是如此——它们实际上只是exec
在您的globals
,这不是一回事。
甚至exec_files
在您的ipython_config.py
或其他 app-config 脚本中作为机制的一部分执行的文件也会以这种方式处理。
但是,作为exec_lines
机制的一部分执行的行不是。所以,这就是解决方案。
编辑或创建~/.ipython/profile_default/ipython_config.py
. (如果您使用不同的配置文件、ipythondir、应用程序名称等,您大概知道,并且知道如何调整。)
如果它不存在,请添加以下行:
c = get_config()
然后添加这个:
c.InteractiveShellApp.exec_lines = ['from __future__ import print_function']
有关更多详细信息,请参阅配置 ipython 命令行应用程序。
如果你真的想,你可能会做这样的事情:
import os
try:
# Make sure to pop it so it won't get exec'd later in the startup
pythonstartup = os.environ.pop('PYTHONSTARTUP')
with open(pythonstartup) as f:
c.InteractiveShellApp.exec_lines.append(list(f))
except KeyError:
pass
但这似乎很hacky。