【问题标题】:How do I change the name of an imported library?如何更改导入库的名称?
【发布时间】:2012-09-10 13:21:02
【问题描述】:

我正在将 jython 与第三方应用程序一起使用。第三方应用程序有一些内置库foo。为了进行一些(单元)测试,我们希望在应用程序之外运行一些代码。由于foo 绑定到应用程序,我们决定编写自己的模拟实现。

但是有一个问题,我们在 python 中实现了我们的模拟类,而他们的类是在 java 中。因此,要使用他们的代码,可以使用 import foo 并且 foo 是之后的模拟 class。但是,如果我们像这样导入 python 模块,我们会在名称上附加 module,因此必须写 foo.foo 才能进入该类。

为方便起见,我们希望能够编写 from ourlib.thirdparty import foo 以将 foo 绑定到 foo-。但是我们希望避免直接导入ourlib.thirdparty 中的所有类,因为每个文件的加载时间都需要相当长的时间。

在python中有什么办法吗? (Import hooks 并没有走多远,我尝试简单地从load_module 返回类或覆盖我写给sys.modules 的内容(我认为这两种方法都很丑陋,尤其是后者))

编辑

好的:这是 ourlib.thirdparty 中的文件看起来简化后的样子(没有魔法):

foo.py:

try:
    import foo
except ImportError:
    class foo
        ....

实际上它们看起来像这样:

foo.py:

class foo
    ....

__init__.py in ourlib.thirdparty
import sys
import os.path
import imp
#TODO: 3.0 importlib.util abstract base classes could greatly simplify this code or make it prettier.

class Importer(object):
    def __init__(self, path_entry):
        if not path_entry.startswith(os.path.join(os.path.dirname(__file__), 'thirdparty')):
            raise ImportError('Custom importer only for thirdparty objects')

        self._importTuples = {}

    def find_module(self, fullname):
        module = fullname.rpartition('.')[2]

        try:
            if fullname not in self._importTuples:
                fileObj, self._importTuples[fullname] = imp.find_module(module)

                if isinstance(fileObj, file):
                    fileObj.close()
        except:
            print 'backup'
            path = os.path.join(os.path.join(os.path.dirname(__file__), 'thirdparty'), module+'.py')
            if not os.path.isfile(path):
                return None
                raise ImportError("Could not find dummy class for %s (%s)\n(searched:%s)" % (module, fullname, path))

            self._importTuples[fullname] = path, ('.py', 'r', imp.PY_SOURCE)

        return self

    def load_module(self, fullname):
        fp = None
        python = False

        print fullname

        if self._importTuples[fullname][1][2] in (imp.PY_SOURCE, imp.PY_COMPILED, imp.PY_FROZEN):
            fp = open( self._importTuples[fullname][0], self._importTuples[fullname][1][1])
            python = True

        try:
            imp.load_module(fullname, fp, *self._importTuples[fullname])
        finally:
            if python:
                module = fullname.rpartition('.')[2]
                #setattr(sys.modules[fullname], module, getattr(sys.modules[fullname], module))
                #sys.modules[fullname] = getattr(sys.modules[fullname], module)

                if isinstance(fp, file):
                    fp.close()

                return getattr(sys.modules[fullname], module)



sys.path_hooks.append(Importer)

【问题讨论】:

  • from ourlib.thirdparty import foo as foo ?
  • ourlib.thirdparty 是什么?是你写的模拟python代码,还是java代码?
  • 您需要ourlib.thirdparty 的其他课程吗?您的第三段有点模棱两可。
  • @PierreGM as foofrom ... import foo 来说肯定是多余的吗?它已经在 foo 的命名空间中。
  • @PierreGM:应该是from ourlib.thirdparty.foo import foo,我们想做from ourlib.thirparty import foo

标签: python import jython


【解决方案1】:

正如其他人所说,在 Python 中,import 语句本身就有这样的语法:

from foo import foo as original_foo,例如 - 甚至import foo as module_foo

值得注意的是,import 语句将名称绑定到本地上下文上的导入模块或对象 - 但是,字典 sys.modules(在模块 sys of course), is a live reference to all imported modules, using their names as a key. This mechanism plays a key role in avoding that Python re-reads and re-executes and already imported module , when running (that is, if various of yoru modules or sub-modules import the samefoo` 模块上,它只被读取一次-- 后续导入使用存储在 sys.modules 中的引用)。

而且——除了“import...as”语法之外,Python 中的模块只是另一个对象:您可以在运行时为它们分配任何其他名称。

所以,下面的代码也很适合你:

import foo
original_foo = foo
class foo(Mock):
   ...

【讨论】:

  • 嗨,不幸的是我不能使用 mock,因为据我所知它是 jython 3 而不是 (j)ython 2.5。将 myeslef 转回根目录:我用当前使用的代码更新了我的问题,稍微澄清一下,如果我可以自动重命名,我会觉得很好,为什么要写 from ourlib.thirdpartylib.foo import foo,当有人可以写 from ourlib.thirdpartylib import foo 甚至更好时import foo.最后一个是最好的,那么您可以在没有我们的模拟库的情况下使用代码(然后是第三方库请求)。所需要的只是更改导入钩子中的查找方法。
  • ...但是正确的重命名是先决条件。
猜你喜欢
  • 1970-01-01
  • 2018-08-16
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
  • 2018-08-14
相关资源
最近更新 更多