简体   繁体   English

将阴影模块导入sys.path中的阴影模块

[英]Import shadowed module into shadowing module which is in sys.path

There are similar questions about importing an intentionally shadowed module into a shadowing module which is not in sys.path . 关于将有意屏蔽的模块导入不在 sys.path的屏蔽模块中,存在类似的问题。 That's pretty easy; 那很简单; just use: 只需使用:

from __future__ import absolute_import

Here's my problem: my module is in sys.path , and it's higher up in sys.path , and that's intentional! 这里是我的问题:我的模块sys.path并且它是由较高的sys.path 这是故意的!

To be more specific, I'm writing a python interpreter which lacks access to stdin , but it can use Tkinter . 更具体地说,我正在编写一个无法访问stdin的python解释器,但是它可以使用Tkinter Not having access to stdin means I can't just use normal input , raw_input , and getpass . 无法访问stdin意味着我不能只使用普通的inputraw_inputgetpass I need to replace those with my own methods. 我需要用自己的方法替换那些方法。 The first two are rather easy to handle - I just replace them in __builtin__ . 前两个很容易处理-我只需将它们替换为__builtin__ getpass isn't as easy though - the user may or may not import it, but when they do, I need to make sure that what they actually import is my module, not the standard one, so that I can get their input through a Tkinter Entry instead of stdin . getpass并不是那么容易-用户可能会或可能不会导入它,但是当他们这样做时,我需要确保他们实际导入的是我的模块,而不是标准模块,以便我可以通过Tkinter Entry代替stdin That part I have handled. 我已经处理过的那部分。 The part that I can't figure out is how to pass everything else through to the standard getpass , IE, getuser() should be handled by the real getpass . 我无法弄清的部分是如何将其他所有内容传递给标准getpass IE, getuser()应该由真正的getpass处理。

Here's what I tried: 这是我尝试过的:

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()

I added in those two print statements just so I could see why getuser() was failing, and I found that it would print this: 我只是在这两个打印语句中添加了代码,这样我才能getuser()为什么getuser()失败了,我发现它将打印以下内容:

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

Plus I end up with infinite recursion. 另外,我最终得到了无限递归。

So... any ideas how I can resolve this? 所以...有什么想法可以解决这个问题?

To try reproducing this, write a file like the one I have above, name it getpass.py , then add the folder that contains it to your sys.path , then run: 要尝试重现此内容,请像上面一样编写一个文件,将其命名为getpass.py ,然后将包含该文件的文件夹添加到sys.path ,然后运行:

import getpass
getpass.getuser()

(Comments posted as an answer:) (评论发布为答案:)

Use imp.load_module and load the module you want, ignoring the standard search. 使用imp.load_module并加载所需的模块,而imp.load_module执行标准搜索。

If you somehow learn the path of the file to import (eg by searching at sys.path on your own), you can just open that file, say something like 如果您以某种方式了解要导入的文件的路径(例如,自行搜索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
  )

Then use shadow_getpass as you would a normal module. 然后像普通模块一样使用shadow_getpass

Error-handling is omitted, but it's not hard to catch appropriate exceptions. 错误处理被省略,但是捕获适当的异常并不难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM