【问题标题】:Import in python 3 complains about argument as a str / bytes在 python 3 中导入抱怨参数为 str / bytes
【发布时间】:2014-10-20 16:52:05
【问题描述】:

我一直 updating a quaternions package 用于与 numpy 集成,因此它可以在 python 2 和 python 3 中使用。不幸的是,基本导入步骤在 3.x 中失败了,尽管它在 python 2.7 中从未失败过. (我用python2.7编译2.7版本,用python3.x编译3.x版本。distutils很简单的东西。)错误信息甚至没有出现在google的结果中,我只是不知道从这里到哪里去。

这是导入包的简单尝试的完整输出:

> python -c 'import quaternion'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/mynamehere/.continuum/anaconda/envs/py3k/lib/python3.4/site-packages/quaternion/__init__.py", line 3, in <module>
    from .numpy_quaternion import quaternion
TypeError: __import__() argument 1 must be str, not bytes

正如错误消息所说,__init__.py 中有一行说

from .numpy_quaternion import quaternion

但是为什么会有问题呢?在与__init__.py 文件相同的目录下有一个文件numpy_quaternion.so,似乎包含相关符号。 Travis-CI 表明它在 2.7 中运行良好(其他测试通过),但在 3.2 和 3.4 中失败。所以这不仅仅是我的python安装有问题。我试图删除相对导入的.,但python找不到要从中导入的numpy_quaternion(不足为奇)。我尝试将其更改为from quaternion.numpy_quaternion,但我得到了同样的错误。

我看到there have been changes to the import system in python 3,但如果有的话,我猜想这将比其他方式 py3k 兼容。怎么了?我怎样才能让它工作?

澄清一下,我的层次结构如下所示:

.../site-packages/
    quaternion/
        __init__.py
        numpy_quaternion.so

在有问题的行之前唯一出现的是import numpy as np,它通常会成功,没有问题。

【问题讨论】:

    标签: python python-2.7 python-3.x python-import python-c-api


    【解决方案1】:

    python-list 人员立即回复我并提出了很好的建议。结果我在numpy_quaternion.so 中导入了一些东西(使用c-api),但是我给那个函数的参数是错误的。我(基本上)使用来自a similar package的代码:

    PyObject* numpy_str = PyString_FromString("numpy");
    PyObject* numpy = PyImport_Import(numpy_str);
    

    我通过使用修复它

    PyObject* numpy = PyImport_ImportModule("numpy");
    

    正如 J. F. Sebastian 在 cmets 中指出的那样,我出错的原因是因为 PyString_FromString 在我使用 python 3 时只是一个错误函数的 #define

    【讨论】:

    • 注意:Porting Extension Modules to Python 3“C 语言中 Python 3 的 PyString_* 函数等价于 Python 2 的 PyUnicode_*。 Unicode 文本使用PyString,二进制数据使用PyBytes。您问题中的 TypeError 建议您以某种方式在 Python 3 上使用 PyBytes 而不是 PyString。
    • 啊哈!不是直接的,但我确实包含npy_3kcompat.h,它包含#define PyString_FromString PyBytes_FromString。所以它在我看来是正确的,但事实并非如此;事实上,PyString_FromString 甚至没有在 python3 中定义。
    【解决方案2】:

    由于很简单,我会先尝试绝对导入,但如果我在下面的猜测是正确的,这将不起作用。

    from quaternion.numpy_quaternion import quaternion
    

    从你的帖子中,我猜你的层次结构看起来像

    .../Libe/site-packages
        quaternion
        __init__.py
        numpy_quaternion.so
            quaternion  # a symbol in .so, not a .py
    

    并且那个四元数是一个模块,而不是一个函数或类。我猜这是因为我无法想象 'numpy_quaternion' 变成字节,而 .so 必须将 'quaternion' 作为字节返回 2.7 才能工作,所以也许它对 3.x 也是如此。我的 unix 经验早于 Python。但我的印象是 2.x 和 3.x 需要单独的 .so。否则,可能需要某些编译标志。如果我是正确的,您需要将 'numpy_quaternion_3x.so 添加到您的包中并在 sys.version[0] 上切换导入。

    如果您在这里没有得到更多响应,请尝试 python-list,它可以在 news.gmane.com 上作为新闻组镜像 gmane.comp.python.general 轻松访问。常规响应者包括一些精明的 linux 用户。

    【讨论】:

    • 是的,我已经尝试过绝对导入。 (在我的帖子中提到过,但我没有说清楚。)另外,py2.7 和 py3.x 有单独的lib 目录,每个目录都用于编译自己的目录,所以他们确实得到了他们的拥有.so 文件。 (py3.x 甚至不知道 py2.7 的存在。)不过,我会在 python-list 上尝试。谢谢!
    猜你喜欢
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    相关资源
    最近更新 更多