常用模块

time模块

1、时间戳、:用来读秒 time.time()

2、格式化的时间字符串:比如2023-01-01 11:11:11  time.strftime()

3、结构化时间:给计算机看的

时间元组:localtime将一个时间戳转换为当前时区struct_time

时间日期的格式化符号:

%y     两位数的年份

%Y     四位数的年份

%m    月份

%d   月里具体哪天

%H     24小时制

%I      12小时制

%M   分钟数

%S   秒

%a    本地简化星期名称

%A    本地完整星期名称

%b  本地简化月份名称

%B  本地完整月份名称

%c  本地相应的日期表示和时间表示

%j  年内的一天

%p  本地AM 或PM的等价符

%U  一年内的星期数

%w  星期几,星期天为星期的开始

%W  一年中的星期数,星期一为星期的开始

%x  本地相应的日期表示

%X  本地相应时间表示

%Z  当前时区的名称

%%  %本身

time..gmtime(时间戳)UTC时间,与伦敦当地时间一致

time.localtime(时间戳) 当地时间。

time.strpyime(时间字符串,字符串对应格式)

import time
year month day
res=time.strftime('%Y-%m-%d %H:%M:%S')  # 2023-06-09 15:34:37
res=time.strftime('%Y-%m-%d %X')  # 2023-06-09 15:34:12
res=time.strftime('%Y-%m-%d %H:%M')  # 2023-06-09 15:35
res=time.strftime('%Y-%m-%d %I')  # 2023-06-09 03   十二小时制时间
res=time.strftime('%y-%m')  # 23-06  月份
res=time.strftime('%y-%m %a')  # 23-06 Fri   星期简化
res=time.strftime('%y-%m %b')  # 2023-06-09 10:10  月份简化
res=time.strftime('%y-%m %B')  # 23-06 June  月份完整
res=time.strftime('%y-%m %c')  #23-06 Fri Jun  9 15:37:53 2023   本地日期时间表示
res=time.strftime('%y-%m %j')  # 23-06 160    年内第几天
res=time.strftime('%y-%m %p')  # 23-06 PM   上午还是下午
res=time.strftime('%y-%m %U')  # 23-06 23 年内第几个星期
res=time.strftime('%y-%m %w')  # 23-06 5 星期几
res=time.strftime('%y-%m %%a')  # 23-06 %a   %%a就是%a
print(res)

打印当地时间

res = time.localtime()
print(res)  #time.struct_time(tm_year=2023, tm_mon=6, tm_mday=9, tm_hour=16, tm_min=5, tm_sec=11, tm_wday=4, tm_yday=160, tm_isdst=0)
print(res.tm_year)   #2023
print(res.tm_mon)   #6
print(res.tm_mday)   #9
print(res.tm_hour)   #16
print(res.tm_min)   #5
print(res.tm_sec)   #11
print(res.tm_wday)   #4
print(res.tm_yday)   #160

print(res[0],res[1]) #2023 6   索引取值

timestamp:时间戳
struct_time:结构化时间
format_string:格式化时间

时间戳转为结构化时间(gmtime)

print(time.time())
# 1686296796.5922346
res1 = time.gmtime(1686296789.459135)   #任意时间戳转为当前化时间
print(res1)
# time.struct_time(tm_year=2023, tm_mon=6, tm_mday=9, tm_hour=7, tm_min=46, tm_sec=29, tm_wday=4, tm_yday=160, tm_isdst=0)
#输出当前时间
res1 = time.gmtime(time.time())
print(res1)
#time.struct_time(tm_year=2023, tm_mon=6, tm_mday=9, tm_hour=8, tm_min=9, tm_sec=38, tm_wday=4, tm_yday=160, tm_isdst=0)

当前化时间转为时间戳(mktime)

# time.mktime(结构化时间)      当前化时间转为时间戳
time_tuple = time.localtime(1686296796.5922346)
print(time_tuple )  #time.struct_time(tm_year=2023, tm_mon=6, tm_mday=9, tm_hour=15, tm_min=46, tm_sec=36, tm_wday=4, tm_yday=160, tm_isdst=0)
print(time.mktime(time_tuple))  #1686296796.0

结构化时间转字符串时间(strftime)

