【问题标题】:Is this __import__ functionality correct?这个 __import__ 功能正确吗?
【发布时间】:2011-03-02 07:50:25
【问题描述】:

我有一个名为 jiva_tasks 的包,我正在尝试通过 celery 导入它(使用 celeryconfig 的 CELERY_IMPORTS 属性。celery 使用的导入语句是这样的:

__import__(module, [], [], [''])

奇怪的是,当使用此语法时,模块会被导入两次,一次为jiva_tasks,另一次为jiva_tasks.(末尾有句点)。现在,芹菜 应该 传递全局变量而不是空列表的可能性很大,但这对我来说似乎很糟糕。即使给出错误的参数,__import__ 也会导入一些不是有效的 Python 模块名称的东西,这似乎很奇怪。

我知道解决这个问题的方法是传入globals,但我想了解为什么会得到这个结果。这是一个错误,还是我不明白__import__ 的工作原理?

更新:如果我使用importlib,它似乎也可以正常工作。

更新 2:这是 sys.meta_pathsys.import_path 就在 __import__ 行执行之前:

>>> sys.meta_path
[]
>>> sys.path_hooks
[<type 'zipimport.zipimporter'>]

在我看来,没有什么不寻常的地方。但是,我刚刚意识到我正在导入的包是使用 setuptools 的开发命令安装的。这有什么不同吗?

【问题讨论】:

    标签: python import celery globals


    【解决方案1】:

    创建一个空文件“foo.py”,然后创建一个“bar.py”,上面写着:

    __import__('foo', [], [], [''])
    import sys
    print sorted(sys.modules)
    

    打印出一个仅包含一次foo 的列表,而不是foo. 或任何其他带有尾随点的列表——因此,导致问题的不仅仅是芹菜使用__import__ 的事实。你能弄清楚芹菜采取了哪些额外的步骤来添加第二个模块吗? (或者在 __import__() 调用之前和之后的 print sorted(sys.modules) 是否表明两个模块都出现在那个时刻——在这种情况下,我们需要查看在导入时定义了哪些导入钩子?)

    【讨论】:

    • 我没有考虑导入钩子。尽管foo. 确实 似乎在调用__import__ 时已在sys.modules 中注册。
    • 如果__import__() 添加foo. 那么让我们看看导入钩子!将打印sys.metapathsys.path_hooks 的输出添加到您的问题中,如果您发现任何问题,请尝试与我们分享他们的代码。
    • 已更新。看起来我没有任何不寻常的导入钩子。
    • 我想问module 的值在 celery 执行导入的那一刻是什么,如果它等于 'jiva_tasks.' 已经有一个尾随句号,并且想根据进行多级导入的规则,这样的值可能会激发 Python 导入逻辑首先导入 jiva_tasks,然后再尝试使用句点 jiva_tasks.。但我刚刚在上面的bar.py 脚本中尝试了__import__('foo.', [], [], ['']),它工作正常——只有foo 被导入。 'foo..' 或更多句点会报错,但一个很好,很有趣!
    猜你喜欢
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    相关资源
    最近更新 更多