在Python中重载命名空间

13 投票
3 回答
17930 浏览
提问于 2025-04-15 12:45

假设有一个文件夹,路径是'/home/user/temp/a40bd22344'。这个名字是完全随机的,每次都会变化。我需要在Python中用一个固定的名字,比如'project',来导入这个文件夹。我知道可以把这个文件夹添加到sys.path中,这样就能找到它,但有没有办法把'a40bd22344'替换成'project'呢?

也许可以在init.py里做一些巧妙的处理?

补充说明:

这个方法需要是全局的,也就是说,其他脚本通过标准方式加载'project'时:

import project

也能正常工作,实际上加载的是a40bd22344这个文件夹。

3 个回答

17

当然,project = __import__('a40bd22344')sys.path 设置正确后就能正常工作。

假设你想在一个函数里实现这个功能,传入完整路径作为参数,并且正确设置global导入的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的原始状态。

25

这里有一种方法可以做到这一点,不需要修改sys.path,使用Python中的imp模块:

import imp

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

project.some_func()

这里有一个链接,可以查看关于imp模块的好文档:

19

首先,你需要用import来引入它:

>>> __import__('temp/a40bd22344')
<module 'temp/a40bd22344' from 'temp/a40bd22344/__init__.py'>

然后,你要确保这个模块在Python中被称为project

>>> import sys
>>> sys.modules['project'] = sys.modules.pop('temp/a40bd22344')

这样一来,在当前的Python会话中,任何引入project的地方都会得到原来的模块

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

这对子模块也适用:如果你在同一个位置有一个foobar.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)]

撰写回答