#time.strftime("格式定义","结构化时间")  结构化时间参数若不传,则显示当前时间
res = time.strftime("%Y-%m-%d %X")
print(res)   #2023-06-09 16:20:51
res1 = time.strftime("%Y-%m-%d",time.localtime(1500000000))
print(res1)  #2017-07-14

字符串时间转结构化时间(strptime)

#字符串时间-->结构化时间
#time.strptime(时间字符串,字符串对应格式)
res = time.strptime("2017-03-16","%Y-%m-%d")
print(res)
#time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1)
res1 = time.strptime("07/24/2017","%m/%d/%Y")
print(res1)
# time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)

datetime模块

日期对象 = 日期对象 +/- timedelta对象
timedelta对象 = 日期对象 +/- 日期对象

import datetime 
#timedelta 可以对时间进行运算
tdelta = datetime.timedelta(days=7)
print(tdelta)   #7 days, 0:00:00
tday = datetime.datetime.today()
print("7天之后的日期是:%s" % (tday + tdelta))
print("7天之前的日期是:%s" % (tday - tdelta))
# 7天之后的日期是:2023-06-16 16:49:29.762151
# 7天之后的日期是:2023-06-02 16:49:29.762151

random模块

随机生成小数:

random.random()  生成大于0小于1之间的小数

 random.uniform(1,3)  生成大于1小于3的小数

随机生成整数:

 random.randint(1,5)  生成大于等于1且小于等于5的整数

random.randrange(1,10,2)  生成大于1且小于10的奇数

随机选择一个返回:

 random.choice([1,'23',[4,5]])  括号里的值随机进行一个返回

随机选择多个返回:

 random.sample([1,'23',[4,5]],2)   列表元素任意两个组合(任意几个数字为后面写的参数)

打乱列表顺序:

random.shuffle(i)

sys模块

sys.argv 命令行参数List,第一个元素是程序本身路径

import sys

print(sys.argv)  # ['D:\\python_study\\正则表达式.py']
print(sys.argv[0])   #D:\python_study\正则表达式.py

sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1)
sys.version 获取Python解释程序的版本信息
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称

异常处理

try:
    res=sys.argv[2]
except Exception:
    pass

os模块

 os模块是与操作系统交互的一个接口

