如何在 C 扩展模块中从 __future__ 导入
How to import from __future__ in C extension module
我有一个扩展模块需要支持 Python 2 和 Python 3。当它加载时,我想做类似 from __future__ import print_function
的事情,这样如果有人尝试为此:
PyRun_SimpleString("print 'foo'");
它会失败,但如果他们这样做:
PyRun_SimpleString("print('foo', file=sys.stdout)");
一定会成功的。我已经尝试了很多事情,包括来自未来声明的 PyRun_SimpleString
。像这样:
PyRun_SimpleString("from __future__ import print_function");
我也试过这样调用 PyImport_ImportModuleEx
:
PyImport_ImportModuleEx("__future__", nullptr, nullptr, fromlist);
其中 fromlist
是表示列表 ["print_function"]
的 PyObject
这些都不起作用。有可能使这项工作吗?
PyRun_SimpleString 没有任何地方可以指定编译器标志,但是 whole host of related functions 有更多可用选项。例如,PyRun_SimpleStringFlags
做 PyRun_SimpleString
做的事情,但使用 flags
参数来指定编译器标志。使用 PyRun_SimpleStringFlags
执行的 __future__
语句可以修改 flags
,并且使用相同 flags
.
的其他调用将看到更改
您可以使用 future 语句或 C 级标志定义来初始化 flags
。大多数可能的标志都没有在 C-api 文档中列出(因为 C-api 文档有点烂),但您可以在 __future__
模块或Python 源代码的几个部分。
>>> import __future__
>>> for name in dir(__future__):
... if name.startswith('CO_'):
... print name
...
CO_FUTURE_ABSOLUTE_IMPORT
CO_FUTURE_DIVISION
CO_FUTURE_PRINT_FUNCTION
CO_FUTURE_UNICODE_LITERALS
CO_FUTURE_WITH_STATEMENT
CO_GENERATOR_ALLOWED
CO_NESTED
例如,您可以 运行 一个受 from __future__ import print_function
和
影响的字符串
PyCompilerFlags flags = {CO_FUTURE_PRINT_FUNCTION};
PyRun_SimpleStringFlags(command, &flags);
如果您想保存用户执行的未来语句的效果,您可以将 PyCompilerFlags 结构保存在某处,并对所有调用使用相同的结构。
话虽如此,我认为自动应用 from __future__ import print_function
并不是正确的做法。人们会惊讶地期待他们所使用的任何解释器的默认行为。此外,PyRun_InteractiveOneFlags
可能有助于让用户输入多行 Python 语句。
我有一个扩展模块需要支持 Python 2 和 Python 3。当它加载时,我想做类似 from __future__ import print_function
的事情,这样如果有人尝试为此:
PyRun_SimpleString("print 'foo'");
它会失败,但如果他们这样做:
PyRun_SimpleString("print('foo', file=sys.stdout)");
一定会成功的。我已经尝试了很多事情,包括来自未来声明的 PyRun_SimpleString
。像这样:
PyRun_SimpleString("from __future__ import print_function");
我也试过这样调用 PyImport_ImportModuleEx
:
PyImport_ImportModuleEx("__future__", nullptr, nullptr, fromlist);
其中 fromlist
是表示列表 ["print_function"]
PyObject
这些都不起作用。有可能使这项工作吗?
PyRun_SimpleString 没有任何地方可以指定编译器标志,但是 whole host of related functions 有更多可用选项。例如,PyRun_SimpleStringFlags
做 PyRun_SimpleString
做的事情,但使用 flags
参数来指定编译器标志。使用 PyRun_SimpleStringFlags
执行的 __future__
语句可以修改 flags
,并且使用相同 flags
.
您可以使用 future 语句或 C 级标志定义来初始化 flags
。大多数可能的标志都没有在 C-api 文档中列出(因为 C-api 文档有点烂),但您可以在 __future__
模块或Python 源代码的几个部分。
>>> import __future__
>>> for name in dir(__future__):
... if name.startswith('CO_'):
... print name
...
CO_FUTURE_ABSOLUTE_IMPORT
CO_FUTURE_DIVISION
CO_FUTURE_PRINT_FUNCTION
CO_FUTURE_UNICODE_LITERALS
CO_FUTURE_WITH_STATEMENT
CO_GENERATOR_ALLOWED
CO_NESTED
例如,您可以 运行 一个受 from __future__ import print_function
和
PyCompilerFlags flags = {CO_FUTURE_PRINT_FUNCTION};
PyRun_SimpleStringFlags(command, &flags);
如果您想保存用户执行的未来语句的效果,您可以将 PyCompilerFlags 结构保存在某处,并对所有调用使用相同的结构。
话虽如此,我认为自动应用 from __future__ import print_function
并不是正确的做法。人们会惊讶地期待他们所使用的任何解释器的默认行为。此外,PyRun_InteractiveOneFlags
可能有助于让用户输入多行 Python 语句。