为Python包创建别名?

kme*_*lvn 3 python

我有一个目录,让我们把它称为Storage包含笨拙名字的包mypackage-xxyyzzww,当然Storage是我的PYTHONPATH.由于包具有很长的不可知名称,因此所有包都符号链接到更友好的名称,例如mypackage.

现在,我不想依靠文件系统的符号链接要做到这一点,而不是我试图与周围碴sys.pathsys.modules.目前我正在做这样的事情:

import imp
imp.load_package('mypackage', 'Storage/mypackage-xxyyzzww')
Run Code Online (Sandbox Code Playgroud)

以这种方式做事有多糟糕,未来有可能会破裂吗?有趣的是,imp.load_package文档中甚至没有提及函数.

编辑:除了不依赖于符号链接,我不能再使用PYTHONPATH变量了.

Gar*_*yde 9

imp您可以为导入的模块指定不同的名称,而不是使用.

import mypackage_xxyyzzww as mypackage
Run Code Online (Sandbox Code Playgroud)

如果您随后在其中创建了一个__init__.py文件Storage,则可以添加上述几行以使导入更容易.

存储/ __ init__.py:

import mypackage_xxyyzzww as mypackage
import otherpackage_xxyyzzww as otherpackage
Run Code Online (Sandbox Code Playgroud)

解释:

>>> from Storage import mypackage, otherpackage
Run Code Online (Sandbox Code Playgroud)

  • "mypackage-xxyyzzww"不是有效的包名. (3认同)
  • 哎呀,问题不在于名称的丑陋 - 你使用的是非法包名! (2认同)

Ter*_*way 4

importlib可能更合适,因为它使用/实现了PEP302机制。

遵循 DictImporter 示例,但重写find_module以查找真实文件名并将其存储在字典中,然后重写load_module以从找到的文件中获取代码。

创建存储模块后,您不需要使用 sys.path

#from importlib import abc
import imp
import os
import sys
import logging
logging.basicConfig(level=logging.DEBUG)

dprint = logging.debug


class MyImporter(object):
    def __init__(self,path):
        self.path=path
        self.names = {}

    def find_module(self,fullname,path=None):
        dprint("find_module({fullname},{path})".format(**locals()))
        ml = imp.find_module(fullname,path)
        dprint(repr(ml))
        raise ImportError


    def load_module(self,fullname):
        dprint("load_module({fullname})".format(**locals()))
        return imp.load_module(fullname)
        raise ImportError


def load_storage( path, modname=None ):
    if modname is None:
        modname = os.path.basename(path)

    mod = imp.new_module(modname)
    sys.modules[modname] = mod
    assert mod.__name__== modname
    mod.__path__=[path]
    #sys.meta_path.append(MyImporter(path))
    mod.__loader__= MyImporter(path)
    return mod

if __name__=="__main__":
    load_storage("arbitrary-path-to-code/Storage")

    from Storage import plain
    from Storage import mypkg
Run Code Online (Sandbox Code Playgroud)

然后当你这样做时import Storage.mypackage,python将立即使用你的导入器而无需费心去查看sys.path

那是行不通的。上面的代码确实可以在 Storage 下导入普通模块,而不需要 Storage 位于 sys.path 上,但 3.1 和 2.6 似乎都忽略了PEP302 中提到的loader属性。如果我取消注释 sys.meta_path 行,3.1 会因 StackOverflow 终止,2.6 则会因 ImportError 终止。嗯...我现在没时间了,但稍后可能会看一下。