模块的搜索路径:

When a module named spam is imported, the interpreter searches for a file named spam.py in the current directory, and then in the list of directories specified by the environment variable PYTHONPATH. This has the same syntax as the shell variable PATH, that is, a list of directory names. When PYTHONPATH is not set, or when the file is not found there, the search continues in an installation-dependent default path; on Unix, this is usually .:/usr/local/lib/python.

导入一个叫 spam 的模块时,解释器先在当前目录中搜索名为 spam.py 的文件,然后在环境变量 PYTHONPATH 表示的目录列表中搜索,。如果 PYTHONPATH没有设置,或者文件没有找到,接下来搜索安装目录,在UNIX中,通常是 .:/usr/local/lib/python。

当前目录-》PYTHONPATH->python安装默认目录

Actually, modules are searched in the list of directories given by the variable sys.path which is initialized from the directory containing the input script (or the current directory), PYTHONPATH and the installation-dependent default. This allows Python programs that know what they're doing to modify or replace the module search path. Note that because the directory containing the script being run is on the search path, it is important that the script not have the same name as a standard module, or Python will attempt to load the script as a module when that module is imported. This will generally be an error. See section 6.2, ``Standard Modules,'' for more information.

实际上,解释器由 sys.path 变量指定的路径目录搜索模块,该变量初始化时默认包含了输入脚本(或者当前目录), PYTHONPATH 和安装目录。这样就允许Python程序(原文如此,programs;我猜想应该是“programer”,程序员--译者)了解如何修改或替换模块搜索目录。需要注意的是由于这些目录中包含有搜索路径中运行的脚本,所以这些脚本不应该和标准模块重名,否则在导入模块时Python会尝试把这些脚本当作模块来加载。这通常会引发一个错误。请参见 6.2节“标准模块”以了解更多的信息。

转自:Python手册Python Tutorial

除了使用import sys这样的方式加载module之外,

还可以使用:

import sys
sys.path.append('f:\\python\works')

sys.path.insert(0,'f:\\c‘)

1)关于module
通常模块为一个文件,直接使用import来导入就好了。

可以作为module的文件类型有".py"、".pyo"、".pyc"、".pyd"、".so"、".dll"。

2)关于package
通常包总是一个目录,可以使用import导入包,

或者from + import来导入包中的部分模块。

包目录下为首的一个文件便是 __init__.py。

然后是一些模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了。

使用import spam 语句就可以将这个文件(spam)作为模块导入。

默认的检索路径为执行python的当前路径和sys.path路径

系统在导入模块时,要做以下三件事: 
1. 为源代码文件中定义的对象创建一个命名空间,通过这个命名空间可以访问到模块中定义的函数及变量。

2. 在新创建的命名空间里执行源代码文件。

3. 创建一个名为源代码文件的对象,该对象引用模块的命名空间,这样就可以通过这个对象访问模块中的函数及变量,如:

import spam           # 导入并运行模块 spam
 print spam.a          # 访问模块 spam 的属性
 spam.foo()
 c = spam.bar()
 ...

用逗号分割模块名称就可以同时导入多个模块: 
import socket, os, regex模块导入时可以使用 as 关键字来改变模块的引用对象名字:

import os as system
import socket as net, thread as threads
system.chdir("..")
net.gethostname()

使用from语句可以将模块中的对象直接导入到当前的名字空间. from语句不创建一个到模块名字空间的引用对象,而是把被导入模块的一个或多个对象直接放入当前的名字空间:

from socket import gethostname
                               # 将gethostname放如当前名字空间
print gethostname()            # 直接调用
socket.gethostname()           # 引发异常NameError: socket

from语句支持逗号分割的对象,也可以使用星号(*)代表模块中除下划线开头的所有对象:

from socket import gethostname, socket
from socket import *   # 载入所有对象到当前名字空间

import 语句可以在程序的任何位置使用,你可以在程序中多次导入同一个模块,但模块中的代码*仅仅*在该模块被首次导入时执行。后面的import语句只是简单的创建一个到模块名字空间的引用而已。sys.modules字典中保存着所有被导入模块的模块名到模块对象的映射。这个字典用来决定是否需要使用import语句来导入一个模块的最新拷贝. 
from module import * 语句只能用于一个模块的最顶层.*特别注意*:由于存在作用域冲突,不允许在函数中使用from 语句。 
每个模块都拥有 __name__ 属性,它是一个内容为模块名字的字符串。最顶层的模块名称是 __main__ .命令行或是交互模式下程序都运行在__main__ 模块内部. 利用__name__属性,我们可以让同一个程序在不同的场合(单独执行或被导入)具有不同的行为,象下面这样做:

