3

我想拥有

from __future__ import (absolute_import, division, print_function, unicode_literals)

在每个交互式会话中加载,使用PYTHONSTARTUP文件。这适用于基本 python(2.7.5,随 Anaconda 一起安装),但不适用于 ipython(1.0.0,Anaconda)。其他import语句与 ipython 一起使用,但__future__只是忽略了一些语句(尽管如果我在命令行上输入它们它们会起作用)。这是一个 ipython 错误,还是我遗漏了什么?

4

1 回答 1

8

这里有两个问题。


第一个比__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. 它确实明确地为 提供了适当globalsexec,这确保您最终得到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。

于 2013-10-08T23:19:00.833 回答