Creating aliases for Python packages?

I have a directory, let it Storagepopulate packages with bulky type names mypackage-xxyyzzww, and of course, Storageis on mine PYTHONPATH. Because packages have long, unsupported names, all packages are symbolically associated with friendlier names, such as mypackage.

Now, I don't want to rely on file system symlinks to do this, instead I tried to trick sys.pathand sys.modules. I am currently doing something like this:

import imp
imp.load_package('mypackage', 'Storage/mypackage-xxyyzzww')

How bad is it to do so, and is there any chance that this will break through in the future? The funny thing is that the documents do not even mention the function imp.load_package.

EDIT: Also, without relying on symbolic links, I can no longer use the variable PYTHONPATH.

+3
source share
3 answers

importlib may be more appropriate as it uses / implements PEP302 .

Follow the example of DictImporter, but redefine find_moduleto find the real file name and save it in a dict, then redefine load_moduleto get the code from the found file.

You do not need to use sys.path once you have created your storage module

#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

Then when you import Storage.mypackage, python will immediately use your importer without bothering to searchsys.path

. "", , Storage sys.path, 3.1, 2.6, , loader, PEP302. sys.meta_path, 3.1 StackOverflow 2.6 ImportError. ... , .

+3

imp .

import mypackage_xxyyzzww as mypackage

__init__.py Storage, , .

/__ __ INIT :.

import mypackage_xxyyzzww as mypackage
import otherpackage_xxyyzzww as otherpackage

:

>>> from Storage import mypackage, otherpackage
+9

- . , python.

0

Source: https://habr.com/ru/post/1772917/


All Articles