模块
模块分为4种形式:
- 使用python编写的 .py文件
- 已经被编译为共享库或DLL的C或C++扩展
- 把一些列模块组织到一起的文件夹(文件夹下需要有——init——.py 文件,改文件夹称为包)
- 使用C编写并链接到python解释器的内置模块
导入顺序(规范):
- 内置模块
- 第三方
- 自定义
命名规范
纯小写+下划线
模块的导入方式:
方式一:
import 模块
import 模块 as 别名
首次导入时,发生的事情:
- 执行导入的代码
- 产生对应的名称空间
- 在当前文件中产生一个名字,指向产生的名称空间中
name
如果一个文件中存在 name ,这个文件单独执行时, name 代表 main ,当被导入时,代表 导入的模块名称
方式二:
使用更加方便,但容易与当前命名空间混淆
from 模块 import 函数 //此时,函数调用不需要加模块的前缀
导入时发生的事情:
- 执行导入的代码
- 产生对应的名称空间
- 在当前的名称空间中产生一个名字,直接指向函数的内存地址
*函数导入时,函数中的变量并不会使用导入到的文件中的,而是使用原本函数所在文件内的
可以使用*导入全部模块,在原模块中使用 __all__ 可以定义*代表的含义
#foo.py
__all__ = ['x'] #默认代表全部
x = 10
y = 11
#test.py
from foo import *
print(x) #x可以打印
print(y) # y不可以打印
模块的循环导入问题
当两个模块循环导入时,容易因为在导入操作时,一个模块中的变量或函数尚未加载就被另外一个函数引用而报错.因尽量避免循环导入.
可以用解决方案:
- 将公用的内容存到另外一个新的模块中,避免循环导入问题的出现
- 将公用的内容放到导入操作的前边
- 在函数内导入
导入的优先级
- 先从内存(已经导入的模块或内置模块)中查找
- 按照sys.path中的路径进行查找
模块编写的规范
- 尽量使用局部变量
代码块的顺序
- 模块的文档描述
- 导入其他模块
- 全局变量
- 类
- 函数
- 如果文件作为脚本执行时的代码(main 函数)
包的使用
包是模块的一种形式,通常在文件夹下边有__init__.py文件,
导入方式
导入包即是导入包中的init文件,包内可以嵌套其他的包(文件夹)
绝对导入
在包的使用过程中,用户一般都会把包的路径加到sys.path中,因此可以基于包的名称在init文件中进行导入
form foo.test import func1 //foo为包 test为py文件 func1为功能
相对导入(包内模块导入时,建议使用)
相对导入以 . 做为起始,第一个点代表当前文件夹,一个 点 代表一层文件夹.相对导入只能在包内使用
from .foo import func1
常用模块
1.time
import time
print(time.time()) #获取时间戳,常用于计算间隔
print(time.strftime('%D-%m-%d %H:%M:%S %p')) #获取格式化后的时间,一般用于展示
print(time.strftime('%X')) #获取时间
print(time.localtime()) #获取结构化的时间,用于获取时间的某一部分
2.datetime
import datetime
print(datetime.datetime.now()) #当前时间
print(datetime.datetime.utcnow()) #当前时间
print(datetime.datetime.now()+datetime.timedelta(days=1)) #时间的运算
间戳之间的转换:
import datetime import time #时间戳->结构化时间 x = time.time() print(time.localtime(x)) #时间戳->datetime datetime.datetime.fromtimestamp(11110) #世界时间 print(time.gmtime(x)) #结构化->时间戳 y = time.localtime() print(time.mktime(y)) # 结构化->格式化 print(time.strftime('%Y-%m-%d %H:%M:%S',y )) # 格式化->结构化 print(time.strptime('2000-1-1 10:10:10','%Y-%m-%d %H:%M:%S'))
3.random
import random
print(random.random()) #(0,1)----float 大于0且小于1之间的小数
print(random.randint(1, 3)) # [1,3] 大于等于1且小于等于3之间的整数
print(random.randrange(1, 3)) # [1,3) 大于等于1且小于3之间的整数
print(random.choice([111, 'aaa', [4, 5]])) # 1或者23或者[4,5]
print(random.sample([111, 'aaa', 'ccc','ddd'],2)) # 列表元素任意2个组合
print(random.uniform(1, 3)) # 大于1小于3的小数,如1.927109612082716
item = [1, 3, 5, 7, 9]
random.shuffle(item) # 打乱item的顺序,相当于"洗牌"
4.OS
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息
os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
5.json
通过json模块可以快速的进行序列化和反序列化,通过序列化,可以让数据更方便的进行网络传输或跨平台使用.
josn格式兼容所有语言通用的数据类型,不能对某个语言专有类型转换。
import json
x = [1,2,3,'aa']
# 序列化
res = json.dumps(x)
print(res,type(res))
# 反序列化
res2 = json.loads(res)
print(res2,type(res2))
#如果想写入或者读取json文件可以使用以下方法
#打开文件后
json.dump(x,f)
json.load(f)
6.configparser
configparser模块可以管理配置文件
#配置文件格式如下
[section1]
k1 = v1
k2:v2
user=egon
age=18
is_admin=true
[section2]
k1 = v1
import configparser
config=configparser.ConfigParser()
config.read('a.cfg')
#查看所有的标题
res=config.sections() #['section1', 'section2']
print(res)
#查看标题section1下所有key=value的key
options=config.options('section1')
print(options) #['k1', 'k2', 'user', 'age', 'is_admin', 'salary']
#查看标题section1下所有key=value的(key,value)格式
item_list=config.items('section1')
print(item_list) #[('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]
#查看标题section1下user的值=>字符串格式
val=config.get('section1','user')
print(val) #egon
#查看标题section1下age的值=>整数格式
val1=config.getint('section1','age')
print(val1) #18
#查看标题section1下is_admin的值=>布尔值格式
val2=config.getboolean('section1','is_admin')
print(val2) #True
#查看标题section1下salary的值=>浮点型格式
val3=config.getfloat('section1','salary')
print(val3) #31.0
7.hashlib模块
hash模块一般用于密码校验以及文件验证中。
- 在密码校验中,为防止被撞库,一般会增加额外的校验字段
- 在文件验证中,有时候文件会特别长,为了提高校验速率,会抽样生成hash值。而不是将整个文件进行校验
8.logging
import logging
简单使用:
logging.debug('调试级别')
logging.ingo('消息级别')
logging.warning('警告级别')
loggging.erro('错误级别')
logging.critical('严重级别')
## 详细使用
#配置文件 setting.py内容
import os
#1.定义常用日志格式
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]'
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
test_format = '%(asctime)s] %(message)s'
#2.定义日志基本参数
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
'test': {
'format': test_format
},
},
'filters': {},
#handlers为日志的接受者,内容可自定义接受者的名字,及输出格式
'handlers': {
'console': {
'level': 'DEBUG', #将loggers传过来的内容进行过滤
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,日志轮转
'formatter': 'standard',
# 可以指定日志文件路径
# BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# LOG_PATH = os.path.join(BASE_DIR,'defaultlog.log')
'filename': 'defaultlog.log', # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M,日志文件超过大小后,会对达到日志大小的文件重命名,然后创建defaultlog.log,继续写入新的内容
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,默认跟随电脑系统的编码,windows默认为GBK,mac、linux默认为utf-8
},
'other': {
'level': 'DEBUG',
'class': 'logging.FileHandler', # 保存到文件
'formatter': 'test',
'filename': 'otherlog.log',
'encoding': 'utf-8',
},
},
#loggers内定义日志生产者的信息,
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 选择handles中定义日志接受者
'level': 'DEBUG', # 在内容输出给handles前进行过滤
'propagate': False, # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
},
'test': {
'handlers': ['other',],
'level': 'DEBUG',
'propagate': False,
},
},
}
#3.使用
import logging.config # 这样连同logging.getLogger都一起导入了,然后使用前缀logging.config.
import settings
logging.config.dictConfig(settings.LOGGING_DIC) #加载配置文件
logger1=logging.getLogger('test') #指定logger
logger1.info('test-logger输出了消息界别的内容') #输出消息级别的日志
format常用的参数
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2020-07-08 20:20:20,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息