Python 如何为模块名称设置别名(重命名同时保留向后兼容性)

21 投票
3 回答
33941 浏览
提问于 2025-04-18 10:28

我有一个叫做 foo 的 Python 包,我在导入时会用到它:

import foo.conf
from foo.core import Something

现在我想把这个 foo 模块改个名字,比如叫 bar,所以我想这样做:

import bar.conf
from bar.core import Something

但是我还想让旧的代码(也就是用 foo. 导入的代码)也能继续使用,并且它们的功能要和用 bar. 导入的一样。

我该如何在 Python 2.7 中实现这个呢?

3 个回答

7

这个答案适用于子模块:

import sys
import os
from importlib.abc import MetaPathFinder, Loader
import importlib
from MainModule.SubModule import *

class MyLoader(Loader):
    def module_repr(self, module):
        return repr(module)

    def load_module(self, fullname):
        old_name = fullname
        names = fullname.split(".")
        names[1] = "SubModule"
        fullname = ".".join(names)
        module = importlib.import_module(fullname)
        sys.modules[old_name] = module
        return module


class MyImport(MetaPathFinder):
    def find_module(self, fullname, path=None):
        names = fullname.split(".")
        if len(names) >= 2 and names[0] == "Module" and names[1] == "LegacySubModule":
            return MyLoader()


sys.meta_path.append(MyImport())
16

你是指像这样吗?

import foo as bar

你可以使用快捷方式来导入模块,比如:

from numpy import array as arr

in: arr([1,2,3])
out: array([1, 2, 3])

而且你还可以同时使用多个别名

from numpy import array as foo
in: foo([1,2,3])
out: array([1, 2, 3])

如果你的 foo 是一个类,你可以这样做:

bar=foo()

然后通过以下方式调用它的子函数:

bar.conf()

这样对你有帮助吗?

14

这就要求你必须保留一个 foo 目录,不过我觉得这是让它正常工作的最好方法。

目录结构如下:

bar
├── __init__.py
└── baz.py
foo
└── __init__.py

foo_bar.py

bar/__init__.py 是空的。
bar/baz.py 里面有: worked = True

foo/__init__.py

import sys

# make sure bar is in sys.modules
import bar
# link this module to bar
sys.modules[__name__] = sys.modules['bar']

# Or simply
sys.modules[__name__] = __import__('bar')

foo_bar.py

import foo.baz

assert(hasattr(foo, 'baz') and hasattr(foo.baz, 'worked'))
assert(foo.baz.worked)

import bar
assert(foo is bar)

撰写回答