python模块与包加载机制

模块的搜索路径:

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

时间: 2024-08-29 18:55:24

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

《python解释器源码剖析》第15章--python模块的动态加载机制

15.0 序 在之前的章节中,我们考察的东西都是局限在一个模块(在python中就是module)内.然而现实中,程序不可能只有一个模块,更多情况下一个程序会有多个模块,而模块之间存在着引用和交互,这些引用和交互也是程序的一个重要的组成部分.本章剖析的就是在python中,一个模块是如何加载.并引用另一个模块的功能的.对于一个模块,肯定要先从硬盘加载到内存. 15.1 import前奏曲 我们以一个简单的import为序幕 # a.py import sys 1 0 LOAD_CONST 0 (

UE4 Pak资源包加载

UE4 Pak包加载机制: 引擎初始化时,默认会去下面的目录搜索所有的*.pak文件, [Demo]/Content/Paks/" [Demo]/Saved/Paks/" Engine/Content/Paks/" 然后解析找到的所有的pak资源包,建立文件索引, 这样当游戏中需要某个文件的数据时,就可以找到这个文件属于哪个pak文件了

Python模块动态加载机制

本文和大家分享的主要是python中模块动态加载机制相关内容,一起来看看吧,希望对大家学习python有所帮助. import 指令 来看看 import sys 所产生的指令: co_consts : (0, None) co_names : ('sys',) 0 LOAD_CONST               0 (0) 2 LOAD_CONST               1 (None) 4 IMPORT_NAME              0 (sys) 6 STORE_NAME  

模块加载机制与包的加载机制

模块加载机制 包是更好的组织功能的代码结构 当前指定一个文件夹,会将文件夹内的index.js作为程序的入口    3 如果当前目录下有一个和文件夹同名的文件,优先加载文件        1 如果当前目录下有一个和文件夹同名的json文件,优先加载json  2 对于文件的加载,顺序是,如果你写上./xxx,优先会加载xxx.js/xxx.json/xxx.node 加载优先级,例如: ./abc 1:先检查当前目录下./abc目录中的package.json文件的main属性,满足就立刻加载

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

最主要的一个思想,加载模块无非就是找到模块在哪,只要清楚了模块的位置以及模块加载的逻辑那么找不到模块的问题就迎刃而解了.本文只是综合了自己所学的知识点进行总结,难免出现理解错误的地方,请见谅. nodejs的模块分类 1.原生模块:http  fs path等,这些模块都在源码包的lib目录下面,nodejs安装好之后是找不到这些模块的,都作为node.exe的一部分了,require这些模块永远没问题的,如果哪天出现问题了,直接重启电脑或者重装node.有什么疑问可以通过下载源码对这些原生模块

Python/模块与包之包

Python/模块与包之包 1. 包是一种通过使用模块名 来组织Python模块名称空间的方式,一个类似于目录并存有__init__.py文件的被称为包 包的本质就是一个包含__init__.py文件的目录.包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法 包 通常包总是一个目录,可以使用import导入包,或者from + i

Python/模块与包之模块

Python/模块与包之模块 1.什么是模块? 模块就是py文件 2.为什么要用模块? 如果在解释器上进行编码,把解释器关闭之前写的文件就不存在了,如果使用模块的话就能永久保存在磁盘中. 3.如何使用模块? 3.1 import    通过import导入要使用的模块 1 #spam.py 2 print('from the spam.py') 3 4 money=1000 5 6 def read1(): 7 print('spam->read1->money',1000) 8 9 def

Android apk动态加载机制的研究(二):资源加载和activity生命周期管理

出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 为了更好地阅读本文,你需要先阅读Android apk动态加载机制的研究这篇文章,在此文中,博主分析了Android中apk的动态加载机制,并在文章的最后指出需要解决的两个复杂问题:资源的访问和activity生命周期的管理,而本文将会分析这两个复杂问题的解决方法.需要说明的一点是,我们不可能调起任何一个未安装的

第八篇 Python 模块与包

一.模块介绍 什么是模块? 常见的场景:一个模块就是一个包含了一组功能的Python文件,比如spam.py,模块名为spam,可以通过import spam使用. 在Python中,模块的使用方式都是一样的,但其实细说的,模块可以分为四个通过类别: 1.使用Python编写的.py文件 2.已被编译为共享库或DLL的C或C++扩展 3.把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包) 4.使用C编写并链接到Python解释器的内置模块 为何要使用