os.mkdir(‘aaa') 创建文件,只能创建一层

 os.mkdirs(‘bbb/aaa') 可生成多层递归目录

os.rmdir('aaa') 只能删除空目录

 os.rmdirs('bbb/aaa') 只有每层文件都为空才能删除

os.listdir() 列出指定路径下的文件夹和文件

os.remove()删除一个文件

os.rename(‘旧文件名’,‘新文件名’) 修改文件和文件夹名称

os.stat() 获取文件和目录信息   (里面会有三time时间,即创建时间、访问时间、修改时间)

os.system(‘tasklist’) 后面讲

os.getcwd()获取当前工作目录,当前python脚本工作目录

os.chdir()改变当前脚本目录

os.path:

__file__返回当前所在路径(也就是,当下在哪个文件下运行该程序,则就会返回当前路径)

os.path.abspath(__file__)返回绝对路径

os.path.dirname() 获取文件夹名,dirname一次往上会找一次文件  os.path.dirname(os.path.dirname(os.path.dirname(__file__) ) ) 

os.path.basename() 只获取文件名(只获取最后一个)

os.path.exists()查看文件和文件夹路径是否存在(True,false)

os.path.isabs() 判断是否是绝对路径,如果是则True

os.path.isfile()是否是一个存在的文件,文件夹就不可

os.path.isdir()是否是一个存在的文件夹

os.path.join(‘原路径’,‘拼接路径’)拼接路径,join会根据操作系统自定识别路径分隔符

os.path.getatime()最后访问时间

os.path.getmtime()最后修改时间

os.path.getsize()返回大小,字节大小

序列化模块

现在我们都会在淘宝上买桌子,桌子这种很不规则不东西,该怎么从一个城市运输到另一个城市,这时候一般都会把它拆掉成板子,再装到箱子里面,就可以快递寄出去了,这个过程就类似我们的序列化的过程(把数据转化为可以存储或者传输的形式)。当买家收到货后,就需要自己把这些板子组装成桌子的样子,这个过程就像反序列 的过程(转化成当初的数据对象)。

作者:吧啦啦小汤圆
链接:https://www.jianshu.com/p/6219d8024d2c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

json格式

实现跨语言传输

序列:字符串

序列化:把其他数据类型转为字符串的过程

反序列化:把字符串转为其他数据类型的过程

能够直接写入文件的类型:字符串、二进制。如果要写入文件必须转为字符串或者二进制

json格式的数据

joson.dumps:序列化

json.loads:反序列化

json格式字符串必须是双引号,但是反序列化之后又变成单引号

joson.dump:先序列化,然后写入文件      f.write(json.dumps(d)) 就等于json.dump(d,f)

json.loads:反序列化   f.read(json.dumps(d)) 就等于json.loads(d,f) 但是文件中必须是标准的格式,如例如两个字典在同一行,就无法读取

pickle格式

json和pickl的区别:

json不是所有的数据类型都能序列化,可以跨语言使用

pickle能够序列化所有的数据类型,比如视频、音频、对象等,但是pickle序列化后的数据只能在python中使用,不能跨语言

pickle的四个方法:dumps、loads、dump、loads用法和json一样,但是结果都是二进制类型

subprocess模块

subprocess是用来判断命令是否正确,如果正确就会执行命令,如果不正确就会显示‘无该命令’

import subprocess

res=subprocess.Popen('ipconfig', shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE
                 )
print("stdout:", res.stdout.read().decode('gbk'))
print("stderr:", res.stderr.read().decode('gbk'))   #windos内部默认的编码是GBK

 

stdout:存储命令执行的正确结果

stderr:存储命令执行错误的结果

hashlib模块

是一类算法(解决问题的高级办法),该算法接受传入的内容,经过运算得到一串hash值,长度一定的数据串,通常用16进制的字符串表示。

特点:

1、只要传入内容一样,得到的hash值必然一样

2、不能由hash值反解成内容

3、不管传入内容多大,只要使用hash算法不变,得到的hash长度就一定

关于我们常见的加密算法,一般是不能逆转出明文数据的

加密方式相同,不管被加密数据多大加密结果长度一样,但不同的加密方式长度则不同。

但是不同的加密方式长度则不同,长度越长被破解难度越大,但是在数据传输过程中占空间更大。

加密方式选择

一般情况下MD5就够了

sha系列加密更难,一般支付会用

如何进行加密操作

1、先选择加密方式md系列、sha系列

2、对数据进行加密

3、获取加密之后的结果

import hashlib

m = hashlib.md5()  # 选择加密方式
m.update('123'.encode('utf8'))  # update里函数必须是字节类型,bytes
res = m.hexdigest()  # 获取加密后的结果
print(res)

m.update(文件所有内容)

m.update(文件一行)

m.update(文件一行)

m.update(文件一行)

以上两种结果都一样,但是文件过大时第二种就会变慢,所以可以定量校验,f.read(2000),随机可以用f.seek

密码加盐

固定盐:自己定义,不告诉别人,只有自己知道

动态盐:每个用户都不一样,随机的

普通注册:

import hashlib
username = input('username:')
password = input('password:')
m = hashlib.md5()
m.update(password.encode('gbk'))
res = m.hexdigest()
print(res)
i = '%s|%s'%(username,res)
with open('1.txt','a',encoding='utf8') as f:
    f.write(i)
lin|202cb962ac59075b964b07152d234b70
 

 加固定盐:

print('''1、注册
        2、登录
''')



#注册
import hashlib
def register():
    username = input('username:')
    password = input('password:')
    m = hashlib.md5()
    h ='@789'
    r = password + h
    m.update(r.encode('gbk'))
    res = m.hexdigest()
    print(res)
    i = '%s|%s'%(username,res)
    with open('1.txt','a',encoding='utf8') as f:
        f.write(i+'\n')

#登录
def login():
    username = input('username.login:')
    password = input('password.login')
    m = hashlib.md5()
    i = password + '@789'
    m.update(i.encode('gbk'))
    res = m.hexdigest()
    print(res)
    with open ('1.txt','r',encoding='utf8') as f:
        for a in f:
            b = a.split('|')
            if b[0] == username and b[1].strip('\n') == res:
                print('登录成功')
                break
        else:
            print('用户名或密码错误')


d = {
    '1': register,
    '2': login

}

choice = input('choice:')
if choice in d:
    d.get(choice)()

加动态盐

print('''1、注册
        2、登录
''')

import random
def get_code(n):
    d = ''
    for i in range(n):
        number = str(random.randint(0,9))
        upper = chr(random.randint(65,90))
        lower = chr(random.randint(97,122))
        res = random.choice([number,upper,lower])
        d += res
    return d

#注册
import hashlib
def register():
    username = input('username:')
    password = input('password:')
    m = hashlib.md5()
    h = get_code(5)
    r = password + h
    m.update(r.encode('gbk'))
    res = m.hexdigest()
    print(res)
    i = '%s|%s|%s'%(username,res,h)
    with open('1.txt','a',encoding='utf8') as f:
        f.write(i+'\n')

#登录
def login():
    username = input('username.login:')
    password = input('password.login')
    with open ('1.txt','r',encoding='utf8') as f:
        real_username,real_password,h = f.read().strip('\n').split('|')
        m = hashlib.md5()
        i = password + h
        m.update(i.encode('gbk'))
        res = m.hexdigest()
        print(res)
        if real_username == username and res.strip('\n') == res:
            print('登录成功')

        else:
            print('用户名或密码错误')


d = {
    '1': register,
    '2': login

}

choice = input('choice:')
if choice in d:
    d.get(choice)()

日志模块

记录代码执行过程中发生的变化

logging.debug() # 10   调试
logging.info() # 20   正常执行
logging.warning() # 30  警告
logging.error() # 40  错误

logging.critical() # 50  最严重

日志的组成部分

logger对象:控制日志的产生

filter对象:过滤日志

handler对象:控制日志的产生位置:文件,终端

format对象:控制日志格式

handler对象和format对象可以有多个

日志基本使用

import logging

file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)   #控制日志产生的位置  中间可以加配置的参数
logging.basicConfig(                          #basicConfig对日志的配置
    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p',
    handlers=[file_handler,],
    level=logging.ERROR         #最低是这个级别才能写
)

logging.error('你好')

配置参数

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 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息

import logging

# 1.logger对象:负责产生日志
logger = logging.getLogger()  # 获取logger对象
# 2.filter对象:负责过滤日志(直接忽略)
# 3.handler对象:负责日志产生的位置
hd1 = logging.FileHandler('a1.log', encoding='utf8')  # 产生到文件的
hd2 = logging.FileHandler('a2.log', encoding='utf8')  # 产生到文件的
hd3 = logging.StreamHandler()  # 产生在终端的



# 4.formatter对象:负责日志的格式
# 2023-06-13 11:49:53 - root - DEBUG -05 日志的详细使用:  写了半天 好累啊 好热啊
fm1 = logging.Formatter(
    fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
)

# 2023-06-13 - root 写了半天 好累啊 好热啊
fm2 = logging.Formatter(
    fmt='%(asctime)s - %(name)s %(message)s',
    datefmt='%Y-%m-%d',
)
# 5.绑定handler对象
logger.addHandler(hd1)
logger.addHandler(hd2)
logger.addHandler(hd3)
# 6.绑定formatter对象

hd1.setFormatter(fm1)
hd2.setFormatter(fm2)
hd3.setFormatter(fm1)


# 7.设置日志等级
logger.setLevel(10)  debug、info等
# 8.记录日志
logger.debug('写了半天 好累啊 好热啊')

配置成字典格式

import logging
import logging.config

standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

test_format = '%(asctime)s] %(message)s'

logfile_path = 'a3.log'
# log配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
         'test': {
            'format': test_format
        },
    },
    'filters': {},  # 过滤日志
    'handlers': {
        #打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        #打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            'formatter': 'standard',
            'filename': logfile_path,  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
        'other': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',  # 保存到文件
            'formatter': 'test',
            'filename': 'a2.log',
            'encoding': 'utf-8',
        },
    },
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置  空字符串作为键 能够兼容所有的日志
        '': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)传递
        },  # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
        'other': {
            'handlers': ['other',],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}


# 使用配置字典
logging.config.dictConfig(LOGGING_DIC)  # 自动加载字典中的配置
logger1 = logging.getLogger('xxx')
logger1.debug('好好的 不要浮躁 努力就有收获')

 

posted @ 2023-06-09 17:29  别管鱼油我了  阅读(14)  评论(0编辑  收藏  举报