您的位置:首页 > 编程语言 > Python开发

Python基础——模块

2017-01-12 21:35 393 查看
模块建立

模块导入
导入步骤
搜索

编译

运行

导入语句
import语句

from语句

包概念
包的定义

包的导入
包外导入

包内导入

针对模块对象的操作

python中不得不提到模块的概念。稍微对python有些了解的话,肯定会遇到import语句,这就是模块导入语句。python中的模块包含标准库模块、第三方模块、自定义模块。标准模块是python安装时自带的模块,大概有200多种,比如ossys等;第三方模块虽然没有封装到python安装包中,但是一般也是经过各种考验的,比如强大的数值计算工具numpy、绘图工具matplotlib等;自定义模块是用户在实现大规模应用时,编写的用于不同目的的脚本文件。

模块建立

建立模块,就是编写.py文件。这里需要注意的一点是,模块名在python程序中会变为变量名,应该遵守变量名规则。

模块导入

导入步骤

python 在运行顶层脚本文件时,按顺序一条条执行语句,当碰到导入语句时,按步骤执行以下步骤。

搜索

首先是根据模块名搜索对应的文件,文件扩展名可以是.py,.pyc等。比如
import b
可能会加载:

b.py

b.pyc

目录b(包)

编译扩展模块

ZIP文件



python的模块搜索路径以字符串的形式保存在列表sys.path中,并且按顺序进行搜索:

>>> import sys
>>>sys.path
['', 'C:\\WINDOWS\\SYSTEM32\\python27.zip', 'C:\\Python27\\DLLs', 'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk', 'C:\\Python27', 'C:\\Python27\\lib\\site-packages']


sys.path按顺序存储以下的路径:

当前工作目录

在交互模式提示符下,是运行python的目录,打印出来为空字符串”“;而如果以脚本文件运行,那么当前工作目录是顶层脚本文件所在的目录,打印的字符串为该文件所在目录的绝对路径。

PYTHONPATH环境变量

可以设置Windows或者Ubuntu系统的环境变量,增加环境变量PYTHONPATH,并追加用户想要添加的模块搜索路径。

标准库目录

这个是python标准库模块安装时的目录。

特殊目录下的.pth文件

这种方式目前没有接触过,暂不做说明。

需要记住的是,用户可以通过三种方式修改python的模块搜索路径:修改PYTHONPATH、.pth文件或者在程序中修改sys.path。

编译

当导入模块的时候,如果检测目标源文件到没有对应的.pyc字节码文件或者该.pyc文件的时间戳比源文件旧,那么会首先编译生成.pyc文件;如果有.pyc文件,那么直接跳过编译步骤。

运行

在首次导入模块的时候,会按顺序执行该模块中的每条语句,把所有顶层的赋值语句(不是嵌套在def、class中的赋值语句)产生的变量作为该模块的属性,包括简单变量、函数、类。

注意,只有在首次导入模块的时候,上面的步骤才会执行,再次以导入语句导入时,只是从内存中提取已加载的模块对象而已。python是如何判断是否为首次导入模块呢?答案是sys.modules。python会把已经载入的模块添加到列表sys.modules中,当碰到载入语句的时候首先检查这个列表。

如果想要重新载入该模块,可以用内建函数reload(module),而且此语句会影响之前的import语句,但不会影响之前的from语句赋值的变量。下面给出一个例子解释这句话:

文件a.py

print 'module a'
x = 1
y = [2, 3, 4]


文件b.py

from a import x, y
x = 2 #不会修改模块a中的x
y = [-1, 2, 3] #会修改模块a中的y
import a
a.x = 2 #会修改模块a中的x
reload(a)
print x, y
print a.x


执行b.py的结果如下:

module a    #这是from语句时运行模块的结果
module a    #这是reload函数重载模块时,对模块的运行
1 [2, 3, 4] #显然reload语句并没有改变from语句赋值的变量
1       #a.x重新变为1


导入语句

import语句

import module #module有两个使命,一个是用于搜索模块文件,一个是作为引用加载的模块对象的变量名


import语句会把整个模块对象赋值给一个变量:执行搜索到的模块文件,生成模块对象,并把模块对象赋值给变量名module。这样对于模块中的所有属性,可以通过.操作符读取。

只有必须使用两个模块中有相同变量名的属性时,才必须要使用import语句。

from语句

from module import value1, value2


from语句相当于执行以下的语句:

improt module
value1 = module.value1
value2 = module.value2
del module


from虽然只复制了模块中的部分变量,但是仍然需要把整个模块加载到内存,只加载模块的一部分是不可能的。

from module import *

from语句还提供了from *这种语法。from *把模块对象的所有属性全部复制到本地。

如果想要对这个导入语句隐藏一些属性,可以在模块内采用X的变量名引用属性,或者在模块顶层定义__all_列表,明确指出from*会导入的属性。后者优先。

包概念

包的定义

前面提到导入的模块可以是目录,这里就用到了包。如果某个目录中包含__init__.py文件,那么这个目录可以称作包,可以直接导入该目录;并且可以以点操作符导入该目录下的包或者模块文件。

python在首次遇到某个目录的时候(import backage.module也算)会自动执行该目录下的__init__.py文件。__init__.py文件中的赋值语句创建的变量名会作为包模块对象的属性。另外,在__init__.py中使用 __all__列表来存储包导入语句所导入的子模块,如果不指定__all__,那么不会自动载入嵌套在包中的子模块作为包属性,只会载入__init__.py中赋值的变量名。

总之,可以把包看作特殊的模块,属性对应着__init__.py文件中生成的变量。

包的导入

导入语句会在首次遇到某个目录时执行该目录的初始化文件。路径中的每个目录名都会变成赋值了模块对象的变量,而模块对象的命名空间有初始化文件中所有的赋值语句指定。

包外导入

import b1.b2.module
import b1


包内导入

包内导入时涉及到相对或者绝对导入。首先引入包内导入中的新的导入语法:

from . import value #当前目录(包)的value属性
from .spam import value #当前目录(包)下的spam模块
from .. import value #上一级目录下


这个导入语句对于python2和python3都只查找相对路径。而对于常规的导入语句,python2.*先搜索相对路径,然后搜索模块搜索路径(绝对路径);python3的常规导入语句会直接搜索绝对路径。

针对模块对象的操作

读取模块对象的命名空间(其实就是包含的值属性以及方法属性):

内建函数dir()

__dict__属性:以模块对象包含的属性名为键

以下是取模块的某一属性的方式:

M.name

M.__dict__[‘name’]

sys.modules[‘M’].name

getattr(M, ‘name’)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: