【问题标题】:using 'from __future__' with ipython and PYTHONSTARTUP在 ipython 和 PYTHONSTARTUP 中使用“来自 __future__”
【发布时间】:2013-10-08 23:08:28
【问题描述】:

我想要

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 错误,还是我遗漏了什么?

【问题讨论】:

  • 这是PYTHONSTARTUP 文件中的第一行(非注释/文档字符串)吗?似乎不是 100% 清楚该文件中的代码是否应该遵循运行脚本或在交互式解释器中输入的规则,因此可以想象,python 可能遵循一条规则,而 ipython 遵循另一条规则……
  • 这是第一行,是的。如果你把它放在别处,它会抱怨。

标签: python python-2.7 ipython


【解决方案1】:

这里有两个问题。


第一个比__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'd 在您的 globals 中,这并不完全相同。

即使是作为exec_files 机制的一部分在您的ipython_config.py 或其他应用程序配置脚本中执行的文件也会以这种方式处理。

但是,作为exec_lines 机制的一部分执行的行不是。所以,这就是解决方案。


编辑或创建~/.ipython/profile_default/ipython_config.py。 (如果您使用不同的配置文件、ipythondir、应用程序名称等,您大概知道,并且知道如何调整。)

如果它不存在,添加这一行:

c = get_config()

然后添加这个:

c.InteractiveShellApp.exec_lines = ['from __future__ import print_function']

更多详情请见Configuring the ipython command line application


如果你真的想这样做,你可以这样做:

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

但这看起来很老套。

【讨论】:

  • 这不是真的。 ipython 1.0.0 在PYTHONSTARTUP 中处理import numpy as np 就好了。而且我刚刚升级到ipthon 1.1.0,它仍然不处理__future__ 语句。将您提供的代码放入 ipython 启动文件中没有任何作用(尽管我已经通过放入 print 行来验证它正在读取文件)。
  • @user2162806:我刚刚测试了我所有的版本——0.13.、1.0.0、1.1.0 和 2.0.dev; 0.13 和 1.0.0 不处理$PYTHONSTARTUP; 1.1.0 和 2.0.dev 可以。所以这绝对是个问题。 __future__ 语句可能存在其他问题,我将对此进行调查……
  • @user2162806:好的,你是对的,$PYTHONSTARTUP 中的 __future__ 声明发生得太晚了。事实上,即使在startup/000.py 中,__future__ 声明也为时已晚。我会用更多细节编辑答案,然后继续寻找……
  • 有趣。在 Anaconda 中分发的 iPython 1.0.0 确实读取了PYTHONSTARTUP(刚刚验证了这一点)。奇怪的是,可能相同的软件包的不同发行版是不同的……但感谢您对此进行调查。
  • PS,我对“太晚”位完全错了;它是关于 iPython 是否实际上将代码解释为用户键入的代码或使用 exec 样式的函数作为快捷方式,在我所知道的所有机制中,只有 exec_lines 是前者(即使你可能认为与名字……)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 2013-09-11
  • 2012-09-14
  • 2018-11-08
相关资源
最近更新 更多