【问题标题】:importing module without importing that models imports导入模块而不导入模型导入
【发布时间】:2013-04-05 07:37:55
【问题描述】:

我正在尝试导入一个 python 模块而不导入该模块的导入。我正在挖掘一点,但是在导入文件时排除任何命令运行的唯一方法是if __name__ == "__main__": 但是该模块也由支持该模块导入的各种其他模块导入,因此我不能将导入放在 if __name__ == "__main__": 下面 知道如何解决吗?

我不想导入这个模块的原因是这些模块也可以从 jar jython 环境和导入 java.lang 函数中运行。我只需要访问该文件中的一些函数,而不需要整个并导入这些模块中断 make 脚本。我尝试访问的功能不需要任何依赖于模块 ahs。

我通过'from moduleX import f1,f2,f3'导入

【问题讨论】:

  • 用例是什么?您为什么要避免导入依赖项(以及您希望模块在没有它们的情况下如何工作)?
  • 你能提供一个你想要完成的例子吗?
  • 你是如何导入模块的?例如import modulefrom module import *from module import a, b, c 等。
  • 您的问题非常复杂。将您尝试导入的模块分解为两个单独的模块不是更简单:访问java.lang.* 的模块和不访问的模块?
  • 或者,假设这是一个 Jython/CPython 互操作性问题,您可以只使用 platform.system() 和/或 platform.python_implementation() 来检测您正在运行的内容并直接在模块中分支代码。

标签: python import


【解决方案1】:

您或许可以使用导入挂钩来解决此问题。 sys.meta_path 变量是可以覆盖正常导入处理的导入器列表。您可以使用它们来存根仅存在于 Jython 中的模块。这是一个例子:

import types, sys

class Stub(object):
    def __getattr__(self, name):
        return self

class StubModule(types.ModuleType):
    def __getattr__(self, name):
        return Stub()

class StubJavaImporter(object):
    def find_module(self, fullname, path = None):
        if fullname == 'java' or fullname.startswith('java.'):
            return self
        else:
            return None

    def load_module(self, fullname):
        mod = sys.modules.setdefault(fullname, StubModule(fullname))
        mod.__file__ = "<%s>" % self.__class__.__name__
        mod.__loader__ = self
        mod.__path__ = []
        mod.__package__ = fullname
        return mod

sys.meta_path.append(StubJavaImporter())

运行此代码后,您可以导入以java. 开头的任何模块并访问其中的任何属性路径。例如:

In [2]: from java.lang import Object

In [3]: Object.equals
Out[3]: <__main__.Stub at 0x14d8b90>

In [4]: Object
Out[4]: <__main__.Stub at 0x14d8b90>

In [5]: Object.foo.bar.baz
Out[5]: <__main__.Stub at 0x14d8b90>

这可能足以让事情顺利进行。这是一个讨厌的,讨厌的 hack,但如果你真的不能修改有问题的模块,这可能是你能做的最好的。

【讨论】:

    【解决方案2】:

    如果您想使用from module import * 并且不包括在module 中导入的所有内容,那么您应该在module 中定义变量__all__。这个变量应该是一个字符串列表,命名应该导入的类、变量、模块等。

    来自 python 文档

    如果标识符列表被星号 (*) 替换,则模块中定义的所有公共名称都绑定在 import 语句的本地命名空间中

    模块定义的公共名称是通过检查模块命名空间中名为__all__的变量来确定的;如果已定义,它必须是由该模块定义或导入的名称的字符串序列。 __all__ 中给出的名称都被认为是公开的,并且必须存在。如果未定义 __all__,则公共名称集包括在模块命名空间中找到的所有不以下划线字符开头的名称 (_) [...] It旨在避免意外导出不属于 API 的项目(例如在模块中导入和使用的库模块)(强调我的)

    【讨论】:

    • 这似乎不是他的问题。无论是否将属性引入到导入模块的命名空间中,都会执行导入模块的模块范围内的所有代码,如果其中任何一个与当前平台不兼容,都会导致一切崩溃.这似乎是 OP 遇到的问题。
    • 谢谢,这听起来很有趣。但我认为就我而言,这无济于事,因为导入此模块的其他模块需要依赖项。所以我需要一种方法来修改导入模块中的导入语句
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 2012-03-07
    • 1970-01-01
    相关资源
    最近更新 更多