# 检查是单独执行还是被导入

if __name__ == '__main__':
      # Yes
      statements
else:
      # No (可能被作为模块导入)
      statements

模块搜索路径
导入模块时,解释器会搜索sys.path列表,这个列表中保存着一系列目录。一个典型的sys.path 列表的值:

Linux:
['', '/usr/local/lib/python2.0',
     '/usr/local/lib/python2.0/plat-sunos5',
     '/usr/local/lib/python2.0/lib-tk',
     '/usr/local/lib/python2.0/lib-dynload',
     '/usr/local/lib/python2.0/site-packages']
Windows:
['', 'C:\\WINDOWS\\system32\\python24.zip', 'C:\\Documents and Settings\\weizhong', 'C:\\Python24\\DLLs', 'C:\\Python24\\lib', 'C:\\Python24\\lib\\plat-win', 'C:\\Python24\\lib\\lib-tk', 'C:\\Python24\\Lib\\site-packages\\pythonwin', 'C:\\Python24', 'C:\\Python24\\lib\\site-packages', 'C:\\Python24\\lib\\site-packages\\win32', 'C:\\Python24\\lib\\site-packages\\win32\\lib', 'C:\\Python24\\lib\\site-packages\\wx-2.6-msw-unicode']

空字符串 代表当前目录. 要加入新的搜索路径,只需要将这个路径加入到这个列表.

二包
多个关系密切的模块应该组织成一个包,以便于维护和使用。这项技术能有效避免名字空间冲突。创建一个名字为包名字的文件夹并在该文件夹下创建一个__init__.py 文件就定义了一个包。你可以根据需要在该文件夹下存放资源文件、已编译扩展及子包。举例来说,一个包可能有以下结构:

Graphics/
      __init__.py
      Primitive/
         __init__.py
         lines.py
         fill.py
         text.py
         ...
      Graph2d/
         __init__.py
         plot2d.py
         ...
      Graph3d/
         __init__.py
         plot3d.py
         ...
      Formats/
         __init__.py
         gif.py
         png.py
         tiff.py
         jpeg.py

import语句使用以下几种方式导入包中的模块: 
* import Graphics.Primitive.fill 导入模块Graphics.Primitive.fill,只能以全名访问模块属性,例如Graphics.Primitive.fill.floodfill(img,x,y,color). 
* from Graphics.Primitive import fill 导入模块fill ,只能以 fill.属性名这种方式访问模块属性,例如fill.floodfill(img,x,y,color). 
* from Graphics.Primitive.fill import floodfill 导入模块fill ,并将函数floodfill放入当前名称空间,直接访问被导入的属性,例如 floodfill(img,x,y,color).

无论一个包的哪个部分被导入, 在文件__init__.py中的代码都会运行.这个文件的内容允许为空,不过通常情况下它用来存放包的初始化代码。导入过程遇到的所有 __init__.py文件都被运行.因此 import Graphics.Primitive.fill 语句会顺序运行 Graphics 和 Primitive 文件夹下的__init__.py文件.

下边这个语句具有歧义: 
from Graphics.Primitive import * 
这个语句的原意图是想将Graphics.Primitive包下的所有模块导入到当前的名称空间.然而,由于不同平台间文件名规则不同(比如大小写敏感问题), Python不能正确判定哪些模块要被导入.这个语句只会顺序运行 Graphics 和Primitive 文件夹下的__init__.py文件. 要解决这个问题,应该在Primitive文件夹下面的__init__.py中定义一个名字all的列表,例如: 
# Graphics/Primitive/__init__.py
__all__ = ["lines","text","fill",...]

这样,上边的语句就可以导入列表中所有模块.

下面这个语句只会执行Graphics目录下的__init__.py文件,而不会导入任何模块: 
import Graphics
Graphics.Primitive.fill.floodfill(img,x,y,color)  # 失败!

不过既然 import Graphics 语句会运行 Graphics 目录下的 __init__..py文件,我们就可以采取下面的手段来解决这个问题: 
# Graphics/__init__.py
import Primitive, Graph2d, Graph3d

# Graphics/Primitive/__init__.py
import lines, fill, text, ...

这样import Graphics语句就可以导入所有的子模块(只能用全名来访问这些模块的属性).

refer to:http://blog.csdn.net/appleheshuang/article/details/7602499

