Python
Python
目录
模块系统(封装)
简概
简概
- 简概
- 模块是包括 Python 定义和声明的文件
- 文件名就是模块名加上
.py
后缀
- 模块的类别
- 可以是函数库、常量库、也可以是类库,导入方法都是一样的
交互式测试重新加载问题
出于性能考虑,每个模块在每个解释器会话中只导入一遍
- 因此,如果你修改了你的模块,需要重启解释器;
- 或者,如果你就是想交互式的测试这么一个模块,可以用 imp.reload() 重新加载
- 例如
import imp; imp.reload(modulename)
- 例如
自定义模块
基本流程、设计与使用
- 基本流程
- 保存文件
a.py
- 同目录下
import fibo
- 保存文件
- 设计
- 可以注明
文档字符串
和函数注解
,以方便他人使用该模块 - 具体设置方法详见 “编写习惯” 一章
- 可以注明
- 使用
使用
模块文件可以包括方法、变量、类
- 导入模块的三种方式(以导入类为例)
- 方式一(导入模块中指定的类或函数)
- 导入:
from car import Car, ElectricCar
- 调用:
my_car = Car(...)
- 好处:只要查看文件开头的import语句,就能清楚知道程序使用了哪些类
- 导入:
- 方式二(导入模块的所有类和函数)
- 导入:
from car import *
- 调用:
my_car = Car(...)
(不推荐) - 缺点:可能会引发类名重复
- 导入:
- 方式三(导入模块)
- 导入:
import car
- 调用:
my_car = car.Car(...)
- 扩展:如果打算频繁使用一个函数,可以将它赋予一个本地变量,如
fn = a_module.fn; fn(...)
- 导入:
- 方式一(导入模块中指定的类或函数)
_
私有变量
以下划线(_
)开头命名的方法或函数为模块私有的
一般*
会导入所有除了以下划线开头的命名
模块的搜索路径
导入一个叫
spam
的模块时,解释器先在当前目录中搜索名为spam.py
的文件如果没有找到的话,接着会到 sys.path 变量中给出的目录列表中查找。 sys.path 变量的初始值来自如下:
输入脚本的目录(当前目录)
环境变量 PYTHONPATH 表示的目录列表中搜索
(这和 shell 变量
PATH
具有一样的语法,即一系列目录名的列表)Python 默认安装路径中搜索
自定义包
简概
包也叫模块集(与java的包的概念类似)
- 作用:封装化结构化,以及避免全局变量之间的相互冲突
- 使用简概:包通常是使用用
圆点模块名
的结构化模块命名空间- 例如,名为
A.B
的模块表示了名为A
的包中名为B
的子模块
- 例如,名为
使用
导入包/模块的方式
方式一(用户可以每次只导入包里的特定模块)
- 导入:
import sound.effects.echo
- 使用:
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
- 导入:
方式二(加载子模块)
- 导入:
from sound.effects import echo
- 使用:
echo.echofilter(input, output, delay=0.7, atten=4)
- 导入:
方式三(直接导入函数或变量)
- 导入:
from sound.effects.echo import echofilter
- 使用:
echofilter(input, output, delay=0.7, atten=4)
- 导入:
方式四(从*导入)
导入:
from sound.effects import *
(导入包的所有子模块或根据__init__.py
中定义的列表进行导入)__init__
:代码举例:__all__ = ["echo", "surround", "reverse"]
由于init机制,有时会混着使用,如下:
import sound.effects.echo import sound.effects.surround from sound.effects import *
包内引用
作用:可以按绝对位置从相邻的包中引入子模块
方法
例如:如果
sound.filters.vocoder
包需要使用sound.effects
包中的echo
模块它可以
from sound.Effects import echo
也可以
from ..filters import equalizer
(类似这种写法)
多重目录中的包(不懂)
包支持一个更为特殊的特性, __path__
在包的 __init__.py
文件代码执行之前,该变量初始化一个目录名列表。该变量可以修改,它作用于包中的子包和模块的搜索功能
这个功能可以用于扩展包中的模块集,不过它不常用
模块补充、与main文件
__name__
的使用
- 简概
- 模块的模块名(做为一个字符串)可以由全局变量
__name__
得到
- 模块的模块名(做为一个字符串)可以由全局变量
- 使用
- 如
import fibo
、fibo.__name__
的值为'fibo'
- 如
“main”文件与模块
- 当当前文件以主函数开始运行时,
__name__
会被设置为__main__
- 可以用
if __name__=='__main__':
判断当前模块是否主运行文件 - 此代码只有在模块作为 “main” 文件执行时才被调用
模块使用相对路径
模块使用相对路径时,是根据main文件的路径去找的相对路径。即若模块与main文件不在同一目录时,以main文件的为准
这可能会引发一些问题:如果想要找模块的相对路径,则需要先把模块路径转为绝对路径,再取找相对路径
模块的 “编译”
简概
为了加快加载模块的速度,Python 会在
__pycache__
目录下以module.*version*.pyc
名字缓存每个模块编译后的版本版本号补充
- 这里的版本编制了编译后文件的格式。它通常会包含 Python 的版本号
- 例如,在 CPython 3.3 版中,spam.py 编译后的版本将缓存为
__pycache__/spam.cpython-33.pyc
- 这种命名约定允许由不同发布和不同版本的 Python 编译的模块同时存在
部分高级技巧(不太懂)
为了减少一个编译模块的大小,你可以在 Python 命令行中使用 -O 或者 -OO。-O 参数删除了断言语句,-OO 参数删除了断言语句和 doc 字符串。
因为某些程序依赖于这些变量的可用性,你应该只在确定无误的场合使用这一选项。“优化的” 模块有一个 .pyo 后缀而不是 .pyc 后缀。未来的版本可能会改变优化的效果。
来自
.pyc
文件或.pyo
文件中的程序不会比来自.py
文件的运行更快;.pyc
或.pyo
文件只是在它们加载的时候更快一些。compileall 模块可以为指定目录中的所有模块创建
.pyc
文件(或者使用 -O 参数创建.pyo
文件)。在 PEP 3147 中有很多关这一部分内容的细节,并且包含了一个决策流程。
常用模块(常用库)
Python的模块系统由三大部分组成
内置模块 / 标准库模块(不用下载,不用显式导入)
string模块
文件输入/输出
- demo
f = open("vuln_banners.txt",'r')
for line in f.readlines():
if line.strip('\n') in list:
pass
标准模块 / 标准模块库(不用下载,要显式导入)
sys模块
作用:能访问到由Python解释器使用或维护的对象,其中包括:
- 标志、版本、整型数最大尺寸、可用的模块、hook路径、标准错误/输入/输出的位置、调用解释器的命令行参数
模块文档:http://docs.python.org/library/sys
具体用法
sys.ps1
:在交互模式下,sys.ps1
和sys.ps2
分别定义了主提示符'>>> '
和辅助提示符'... '
sys.path
:是解释器搜索模块路径的字符串列表- 它由环境变量 PYTHONPATH 初始化
- 如果没有设定 PYTHONPATH ,就由内置的默认值初始化
- 你可以用标准的字符串操作修改它:例如
sys.path.append('/ufs/guido/lib/python')
sys.argv
:$ python vuln-scanner.py vuln-banners.txt
调用python时:import sys if len(sys.argv)==2: # python启动的参数 filename = sys.argv[1] # 第二个启动的参数
os模块
- 作用:提供了丰富的适用于各种操作系统的函数,可以交互的对象:
- 操作系统环境、文件系统、用户数据、权限
- demo
import os
# ...
if not os.path.isfile(filename): # 没有该文件
pass
if not os.access(filename, os.R_OK): # 没有权限访问该文件
pass
socket模块(网络模块)
- demo
import socket
socket.setdefaulttimeout(2) # 设置超时
s = socket.socket() # 创建实例
s.connect(("192.168.95.148",21)) # 连接指定ip和端口
ans = s.recv(1024) # 读取接下来1KB数据
print ans # 打印
OrderedDict类(有序字典)
- 载入:
from collections import OrderedDict