1. 模块
1.1 概念
- 每一个以扩展名
.py
结尾的 Python
源代码文件都是一个模块; - 模块名同样也是一个标识符,需要符合标识符的命名规则;
- 在模块中定义的全局变量, 函数, 类都是提供给外界直接使用的工具;
1.2 模块的两种导入方式
import
导入 from...import
导入
# 示例: import 导入import 模块名1import 模块名2# 备注: 如果模块的名字太长,可以使用as指定模块的名称,以方便在代码中的使用import 模块名1 as 模块别名(模块别名应该符合大驼峰命名法)# 示例二: from ... import# 如果希望从某一个模块中,导入部分工具,就可以使用 from ... import 的方式from 模块名1 import 工具名# 导入之后,不需要通过 模块名.# 可以直接使用模块提供的工具(即全局变量,函数, 类)# 如果两个模块,存在同名的函数,那么后导入模块的函数,会覆盖掉先导入的函数;
1.3 import
的搜索路径
# import 搜索路径# ipython3 中输入import syssys.path # 查看 import 依次查找要导入的模块文件的路径# 添加自定义路径sys.path.append('/Documents/python/xxxx')sys.path.insert(0, '/Documents/python/xxx') # 可以确保先搜索这个路径# 重新导入模块from imp import *reload(需要重新导入的模块)
1.4 循环导入
# 示例# a.pyfrom b import bprint('===========this is module a.py============')def a(): print("hello, a") b()a()# b.pyfrom a import aprint('===========this is module b.py============')def b(): print("hello, b")def c(): a()c()
1.5 开发原则
__name__
属性:测试模块的代码只在测试情况下被运行,而在被导入时,不会被执行! __name__
记录着一个字符串: - 被导入到其他文件内部后,
__name__
就是当前模块名; - 在当前执行的程序内部,
__name__
是 __main__
;
# 示例: 代码格式# 1. 导入模块# 2. 定义全局变量# 3. 定义类# 4. 定义函数# 5. 测试代码# 在代码的最下方def main(): # 编写测试代码 pass# 根据 __name__ 的值,判断是否执行下方代码if __name__ = "__main__": main()
1.6 包(Package)
- 包就是一个包含多个模块的特殊目录;
- 目录下,有一个特殊的文件
__init__.py
; - 包的命名方式和变量名一致;
- 使用
import 包名
可以一次性导入包中所有的模块,也就是先执行__init__.py
文件的内容; __init__.py
中需要指定对外界提供的模块列表;
# 示例:# 从 当前目录 导入 模块列表from . import 模块1from . import 模块2
1.7 发布模块
# 具体步骤(三步):# 1) 创建 setup.pyfrom distutils.core import setupsetup(name="xxx_message", # 包名 version="1.0", # 版本 description="消息模块", # 描述信息 long_description="详细的描述信息", # 完整描述信息 author="noodles", # 作者 author_email="isliuxian@163.com", # 作者邮箱 url="www.google.com", # 主页 py_modulse=["模块1", "模块2"])# 2) 构建模块$ python3 setup.py build# 3) 生成发布压缩包$ python3 setup.py sdist
1.8 安装模块
模块(包).__file__
: 可以查看模块(包)的完整路径;
# 安装模块$ tar -zxvf 模块压缩包$ sudo python3 setup.py install# 卸载模块,直接从安装目录下删除$ cd /usr/local/lib/python3.5/dist-packages/$ sudo rm -r 包名
1.9 pip
安装第三方模块
pip
是一个现代的,通用的 Python
包管理工具; - 提供了对
Python
包的查找,下载,安装和卸载等功能;
# 将 pygame 模块安装到 python2.x 环境$ sudo pip install pygame$ sudo pip uninstall pygame# 将 pygame 模块安装到 Python 3.x 环境$ sudo pip3 install pygame$ sudo pip3 uninstall pygame# mac 下安装 iPython$ sudo pip install ipython # 针对 python2.x$ sudo pip3 install ipython # 针对 python3.x
2. 文件操作
2.1 操作文件的函数/方法
open
函数,负责打开文件,并且返回文件操作对象; read
方法,将文件内容读取到内存; write
方法,将指定内容写入文件; close
方法,关闭文件; - 以上三个方法均需要通过文件对象来调用;
2.2 read
方法--读取文件
open
函数的第一个参数就是要打开的文件名(文件名区分大小写) - 如果文件存在,返回文件操作对象;
- 如果文件不存在,会抛出异常;
read
方法可以一次性读入并返回文件的所有内容; close
方法负责关闭文件; - 如果忘记关闭文件,会造成系统资源消耗,而且会影响到后续对文件的访问;
# 示例:# 打开file = open("a.txt")# 读取text = file.read()print(text)# 关闭file.close()
2.3 文件指针
- 文件指针标记从哪个位置开始读取数据;
- 第一次打开文件时,通常文件指针会指向文件的开始位置;
- 当执行了
read
方法后,文件指针会移动到读取内容的末尾;
2.4 打开文件的方式
open
函数默认以只读方式打开文件,并且返回文件对象
f = open("文件名", "访问方式")# 访问方式说明:# r: 以只读方式打开文件;文件的指针将会放在文件的开头,这是默认模式;# w: 以只写方式打开文件,如果文件存在会被覆盖;如果文件不存在,创建新文件;# a: 以追加方式打开文件,如果该文件已经存在,文件指针将会放在文件的末尾; 如果文件不存在,创建新的文件进行写入;# r+: 以读写方式打开文件;文件的指针将会放在文件的开头;如果文件不存在,抛出异常;# w+: 以读写方式打开文件;如果文件存在会被覆盖;如果文件不存在,创建新文件;# a+: 以读写方式打开文件;如果该文件已经存在,文件指针将会放在文件的末尾; 如果文件不存在,创建新的文件进行写入;# 备注:频繁的移动文件指针,会影响文件的读写效率;开发中,更多的时候会以只读,只写的方式来操作文件;# a(append)
2.5 按行读取文件内容
readline
方法可以一次读取一行内容; - 方法执行后,会把文件指针移动到下一行,准备再次读取;
read
方法默认会把文件的所有内容一次性读取到内存。如果文件太大,对内存的占用会非常严重;
# 打开文件file = open("a.txt")while True: # 读取一行内容 text = file.readline() # 判断是否读到内容 if not text: break # 没读取一行的末尾已经有一个 '\n' print(text, end="")# 关闭文件file.close()# 示例: 文件复制# 1. 打开文件file_read = open("a.txt")file_write = open("b.txt", "w")# 2. 读 写while True: # 读取到一行内容 text = file_read.readline() # 判断是否读取到内容 if not text: break file_write.write(text)# 3. 关闭file_read.close()file_write.close()
3. 常用模块及其方法
3.1 time 模块
time()
: 获取当前时间,毫秒数; clock()
: 计算CPU执行的时间; localtime()
: 获取本地时间; strftime('%Y--%m--%d %H:%M:%S', time.localtime())
: 将时间格式化为字符串; striptime('2018--03--16 10:03:36', %Y--%m--%d %H:%M:%S)
: 将字符串时间转换成元组的形式; ctime(毫秒数)
:将毫秒值转换成具体的时间格式; mktime(具体日期)
: 将具体日期转换成毫秒值;
3.2 datetime 模块
datetime.datetime.now()
:获取当前时间;
3.3 random 模块
random()
: 获取 0~1 的随机数; randint(1, 6)
: 获取 1~6 的随机数(包括6); randrange(1, 5)
: 取 1~5 的随机数(不包括5); choice('this is a beatiful day')
: 从字符串中随机取一个值; choice(['234', '57', 5, [4, 6]])
: 从列表中随机取一个值; sample(['234', '57', 5, [4, 6]], 2)
: 从列表中随机取两个值;
3.4 os 模块
os
模块在与操作系统进行交互; os.getcwd()
: 获取当前工作目录, 即当前python脚本工作的目录路径; os.chdir('dirname')
: 改变当前脚本工作目录, 相当于 shell 下 cd
; os.curdir()
: 返回当前目录(current dir); os.pardir()
: 获取当前目录的父目录字符串名(parent dir); os.makedirs('dir2/dir3')
: 可生成多层递归目录; os.removedirs('dir1')
: 删除多级空目录; os.mkdir(目录名)
: 创建目录; os.rmdir(目录名)
: 删除单级空目录; os.listdir(目录名)
: 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式返回; os.remove(文件名)
: 删除一个文件; os.rename(源文件名, 目标文件名)
: 重命名; os.stat('path/filename')
: 获取文件/目录信息; os.sep
: 输出操作系统特定的路径分隔符, win下为 \\
, Linux 为 /
; os.linesep
: 输出当前平台使用的行终止符; win下为 \t\n
, Linux 为 \n
; os.pathsep
: 输出用于分割文件路径的字符串; os.name
: 输出字符串,指示当前使用的平台, win -> nt
, Linux -> posix
; os.system('bash command')
: 运行shell命令,直接显示; os.environ
: 获取系统环境变量; os.path.abspath(path)
: 返回规范化的绝对路径; os.path.split(path)
: 将 path 分割成目录和文件名的元组形式返回; os.path.dirname(path)
: 返回 path 的目录, 其实就是 os.path.split(path)
的第一个元素; os.path.basename(path)
: 返回 path 最后的文件名; 若path以/
或\
结尾,那么就会返回空值; os.path.exists(path)
: 如果path存在,返回True; 如果不存在,返回 False; os.path.isdir(文件路径)
: 判断是否是文件; os.path.join([path2, path3])
:将多个路径组合后,返回; os.path.getatime(path)
: 返回path所指向的文件或者目录的最后存取时间; os.path.getmtime(path)
: 返回path所指向的文件或者目录的最后修改时间;
3.5 sys 模块
sys
模块在与Python解释器进行交互; sys.argv
: 命令行参数List, 第一个元素是程序本身路径; sys.exit(n)
: 退出程序, 正常退出:exit(0)
; sys.version
: 获取Python解释程序的版本信息; sys.maxint
: 最大的Int值; sys.path
: 返回模块的搜索路径,初始化时,使用PYTHONPATH环境变量的值; sys.platform
: 返回操作系统平台名称; sys.stdout.write('please: ')
val = sys.stdin.readline()[:-1]
3.6 hashlib 模块
# 示例:import hashlibm = hashlib.md5()print(m) # 输出: # 'hello world' 是以 unicode 保存的, 需要编码为 utf8m.update('hello world'.encode('utf8'))print(m.hexdigest()) # 输出: 5eb63bbbe01eeed093cb22bb8f5acdc3# 备注: hex, 表示十六进制;s = hashlib.sha256()s.update('hello world'.encode('utf8'))print(s.hexdigest())
3.7 logging 模块
logging
模块提供了标准的日志接口,可以存储各种格式的日志; logging
日志可以分为: debug()
,info()
,warning()
,error()
和critical()
# 示例一:import logging# 日志配置logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='/tmp/test.log', filemode='w')logging.debug('debug message')logging.info('info message')logging.warning('hello error')logging.error('error message')logging.critical('critical message')# 示例二:# logging.getLogger([name])(返回一个logger对象, 如果没有指定名字,将返回root logger)import logginglogger = logging.getLogger()# 创建一个handler, 用于写入日志文件fh = logging.FileHandler('test.log')# 再创建一个handler, 用于输出到控制台ch = logging.StreamHandler()formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')fh.setFormatter(formatter)ch.setFormatter(formatter)logger.addHandler(fh)logger.addHandler(ch)logger.setLevel(logging.DEBUG) # 设置日志级别logger.debug('logger debug message')logger.info('logger info message')logger.warning('logger warning message')logger.error('logger error message')logger.critical('logger critical message')
3.8 ConfigParser 模块
- 用于生成和修改常见配置文档,Python 3.x 变更为
configparser
# 示例一:# 常见文档格式:ServerAliveInterval = 45Compression = yesCompressionLevel = 9ForwardX11 = yes[bitbucket.org]User = hg[topsecret.server.com]Port = 50022ForwardX11 = no# 使用 Python 生成上面的文档import configparserconfig = configparser.ConfigParser()config['DEFAULT'] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9'}config['bitbucket.org'] = {}config['bitbucket.org']['User'] = 'hg'config['topsecret.server.com'] = {}topsecret = config['topsecret.server.com']topsecret['Host Port'] = '50022'topsecret['ForwardX11'] = 'no'config['DEFAULT']['ForwardX11'] = 'yes'# 写入配置文件with open('example.ini', 'w') as configfile: config.write(configfile)# 示例二: 读取配置文件内容import configparserconfig = configparser.ConfigParser()# 读取配置文件config.read('example.ini')print(config.sections()) # 输出: ['bitbucket.org', 'topsecret.server.com']print(config.defaults()) # 输出: OrderedDict([()'compression', 'yes'), ])# 判断'bitbucket.org' in config # 输出: True# 获取某一个值config['bitbucket.org']['User'] # 输出: 'hg'# 删除某一个值config.remove_section('topsecret.server.com')config.write(open('example.ini', 'w'))# 修改某一个值config.set('bitbucket.org', 'user', 'alex')config.write(open('example.ini', 'w'))
3.9 re 模块(正则表达式模块)
- 正则表达式是一种小型的,高度专业化的编程语言,在Python中,通过re模块实现。
re.findall(匹配规则, 需要匹配的字符串, flags)
: 所有的结果都返回到一个列表里; re.search(匹配规则, 需要匹配的字符串, flags)
: 返回返回匹配到的第一个对象(object),对象可以调用group()
来返回结果; re.match()
: 只从字符串的第一个字符开始匹配,返回匹配到的第一个对象(object); re.split()
: 分割; re.sub()
:替换; re.compile()
4. eval()
函数
eval()
函数,可以将字符串当成有效的表达式来求值,并返回计算结果 eval("1 + 1")
, 输出结果: 2
# 示例: 计算器# 提示用户输入一个加减乘除混合运算表达式input_str = input("请输入一个算术题: ")print(eval(input_str))# 备注: 开发时,千万不要使用 eval() 函数,直接转换 input 的结果# 原因:类似于"注入攻击"# 当用户输入: __import__('os').system('ls')# 等价于:import osos.system("终端命令")