Python中的重写命名空间

Python中的重写命名空间,python,python-import,Python,Python Import,假设有一个文件夹“/home/user/temp/a40bd22344”。名称是完全随机的,在每次迭代中都会发生变化。我需要能够在Python中使用固定名称导入此文件夹,例如“project”。我知道我可以将此文件夹添加到sys.path以启用导入查找,但是否有方法将“a40bd22344”替换为“project” 也许是init.py中的一些聪明的黑客 增加: 它需要是全局的-也就是说,其他脚本通过标准加载“项目”: import project 必须正常工作,改为加载a40bd22344。

假设有一个文件夹“/home/user/temp/a40bd22344”。名称是完全随机的,在每次迭代中都会发生变化。我需要能够在Python中使用固定名称导入此文件夹,例如“project”。我知道我可以将此文件夹添加到sys.path以启用导入查找,但是否有方法将“a40bd22344”替换为“project”

也许是init.py中的一些聪明的黑客

增加:

它需要是全局的-也就是说,其他脚本通过标准加载“项目”:

import project

必须正常工作,改为加载a40bd22344。

当然,
project=\uuuuu import\uuuu('a40bd22344')
sys.path
设置正确后才能正常工作

假设您希望在函数中使用完整路径作为参数,并正确设置
project
的全局导入(以及神奇地使
import project
在其他模块中工作)。小菜一碟:

def weirdimport(fullpath):
  global project

  import os
  import sys
  sys.path.append(os.path.dirname(fullpath))
  try:
      project = __import__(os.path.basename(fullpath))
      sys.modules['project'] = project
  finally:
      del sys.path[-1]

这也使sys.path保持原样。

这里有一种方法,使用Python中的
imp
模块,不必触摸sys.path:

import imp

f, filename, desc = imp.find_module('a40bd22344', ['/home/user/temp/'])
project = imp.load_module('a40bd22344', f, filename, desc)

project.some_func()
以下是有关
imp
模块的一些好文档的链接:


您首先使用导入导入它:

>>> __import__('temp/a40bd22344')
<module 'temp/a40bd22344' from 'temp/a40bd22344/__init__.py'>
在此之后,在当前Python会话中导入项目的任何内容都将获得原始模块

>>> import project
>>> project
<module 'temp/a40bd22344' from 'temp/a40bd22344/__init__.py'>

我刚刚对我的问题做了澄清,它在这种情况下也会起作用吗?Alex,将import语句放在try.最后一个括号中,以确保sys.path始终正确还原。@Art,正如@krawyoti所说,这是通过将它按@krawyoti所说粘贴在sys.modules[project]中来实现的@krawyoti,很好的建议--让我编辑以反映这两个更改。为什么您不能修复创建临时文件的过程?在源代码处解决这个问题比创建一个复杂的解决方案更容易。将/temp/中的名称固定为真正的模块名有什么错?这超出了我的控制范围,文件夹是由CI服务器创建的。非常好,除了不起作用的一点细节:在Python 2.6和3.1中,它说“ImportError:不支持按文件名导入”。在2.5中,在导入时只说“ImportError:没有名为temp/a40bd22344的模块”(刚刚在我的Mac电脑上尝试了这三种方法,以确认我没有忘记导入是如何工作的!).我假设它在你的平台krawyoti和你的平台Art上都能工作,否则你就不会将它标记为已接受,所以我很好奇:这些是什么平台?很显然,我使用的导入漏洞已经修复。我太懒了,没有在Python 2.6中尝试它。Alex,为我工作。Ubuntu/Python 2.5/2.6。你需要在导入中使用完整路径,或者,将其添加到sys.path,然后在文件夹名上调用import。您可能还需要设置模块的
\uuu name\uuu
属性,以便代码检查它时会看到它与查看
sys.modules
的代码相同。这不会触及sys.path,但我认为使用imp会导致每次都重新加载包我更喜欢Alex的解决方案,因为即使执行多次,它也能做正确的事情。
>>> import project
>>> project
<module 'temp/a40bd22344' from 'temp/a40bd22344/__init__.py'>
>>> import project.foobar
>>> project.foobar
<module 'project.foobar' from 'temp/a40bd22344/foobar.py'>
>>> print sys.version
2.5.2 (r252:60911, Jul 31 2008, 17:28:52) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)]