16

规格:Python 2.7

我正在开发一个包含多个模块的项目,我想在所有模块中激活 __future__ 模块中的一些功能。我想在一个模块上导入我需要的所有功能,然后将该单个模块导入到其他模块中,并让这些功能在所有模块中都处于活动状态,或者类似的效果。

我试过了:

[A.py]

from __future__ import division

[B.py]

import A
print(1/2)

运行 B.py 的除法仍然是整数。我试过了:

[A.py]

print(1/2)

[B.py]

from __future__ import division
import A

运行 B.py 给出了相同的结果。对于前面的两个示例,我还尝试通过“from A import *”切换“import A”,结果相同。

我在 Google 上搜索了一段时间,并在 Python 文档中找到了关于 __future__ 模块如何工作的最佳描述,显然足够了。在那里,我只能找到这些功能在它们被导入的模块中处于活动状态的保证,而没有提及如何在全局范围内进行操作。

所以我想知道是否有办法做到这一点,无论是我描述的方式,还是创建某种运行时配置文件,或者通过其他方式。

4

2 回答 2

15

没有办法用语言做到这一点。从这个意义上说,你真的不能让__future__进口全球化。(好吧,您可能可以import用一些复杂的东西imp或其他东西替换正常的语句。请参阅Future 语句文档并向下滚动到“代码编译...”但是这样的任何事情几乎肯定是个坏主意。)

原因是这from __future__ import division不是真正的正常导入。或者,更确切地说,它不仅仅是一个正常的导入。实际上,您确实获得了一个division可以检查的名称,但是仅具有该值没有任何效果-因此将其传递给其他模块不会影响这些模块。除了正常的导入之外,Python 还具有特殊的魔力,可以检测__future__模块顶部或交互式解释器中的导入,并更改代码的编译方式。如果您想了解所有详细信息,请参阅“真正导入”部分的未来和魔术”部分的未来声明

并且没有配置文件可以让您执行此操作。但是有一个命令行参数:

python -Qnew main.py

这与在任何地方执行相同的效果from __future__ import division

您可以将其添加到#!行中,或者alias pyfuturediv='python -Qnew'(甚至alias python='python -Qnew')添加到您的 shell 中,或者其他任何内容,这可能与您的目的的配置文件一样好。

但实际上,如果您想确保模块 B 获得新式划分,您可能应该__future__首先在 B 中声明。

或者,当然,您可以只为 Python 3.0+ 而不是 2.3-2.7 编写代码。(请注意,一些核心开发人员反对使用命令行参数,因为“全局获取功能 X 的正确方法是使用 Python >= 功能 X 的 MandatoryRelease 的版本”。)或者//在你的意思是使用//.

另一种可能性是使用6,该模块旨在让您编写几乎是 Python 3.3 的代码并使其在 2.4-2.7(和 3.0-3.2)中正常工作。例如,你没有得到一个print函数,但你得到了一个print_工作完全相同的函数。你没有得到 Unicode 文字,但你得到u()了假文字——再加上源代码中的 UTF-8 编码声明,几乎就足够了。它还提供了很多你无法从中获得的东西—— __future__<code>StringIO 和BytesIO作为exec函数的next函数等等。

如果问题是您有 1000 个源文件,并且全部编辑它们很痛苦,您可以使用sed,或3to2仅使用修复除法的选项,或者......</p>

于 2012-12-08T02:38:43.543 回答
3

另一种方法是使用isortisort有一个-a命令行标志来将导入添加到您指定的文件中。简单地isort不带参数运行将在当前工作目录和所有子目录中的所有 python 文件上递归运行它。

如果像我一样,您在该文件夹中有一个虚拟环境,并且正在使用 git(或具有仅列出您的文件的等效方式)并且不想在该虚拟环境中的所有文件上运行它,您可以使用一些东西喜欢:

git ls-tree -r HEAD --name-only | grep "\.py$" | xargs isort -a -y "from __future__ import division"

于 2016-09-15T17:32:24.177 回答