python模块与包加载机制的更多相关文章

  1. Python模块的动态加载机制

    Python在运行环境初始化中,就将sys module加载到了内存中, 实际上,Python是将一大批的module加载到了内存中.但是为了使local名字空间能够达到最干净的效果,Python并没 ...

  2. 基于python的opcode优化和模块按需加载机制研究(学习与个人思路)(原创)

    基于python的opcode优化和模块按需加载机制研究(学习与思考) 姓名:XXX 学校信息:XXX 主用编程语言:python3.5 个人技术博客:http://www.cnblogs.com/M ...

  3. node.js的包加载机制

    加载一个模块 require('moduleName'); 现在核心模块中加载,如果核心模块中没有,那么就去node_modules目录下去找,核心模块的优先级最高. 如果加载模块式省略了文件的后缀名 ...

  4. nodejs 模块以及加载机制,主要讨论找不到模块的问题

    最主要的一个思想,加载模块无非就是找到模块在哪,只要清楚了模块的位置以及模块加载的逻辑那么找不到模块的问题就迎刃而解了.本文只是综合了自己所学的知识点进行总结,难免出现理解错误的地方,请见谅. nod ...

  5. Skywalking-13:Skywalking模块加载机制

    模块加载机制 基本概述 Module 是 Skywalking 在 OAP 提供的一种管理功能特性的机制.通过 Module 机制,可以方便的定义模块,并且可以提供多种实现,在配置文件中任意选择实现. ...

  6. 【前端】CommonJS的模块加载机制

    CommonJS的模块加载机制 CommonJS模块的加载机制是,输入的是被输出的值的拷贝.也就是说,一旦输出一个值,模块内部的变化就影响不到这个值. 例如: // lib.js var counte ...

  7. Dojo初探之1:AMD规范,编写符合AMD规范(异步模块加载机制)的模块化JS(其中dojo采用1.11.2版本)

    一.AMD规范探索 1.AMD规范(即异步模块加载机制) 我们在接触js的时候,一般都是通过各种function来定义一些方法,让它们帮我们做一些事情,一个js可以包含很多个js,而这些functio ...

  8. webpack4下import()模块按需加载,打包按需切割模块,减少包体积,加快首页请求速度

    一:背景 因为项目功能越加越多,打包后的体积越来越大,导致首页展示的时候速度比较慢,因为要等压缩的js的包加载完毕. 首页展示的时候只需要对应的js,并不需要全部的js模块,所以这里就可以用按需加载, ...

  9. nodejs(13)模块加载机制

    模块加载机制 优先从缓存中加载 当一个模块初次被 require 的时候,会执行模块中的代码,当第二次加载相同模块的时候,会优先从缓存中查找,看有没有这样的一个模块! 好处:提高模块的加载速度:不需要 ...

随机推荐

  1. 利用AWS简单存储服务(S3)托管网站

    1.首先建立Storage Bucket存储桶,名为网站域名: 2.在[属性]中选择启用网站托管或重定向到另一主机,即可. 3.官方参考文档:https://docs.aws.amazon.com/z ...

  2. JS获取URL的参数

    function request(paras) { var url = location.href; , url.length).split("&"); var paraO ...

  3. 第二篇:web之前端之css

    前端之css   前端之css 本节内容 css概述及引入 css选择器 css常用属性 1.css概述及引入 CSS概述 CSS是Cascading Style Sheets的简称,中文称为层叠样式 ...

  4. asp.net pagebase获取缓存的方法

    public string GetSysConfigByKey(string key) { if (object.Equals(HttpContext.Current.Cache["Cach ...

  5. ubuntu14.04使用wubi安装出错

    使用wubi安装后,进入系统是总是提示/分区加载异常,无法正常进入系统. 参考解决方案来自 http://jingyan.baidu.com/article/0aa22375bbffbe88cc0d6 ...

  6. LINQ数据库连接对象制造工厂

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  7. 如何在PSD中准确切出图片

    步骤如下: 1.Ctrl+alt+鼠标滚轮 放大图片,按住H键拖动图片选取位置: 2.选择“移动工具” (勾选“自动选择”,“图层”): 3.选中后,选择图层,右击,选择“转换为智能对象”: 4.使用 ...

  8. 问题:Bringing up interface eth0: Device eth0 does not seem to be present,delaying initialization. [FAILED]—— 找不到网卡。

    克隆虚拟机的时候或其他情况出现以下问题(命令service network restart):   Bringing up interface eth0:  Device eth0 does not ...

  9. juquery验证插件validation addMethod方法使用笔记

    该方法有三个api接口参数,name,method,messages addMethod(name,method,message)方法 参数 name 是添加的方法的名字. 参数 method 是一个 ...

  10. Git版本控制工具使用:Error pulling origin: error: Your local changes to the following files would be overwritten by merge

    摘自: CSDN 逆觞 git在pull时,出现这种错误的时候,可能很多人进进行stash,相关stash的请看:Error pulling origin: error: Your local cha ...