Python基础——模块

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’)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值