将镜像模块导入sys.path中的shadowing模块

时间:2014-10-07 14:42:17

标签: python python-module

关于将有意遮蔽的模块导入到sys.path的阴影模块,也存在类似的问题。这很容易;只需使用:

from __future__ import absolute_import

这是我的问题:sys.path中的模块 它在sys.path中更高, 这是故意的!

更具体地说,我正在编写一个无法访问stdin的python解释器,但它可以使用Tkinter。无法访问stdin表示我无法使用普通inputraw_inputgetpass。我需要用自己的方法替换它们。前两个很容易处理 - 我只是在__builtin__中替换它们。 getpass并不容易 - 用户可能会也可能不会导入它,但是当他们这样做时,我需要确保他们实际导入的是我的模块,而不是标准模块,以便我可以通过Tkinter Entry代替stdin获取他们的输入。那部分我已经处理过了。我无法弄清楚的部分是如何将其他所有内容传递给标准getpass,IE,getuser()应该由真实getpass处理。

这是我尝试的内容:

from __future__ import absolute_import
import sys
pathToThisGetpass = sys.path.pop(1)    # I know that the shadowing getpass is at index 1.
import getpass as realGetpass          # Since the path doesn't contain this getpass, this should be the real one, right?
sys.path.insert(1, pathToThisGetpass)  # Put this getpass module back into the path again

def getuser():
    print("I am " + str(getuser))
    print("I should call " + str(realGetpass.getuser))
    return realGetpass.getuser()

我在这两个印刷语句中添加了这样我才明白为什么getuser()失败了,我发现它会打印出来:

I am <function getuser at 0x026D8A30>
I should call <function getuser at 0x026D8A30>

另外,我最终得到了无限递归。

那么......我有什么想法可以解决这个问题吗?

要尝试重现此操作,请编写一个类似我上面的文件,将其命名为getpass.py,然后将包含它的文件夹添加到sys.path,然后运行:

import getpass
getpass.getuser()

1 个答案:

答案 0 :(得分:1)

(评论作为答案发布:)

使用imp.load_module并加载所需的模块,忽略标准搜索。

如果您以某种方式了解要导入的文件的路径(例如,通过自己在sys.path搜索),则可以打开该文件,例如

with open(off_path_name) as shadowed_module_file:
  shadow_getpass = imp.load_module(
      'shadowed.getpass',    # the name reported by the module, rather arbitrary
      shadowed_module_file,  # where we are reading it from
      '', # we don't plan to reload this module normally, no suffix
      ('', 'r', imp.PY_COMPILED) # Assuming it's getpass.pyc, use PY_COMPILED
  )

然后像使用普通模块一样使用shadow_getpass

省略了错误处理,但捕获适当的异常并不困难。