模块
- 一个python文件,以
.py
结尾,包含了对象定义和可执行语句- 模块能定义函数,类和变量,模块里也能包含可执行的代码
- 更有逻辑和层次地组织
python
代码 - 相关的代码进行单独的组织会使代码更容易理解并被复用
- 模块的模块名(字符串)可以由全局变量
__name__
得到 - python
module.py
时,其__name__
被设置 为”__main__
“
import
语句
import
语句应该放在模块的初始位置- 当解释器遇到
import
语句时,如果模块在当前的搜索路径就会被导入- 搜索路径为当前目录或存储在
sys.path
的路径- 首先在当前目录进行搜索
sys.path.append()
- 搜索路径为当前目录或存储在
- 可通过模块名称来访问模块成员
- 如果频繁使用一个函数,则可以将之赋给本地变量
sf = sys.f
- 模块在解释器会话中只导入一次
- 如果更新,需要重启解释器或者重新加载
import imp imp.reload(modulename) #交互式情况下可能会用到
from ... import
语句
- 从模块导入指定的部分到当前的命名空间
- 既可以是子模块(甚至子包),也可以是函数、 类或变量等
from ... import *
- 导入所有部分
- 除下划线( _ )开头的命名
- 不建议过多使用(低效繁杂)
可执行语句
- 模块可以包含可执行语句
- 这些语句一般用来初始化模块,其仅在第一次被导入的地方执行一次
- 如
jieba
导入时的打印信息
全局变量
- 模块私有符号表,并被模块内所有的函数作为 全局符号表使用
- 模块内部可以使用全局变量,而无需担心与其他模块全局变量冲突
- 可通过模块访问其全局变量
modname.itemname
模块加载
加速
- 在
__pycache__
目录下以module.version.pyc
名字缓存模块编译后的版本 - 编译后的模块是跨平台的
- 解释器会检查源文件与编译版本的修改日期以 确定是否过期并需要重新编译
- 如果没有源文件则不会检查缓存
- 若支持没有源文件(只有编译版)的程序发布, 则编译后的模块必须在源目录下且不包含源文 件
优化
- 为了减少编译模块的大小,可在Python命令 行中使用
-O
或者-OO
“优化”-O
参数删除了断言语句-OO
参数删除了断言语句和__doc__
字符串
- 缓存文件名会发生变化
- 包括
opt
等优化标记
- 包括
- 仅在确定无误的场合使用这一选项
- 并非加速代码的执行速度
- 程序逻辑可能依赖
__doc__
等
compileall
为指定目录的所有模块创建缓存python -m compileall
目录
dir()
函数
- dir()
- 按模块名搜索模块定义并返回一个字符串类型的命名列表
- 无参数调用时,dir()函数返回当前模块定义的命名
包
包
- 模块集,结构化的模块命名空间
- 圆点.
- A.B的模块表示了名为A的包中名为B的子模块
- 避免模块之间的命名冲突
- 通过分层的文件体系来组织
- 为了让Python将目录当做内容包,必须包含
__init__.py
文件 - 一般空白即可
- 可以执行包的初始化代码
__all__
变量
- 为了让Python将目录当做内容包,必须包含
包的导入
– 可只导入包里的特定模块 import a.b.c 通过完整的名称来引用 a.b.c.fun() from a.b import c c.fun() from a.b.c import fun fun()
from package import *
- 如果包中的
__init__.py
代码定义了一个名 为__all__
的列表,就会按照列表中给出的模 块名进行导入 - 如果没有定义
__all__
,则不会导入所有子模块
- 如果包中的
包内引用
from module import name
来显式地从相对位置导入- 用点号标明关联导入当前和上级包
from . import b
当前目录from .. import d
上一级目录from ... import e
命名空间
三种类型
- 内置名称(built-in names)
- Python语言内置的名称,比如函数名abs和异常名 称Exception等
- 全局名称(global names)
- 模块中定义的名称,如函数、类、其它导入的模块、模块级的变量和常量等
- 局部名称(local names)
- 函数中定义的名称,如函数的参数和局部变量等, 或类中定义的函数及变量等
- 查找顺序
- 局部的命名空间->全局命名空间->内置命名空间
命名空间的生命周期
- 命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束
- Python 中只有模块、类和函数才会引入新的作用域,其它的代码块(如
if/elif/else/、try/except、for/while
等)并不会引入新的作用域- 在这些语句内定义的变量,在代码块外也可访问
- 与c语言是否一样?
四种作用域
- L(Local)
- 最内层,包含局部变量,比如一个函数或方法内部
- E(Enclosing)
- 包含了非局部(non-local)也非全局(non-global)的变量, 比如嵌套函数等,一个函数A 中包含了另一个函数B,那么对 于B,A中的作用域就为 nonlocal
- G(Global)
- 当前模块的最外层,比如当前模块的全局变量
- B(Built-in)
- 包含了内建的变量/关键字等
- 搜索规则顺序
- L –> E –> G –>B
虚拟环境和包
虚拟环境
- Python应用程序经常会使用一些不属于标准库的包和模块,或者应用程序有时候需要某个特定版本的库
- 导致无法安装一个Python来满足每个应用程 序的要求
- 创建一个虚拟环境(通常简称为 “virtualenv”),包含一个特定版本的 Python,以及一些附加的包的独立的目录树
pyvenv
- 指定安装一个特定的版本的Python
- 或选择一个指定的Python版本 –pyvenv 虚拟环境目录
pyvenv
目录- 会创建一个目录,并且也在目录里面创建一个包含Python解释器,标准库,以及各种配套文件的 Python “副本”
- 激活环境
- win: Scripts/activate
- linux/unix: source /bin/activate
- 激活虚拟环境会改变shell提示符,显示正在使用的虚拟环境
- 可以使用pip进行对应版本的包管理
输入输出
format
函数
- 通过位置
- 通过关键字参数
print('a1 = {} a2= {} a3= {}'.format('first','second','third')) print('a1 = {1} a2= {0} a3= {2}'.format('first','second','third')) print('your name is {name} , age is {age}'.format(age=87,name='jack’)) ------------------ a1 = first a2= second a3= third a1 = second a2= first a3= third your name is jack , age is 87
- 通过对象属性
class Person(object): address = '中国' # 类属性,没个实例的公共属性 def __init__(self, name, sex, age): # 相当于java中的构造方法 self.name = name # 实例属性 self.sex = sex # 实例属性 self.age = age # 实例属性 p = Person('Steve', 'M', 21) print('name = {p.name} age = {p.age}'.format(p=p)) -------------------- name = Steve age = 21
dt = {'k1': 1, 'k2': 2, 'k3': 3} print('k1: {0[k1]:d}; k2: {0[k2]:d}; k3: {0[k3]:d}'.format(dt)) print('k1: {k1:d}; k2: {k2:d}; k3: {k3:d}'.format(**dt)) --------------------- k1: 1; k2: 2; k3: 3 k1: 1; k2: 2; k3: 3
- 通过下标
print('{0[1]} {0[2]} {1[2]} {1[0]}'.format(s1,s2))
格式化输出
- 对齐与填充
print('{0:10} ==> {1:10d}'.format(name, number))
- 浮点小数输出
print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
- 进制及其他显示
b
: 二进制d
:十进制o
:八进制x
:十六进制!s
:将对象格式化转换成字符串!a
:将对象格式化转换成ASCII
print(’{!a}’.format(‘天津tianjin’))
!r
:将对象格式化转换成repr
序列化与反序列化
- 序列化(serialization):将程序中的对象保存到文件中以永久存储
- 反序列化(deserialization):从文件中创建上一次程序保存的对象
pickle
import pickle #文件 pickle.dump(obj, file[, protocol]) pickle.load(file) #字符串 pickle.dumps(obj[, protocol]) pickle.loads(string)
json
import json #文件 json.dump(f) json.load(f) – #字符串 json.dumps() – json.loads()
文件操作
os
模块- 目录遍历
- 文件是否存在
shutil
模块- 文件移动
- 文件删除
- 文件复制
zipfile
模块- 压缩文件读取或存储
class person(object): address = '中国' # 类属性,没个实例的公共属性 def __init__(self, name, sex, age): # 相当于java中的构造方法 self.name = name # 实例属性 self.sex = sex # 实例属性 self.age = age # 实例属性 def dance(self): # 方法 print(self.name, '跳了一场舞') hong = person('小红', '女', 18) # 实例化小红,将实例化的对象赋值给变量hong ming = person('小明', '男', 26) hua = person('小花', '女', 22)