我们如何使 __future__ 进口全球化? [英] How can we make __future__ imports global?

查看:50
本文介绍了我们如何使 __future__ 进口全球化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

规格:Python 2.7

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

我试过了:

[A.py]

from __future__ 导入师

[B.py]

import A打印(1/2)

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

[A.py]

打印(1/2)

[B.py]

from __future__ 导入师进口A

运行 B.py 给出了相同的结果.在前面的两个示例中,我还尝试将import A"切换为from A import *",结果相同.

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

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

解决方案

没有办法在语言中做到这一点;从这个意义上说,你真的不能让 __future__ 导入全局.(好吧,你可能可以用一些复杂的 imp 或其他东西来替换普通的 import 语句.请参阅 Future statement 文档并向下滚动到代码编译器..."但是这样的事情几乎肯定是个坏主意.)

原因是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 获得新式划分,您可能应该首先在 B 中包含 __future__ 声明.

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

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

如果问题是你有 1000 个源文件,而且编辑它们很麻烦,你可以使用 sed,或者使用 3to2 只需要一个选项修正除法,或者……

Specs: Python 2.7

I'm working on a project that has several modules, I want to activate some features from the __future__ module in all of them. I would like to import all the features I need on one module, and then import that single module to every other, and have those features be active in all of them, or something to that effect.

I tried:

[A.py]

from __future__ import division

[B.py]

import A
print(1/2)

Running B.py the division was still integer. I tried:

[A.py]

print(1/2)

[B.py]

from __future__ import division
import A

Running B.py gave the same result. With both previous examples I also tried switching 'import A' by 'from A import *' with the same results.

I searched Google for a while, and found the best description about how the __future__ module works, obviously enough, on the Python documentation. There I could only find the assurance the features would be active in the module they were imported to, without any mention of how to do it globally.

So I'd like to know if there is a way of doing this, either the way I described, or creating some sort of runtime configuration file, or through some other means.

解决方案

There's no way to do this in-language; you really can't make __future__ imports global in this sense. (Well, you probably can replace the normal import statements with something complicated around imp or something. See the Future statement documentation and scroll down to "Code compiled by…" But anything like this is almost certainly a bad idea.)

The reason is that from __future__ import division isn't really a normal import. Or, rather, it's more than a normal import. You actually do get a name called division that you can inspect, but just having that value has no effect—so passing it to other modules doesn't affect those modules. On top of the normal import, Python has special magic that detects __future__ imports at the top of a module, or in the interactive interpreter, and changes the way your code is compiled. See future for the "real import" part, and Future statements for the "magic" part, if you want all the details.

And there's no configuration file that lets you do this. But there is a command-line parameter:

python -Qnew main.py

This has the same effect as doing a from __future__ import division everywhere.

You can add this to the #! lines, or alias pyfuturediv='python -Qnew' (or even alias python='python -Qnew') in your shell, or whatever, which maybe as good as a configuration file for your purposes.

But really, if you want to make sure module B gets new-style division, you probably should have the __future__ declaration in B in the first place.

Or, of course, you could just write for Python 3.0+ instead of 2.3-2.7. (Note that some of the core devs were against having command-line arguments, because "the right way to get feature X globally is to use a version of Python >= feature X's MandatoryRelease".) Or use // when you mean //.

Another possibility is to use six, a module designed to let you write code that's almost Python 3.3 and have it work properly in 2.4-2.7 (and 3.0-3.2). For example, you don't get a print function, but you do get a print_ function that works exactly the same. You don't get Unicode literals, but you get u() fake literals—which, together with a UTF-8 encoding declaration in the source, is almost good enough. And it provides a whole lot of stuff that you can't get from __future__ as well—StringIO and BytesIO, exec as a function, the next function, etc.

If the problem is that you have 1000 source files, and it's a pain to edit them all, you could use sed, or use 3to2 with just the option that fixes division, or…

这篇关于我们如何使 __future__ 进口全球化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