刘刚刚的个人博客

7.python基础——模块

创建时间:2020-07-13 17:07:17
更新时间:2020-07-19 22:14:38

站在巨人的肩膀上前进。

模块

模块分为4种形式:

  1. 使用python编写的 .py文件
  2. 已经被编译为共享库或DLL的C或C++扩展
  3. 把一些列模块组织到一起的文件夹(文件夹下需要有——init——.py 文件,改文件夹称为包)
  4. 使用C编写并链接到python解释器的内置模块

导入顺序(规范):

  1. 内置模块
  2. 第三方
  3. 自定义

命名规范

纯小写+下划线

模块的导入方式:

方式一:

import   模块
import 模块  as  别名

首次导入时,发生的事情:

  1. 执行导入的代码
  2. 产生对应的名称空间
  3. 在当前文件中产生一个名字,指向产生的名称空间中

    name

如果一个文件中存在 name ,这个文件单独执行时, name 代表 main ,当被导入时,代表 导入的模块名称

方式二:

使用更加方便,但容易与当前命名空间混淆

from  模块 import  函数   //此时,函数调用不需要加模块的前缀

导入时发生的事情:

  1. 执行导入的代码
  2. 产生对应的名称空间
  3. 在当前的名称空间中产生一个名字,直接指向函数的内存地址
*函数导入时,函数中的变量并不会使用导入到的文件中的,而是使用原本函数所在文件内的

可以使用*导入全部模块,在原模块中使用 __all__ 可以定义*代表的含义

#foo.py
__all__ = ['x']  #默认代表全部
x = 10
y = 11

#test.py
from foo import *
print(x)  #x可以打印
print(y)  # y不可以打印

模块的循环导入问题

当两个模块循环导入时,容易因为在导入操作时,一个模块中的变量或函数尚未加载就被另外一个函数引用而报错.因尽量避免循环导入.

可以用解决方案:

  1. 将公用的内容存到另外一个新的模块中,避免循环导入问题的出现
  2. 将公用的内容放到导入操作的前边
  3. 在函数内导入

导入的优先级

  1. 先从内存(已经导入的模块或内置模块)中查找
  2. 按照sys.path中的路径进行查找

模块编写的规范

  1. 尽量使用局部变量
  2. 代码块的顺序

    1. 模块的文档描述
    2. 导入其他模块
    3. 全局变量
    4. 函数
    5. 如果文件作为脚本执行时的代码(main 函数)

包的使用

包是模块的一种形式,通常在文件夹下边有__init__.py文件,

导入方式

导入包即是导入包中的init文件,包内可以嵌套其他的包(文件夹)

  1. 绝对导入

    在包的使用过程中,用户一般都会把包的路径加到sys.path中,因此可以基于包的名称在init文件中进行导入

    form  foo.test import func1   //foo为包 test为py文件 func1为功能
  2. 相对导入(包内模块导入时,建议使用)

    相对导入以 . 做为起始,第一个点代表当前文件夹,一个 点 代表一层文件夹.相对导入只能在包内使用

    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用户输出的消息
我的名片

昵称:shuta

职业:后台开发(python、php)

邮箱:648949076@qq.com

站点信息

建站时间: 2020/2/19
网站程序: ANTD PRO VUE + TP6.0
晋ICP备18007778号