⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ni.py

📁 minimal python variant for small footprint apps like embedded apps
💻 PY
字号:
"""New import scheme with package support.Quick Reference---------------- To enable package support, execute "import ni" before importing any  packages.  Importing this module automatically installs the relevant  import hooks.- To create a package named spam containing sub-modules ham, bacon and  eggs, create a directory spam somewhere on Python's module search  path (i.e. spam's parent directory must be one of the directories in  sys.path or $PYTHONPATH); then create files ham.py, bacon.py and  eggs.py inside spam.- To import module ham from package spam and use function hamneggs()  from that module, you can either do    import spam.ham             # *not* "import spam" !!!    spam.ham.hamneggs()  or    from spam import ham    ham.hamneggs()  or    from spam.ham import hamneggs    hamneggs()- Importing just "spam" does not do what you expect: it creates an  empty package named spam if one does not already exist, but it does  not import spam's submodules.  The only submodule that is guaranteed  to be imported is spam.__init__, if it exists.  Note that  spam.__init__ is a submodule of package spam.  It can reference to  spam's namespace via the '__.' prefix, for instance    __.spam_inited = 1          # Set a package-level variableTheory of Operation-------------------A Package is a module that can contain other modules.  Packages can benested.  Package introduce dotted names for modules, like P.Q.M, whichcould correspond to a file P/Q/M.py found somewhere on sys.path.  Itis possible to import a package itself, though this makes little senseunless the package contains a module called __init__.A package has two variables that control the namespace used forpackages and modules, both initialized to sensible defaults the firsttime the package is referenced.(1) A package's *module search path*, contained in the per-packagevariable __path__, defines a list of *directories* where submodules orsubpackages of the package are searched.  It is initialized to thedirectory containing the package.  Setting this variable to None makesthe module search path default to sys.path (this is not quite the sameas setting it to sys.path, since the latter won't track laterassignments to sys.path).(2) A package's *import domain*, contained in the per-package variable__domain__, defines a list of *packages* that are searched (usingtheir respective module search paths) to satisfy imports.  It isinitialized to the list cosisting of the package itself, its parentpackage, its parent's parent, and so on, ending with the root package(the nameless package containing all top-level packages and modules,whose module search path is None, implying sys.path).The default domain implements a search algorithm called "expandingsearch".  An alternative search algorithm called "explicit search"fixes the import search path to contain only the root package,requiring the modules in the package to name all imported modules bytheir full name.  The convention of using '__' to refer to the currentpackage (both as a per-module variable and in module names) can beused by packages using explicit search to refer to modules in the samepackage; this combination is known as "explicit-relative search".The PackageImporter and PackageLoader classes together implement thefollowing policies:- There is a root package, whose name is ''.  It cannot be imported  directly but may be referenced, e.g. by using '__' from a top-level  module.- In each module or package, the variable '__' contains a reference to  the parent package; in the root package, '__' points to itself.- In the name for imported modules (e.g. M in "import M" or "from M  import ..."), a leading '__' refers to the current package (i.e.  the package containing the current module); leading '__.__' and so  on refer to the current package's parent, and so on.  The use of  '__' elsewhere in the module name is not supported.- Modules are searched using the "expanding search" algorithm by  virtue of the default value for __domain__.- If A.B.C is imported, A is searched using __domain__; then  subpackage B is searched in A using its __path__, and so on.- Built-in modules have priority: even if a file sys.py exists in a  package, "import sys" imports the built-in sys module.- The same holds for frozen modules, for better or for worse.- Submodules and subpackages are not automatically loaded when their  parent packages is loaded.- The construct "from package import *" is illegal.  (It can still be  used to import names from a module.)- When "from package import module1, module2, ..." is used, those    modules are explicitly loaded.- When a package is loaded, if it has a submodule __init__, that  module is loaded.  This is the place where required submodules can  be loaded, the __path__ variable extended, etc.  The __init__ module  is loaded even if the package was loaded only in order to create a  stub for a sub-package: if "import P.Q.R" is the first reference to  P, and P has a submodule __init__, P.__init__ is loaded before P.Q  is even searched.Caveats:- It is possible to import a package that has no __init__ submodule;  this is not particularly useful but there may be useful applications  for it (e.g. to manipulate its search paths from the outside!).- There are no special provisions for os.chdir().  If you plan to use  os.chdir() before you have imported all your modules, it is better  not to have relative pathnames in sys.path.  (This could actually be  fixed by changing the implementation of path_join() in the hook to  absolutize paths.)- Packages and modules are introduced in sys.modules as soon as their  loading is started.  When the loading is terminated by an exception,  the sys.modules entries remain around.- There are no special measures to support mutually recursive modules,  but it will work under the same conditions where it works in the  flat module space system.- Sometimes dummy entries (whose value is None) are entered in  sys.modules, to indicate that a particular module does not exist --  this is done to speed up the expanding search algorithm when a  module residing at a higher level is repeatedly imported (Python  promises that importing a previously imported module is cheap!)- Although dynamically loaded extensions are allowed inside packages,  the current implementation (hardcoded in the interpreter) of their  initialization may cause problems if an extension invokes the  interpreter during its initialization.- reload() may find another version of the module only if it occurs on  the package search path.  Thus, it keeps the connection to the  package to which the module belongs, but may find a different file.XXX Need to have an explicit name for '', e.g. '__root__'."""import impimport stringimport sysimport __builtin__import ihooksfrom ihooks import ModuleLoader, ModuleImporterclass PackageLoader(ModuleLoader):    """A subclass of ModuleLoader with package support.    find_module_in_dir() will succeed if there's a subdirectory with    the given name; load_module() will create a stub for a package and    load its __init__ module if it exists.    """    def find_module_in_dir(self, name, dir):        if dir is not None:            dirname = self.hooks.path_join(dir, name)            if self.hooks.path_isdir(dirname):                return None, dirname, ('', '', 'PACKAGE')        return ModuleLoader.find_module_in_dir(self, name, dir)    def load_module(self, name, stuff):        file, filename, info = stuff        suff, mode, type = info        if type == 'PACKAGE':            return self.load_package(name, stuff)        if sys.modules.has_key(name):            m = sys.modules[name]        else:            sys.modules[name] = m = imp.new_module(name)        self.set_parent(m)        if type == imp.C_EXTENSION and '.' in name:            return self.load_dynamic(name, stuff)        else:            return ModuleLoader.load_module(self, name, stuff)    def load_dynamic(self, name, stuff):        file, filename, (suff, mode, type) = stuff        # Hack around restriction in imp.load_dynamic()        i = string.rfind(name, '.')        tail = name[i+1:]        if sys.modules.has_key(tail):            save = sys.modules[tail]        else:            save = None        sys.modules[tail] = imp.new_module(name)        try:            m = imp.load_dynamic(tail, filename, file)        finally:            if save:                sys.modules[tail] = save            else:                del sys.modules[tail]        sys.modules[name] = m        return m    def load_package(self, name, stuff):        file, filename, info = stuff        if sys.modules.has_key(name):            package = sys.modules[name]        else:            sys.modules[name] = package = imp.new_module(name)        package.__path__ = [filename]        self.init_package(package)        return package    def init_package(self, package):        self.set_parent(package)        self.set_domain(package)        self.call_init_module(package)    def set_parent(self, m):        name = m.__name__        if '.' in name:            name = name[:string.rfind(name, '.')]        else:            name = ''        m.__ = sys.modules[name]    def set_domain(self, package):        name = package.__name__        package.__domain__ = domain = [name]        while '.' in name:            name = name[:string.rfind(name, '.')]            domain.append(name)        if name:            domain.append('')    def call_init_module(self, package):        stuff = self.find_module('__init__', package.__path__)        if stuff:            m = self.load_module(package.__name__ + '.__init__', stuff)            package.__init__ = mclass PackageImporter(ModuleImporter):    """Importer that understands packages and '__'."""    def __init__(self, loader = None, verbose = 0):        ModuleImporter.__init__(self,        loader or PackageLoader(None, verbose), verbose)    def import_module(self, name, globals={}, locals={}, fromlist=[]):        if globals.has_key('__'):            package = globals['__']        else:            # No calling context, assume in root package            package = sys.modules['']        if name[:3] in ('__.', '__'):            p = package            name = name[3:]            while name[:3] in ('__.', '__'):                p = p.__                name = name[3:]            if not name:                return self.finish(package, p, '', fromlist)            if '.' in name:                i = string.find(name, '.')                name, tail = name[:i], name[i:]            else:                tail = ''            mname = p.__name__ and p.__name__+'.'+name or name            m = self.get1(mname)            return self.finish(package, m, tail, fromlist)        if '.' in name:            i = string.find(name, '.')            name, tail = name[:i], name[i:]        else:            tail = ''        for pname in package.__domain__:            mname = pname and pname+'.'+name or name            m = self.get0(mname)            if m: break        else:            raise ImportError, "No such module %s" % name        return self.finish(m, m, tail, fromlist)    def finish(self, module, m, tail, fromlist):        # Got ....A; now get ....A.B.C.D        yname = m.__name__        if tail and sys.modules.has_key(yname + tail): # Fast path            yname, tail = yname + tail, ''            m = self.get1(yname)        while tail:            i = string.find(tail, '.', 1)            if i > 0:                head, tail = tail[:i], tail[i:]            else:                head, tail = tail, ''            yname = yname + head            m = self.get1(yname)        # Got ....A.B.C.D; now finalize things depending on fromlist        if not fromlist:            return module        if '__' in fromlist:            raise ImportError, "Can't import __ from anywhere"        if not hasattr(m, '__path__'): return m        if '*' in fromlist:            raise ImportError, "Can't import * from a package"        for f in fromlist:            if hasattr(m, f): continue            fname = yname + '.' + f            self.get1(fname)        return m    def get1(self, name):        m = self.get(name)        if not m:            raise ImportError, "No module named %s" % name        return m    def get0(self, name):        m = self.get(name)        if not m:            sys.modules[name] = None        return m    def get(self, name):        # Internal routine to get or load a module when its parent exists        if sys.modules.has_key(name):            return sys.modules[name]        if '.' in name:            i = string.rfind(name, '.')            head, tail = name[:i], name[i+1:]        else:            head, tail = '', name        path = sys.modules[head].__path__        stuff = self.loader.find_module(tail, path)        if not stuff:            return None        sys.modules[name] = m = self.loader.load_module(name, stuff)        if head:            setattr(sys.modules[head], tail, m)        return m    def reload(self, module):        name = module.__name__        if '.' in name:            i = string.rfind(name, '.')            head, tail = name[:i], name[i+1:]            path = sys.modules[head].__path__        else:            tail = name            path = sys.modules[''].__path__        stuff = self.loader.find_module(tail, path)        if not stuff:            raise ImportError, "No module named %s" % name        return self.loader.load_module(name, stuff)    def unload(self, module):        if hasattr(module, '__path__'):            raise ImportError, "don't know how to unload packages yet"        PackageImporter.unload(self, module)    def install(self):        if not sys.modules.has_key(''):            sys.modules[''] = package = imp.new_module('')            package.__path__ = None            self.loader.init_package(package)            for m in sys.modules.values():                if not m: continue                if not hasattr(m, '__'):                    self.loader.set_parent(m)        ModuleImporter.install(self)def install(v = 0):    ihooks.install(PackageImporter(None, v))def uninstall():    ihooks.uninstall()def ni(v = 0):    install(v)def no():    uninstall()def test():    import pdb    try:        testproper()    except:        sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()        print        print sys.last_type, ':', sys.last_value        print        pdb.pm()def testproper():    install(1)    try:        import mactest        print dir(mactest)        raw_input('OK?')    finally:        uninstall()if __name__ == '__main__':    test()else:    install()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -