Python如何别名模块名称(重命名保留向后兼容性)

Mar*_*mro 6 python import python-2.7 python-importlib

我有一个名为python的包foo,我在导入中使用:

import foo.conf
from foo.core import Something
Run Code Online (Sandbox Code Playgroud)

现在我需要将foo模块重命名为其他东西,比方说bar,所以我想这样做:

import bar.conf
from bar.core import Something
Run Code Online (Sandbox Code Playgroud)

但是我希望保持与现有代码的向后兼容性,因此old(foo.)导入也应该起作用并且与bar.导入相同.

如何在python 2.7中实现?

Thi*_*aos 10

这会强制您保留一个foo目录,但我认为这是使其工作的最佳方式.

目录设置:

bar
??? __init__.py
??? baz.py
foo
??? __init__.py

foo_bar.py
Run Code Online (Sandbox Code Playgroud)

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')
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)


Hia*_*tus 7

你的意思是这样的吗?

import foo as bar
Run Code Online (Sandbox Code Playgroud)

您可以使用快捷方式进行模块导入,例如:

from numpy import array as arr

in: arr([1,2,3])
out: array([1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

并且您也可以一次使用多个别名

from numpy import array as foo
in: foo([1,2,3])
out: array([1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

如果你foo是一个班级,你可以做:

bar=foo()
Run Code Online (Sandbox Code Playgroud)

并通过以下方式调用它的子功能:

bar.conf()
Run Code Online (Sandbox Code Playgroud)

这对你有帮助吗?


Grz*_*ota 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())
Run Code Online (Sandbox Code Playgroud)