模块 (上)

一 time模块

在Python中,通常有这几种方式来表示时间:

时间戳(timestamp):通常来说,时间戳表示的是从1970年开始按秒计算的偏移量。
我们运行“type(time.time())”,返回的是float类型。
格式化的时间字符串(Format String)
结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:
(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时(is_dst))
import time

#我们先以当前时间为准,让大家快速认识三种形式的时间

print(time.time()) # 时间戳:1487130156.419527
# 1970年开始到现在的秒数,用于时间间隔的计算

# %X=%H:%M:%S  %p(上午或者下午)
print(time.strftime("%Y-%m-%d %H:%M:%S %p")) 
print(time.strftime("%Y-%m-%d %X %p"))
#格式化的时间字符串:'2017-02-15 11:40:53'
# 按照某种格式显示时间,用于展示时间

print(time.localtime()) #本地时区的struct_time
print(time.gmtime())    #UTC时区的struct_time
# 获取当前时间的某一部分 

格式化字符串的时间格式其他用法———————————>>

datetime模块(时间加减)

import datetime

print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925
print(datetime.date.fromtimestamp(time.time()) )  # 时间戳直接转成日期格式 2016-08-19
print(datetime.datetime.now() )
print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分

c_time  = datetime.datetime.now()
print(c_time.replace(minute=3,hour=2)) #时间替换

Untitled

时间模块震要掌握的操作
# 1、时间格式的转换
#struct_time->时间戳 
import time
s_time=time.localtime()
print(time.mktime(s_time))

时间戳->struct_time
tp_time=time.time()
print(time.localtime(tp_time))
structtime->格式化的字符串形式的时间
s_time=time.localtime()
print(time.strftime('%Y-%m-%d %H:%M:%S',s_time))
print(time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S'))
**真正需要掌握的只有一条**:format string<------>timestamp

以1988-03-0311:11:11'+7举例

# format string-->struct_time--->timestamp
struct_time=time.strptime('1988-03-0311:11:11','%Y-%m-%d %H:%M:%S
timestamp=time.mktime(struct_time)+7*86400 
print(timestamp)

# format string<--struct_time<---timestamp
res=time.strftime('%Y-%m-%d %X',time.localtime(timestamp)) 
print(res)

# 其他 time.sleep(3) # 比如让程序睡三秒

三 random模块

import random

print(random.random())#(0,1)----float    大于0且小于1之间的小数(只能(0,1)不能指定范围)

print(random.randint(1,3))  #[1,3]    大于等于1且小于等于3之间的整数

print(random.randrange(1,3)) #[1,3)    大于等于1且小于3之间的整数

print(random.choice([1,'23',[4,5]]))#1或者23或者[4,5]

print(random.sample([1,'23',[4,5]],2))#列表元素任意2个组合

print(random.uniform(1,3))#大于1小于3的小数,如1.927109612082716

item=[1,3,5,7,9]
random.shuffle(item) #打乱item的顺序,相当于"洗牌"随机打乱顺序
print(item)
**应用:随机生成6位数验证码**

# ord('A')——>65, chr('65')———>'A'
# ord()函数主要用来返回对应字符的ascii码,
# chr()主要用来表示ascii码对应的字符他的输入时数字,
  可以用十进制,也可以用十六进制。

import random

def make_code(size):
    res=''
    for i in range(size):
        num=str(random.randint(0,9))
        s= chr(random.randint(65,90))
        res+=random.choice([num,s])
    return res
res=make_code(6)
print(res)

四 os模块

**os模块:**与操作系统交互的一个接口(标*即重点,优先掌握)
* os.listdir('dirname')   获取指定文件夹下的子文件及子文件夹名字,包括隐藏文件,并以列表方式打印
* os.system("bash command")  运行shell命令,直接显示  **  查看子文件夹查看子文件夹  
*  os.environ  获取系统环境变量 
   print(os.environ)
   os.environ['aaa]='111' ,key跟value都得是字符串
   PATH——>系统命令下,sys.path——>导模块
* os.path.getsize(path) 返回path的文件的大小(单位字节) 
* os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
  print(os.path.dirname("E:/Read_File"))
  结果:E:/
* os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
  os.path.basename('c:\test.csv')
  'test.csv'
* os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
* os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
* os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略,根据平台以/或\进行拼接
os.getcwd() 获取当前所在文件夹,即当前python脚本工作的目录路径
os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
os.curdir  返回当前目录: ('.')
os.pardir  获取当前目录的上级目录字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多层递归目录,可以帮你生成子子文件夹
os.removedirs('dirname1')    若dirname文件下为空文件,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.remove()  删除一个文件
os.rename("oldname","newname")  重命名文件/目录
os.stat('path/filename')  获取文件/目录信息(针对linux系统)
os.sep    输出操作系统特定的路径分隔符,win下为"\\(第一个\对第二个\转义的意思)",Linux下为"/" (纯了解)
os.linesep    输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"(纯了解)
os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:(纯了解)
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.path.abspath(path)  返回path规范化的绝对路径 (windows系统'\' linux系统'/'符合平台需求)
  import os
  print(__file__)
  print(os.path.abspath(__file__))
  结果:c:/Users/PycharmProjects/bbb.py 
        C:\Users\PycharmProjects\bbb.py
os.path.split(path)  将path分割成目录和文件名二元组返回
os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)  如果path是绝对路径,返回True
os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间

os.stat('path/filename') 获取文件/目录信息 的结构说明

五 sys模块

**基本用法**

1*sys.argv           命令行参数List,第一个元素是程序本身路径
2 sys.exit(n)        退出程序,正常退出时exit(0)
3 sys.version        获取Python解释程序的版本信息
4 sys.maxint         最大的Int值
5*sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
6 sys.platform       返回操作系统平台名称
* sys.argv 

import sys

print(sys.argv)

src_file = input("请输入源文件路径>>>:").strip()
dst_file = input("请输入目标文件路径>>>:").strip()

src_file = sys.argv[1]
dst_file = sys.argv[2]
print(src_file)
print(dst_file)

with open(r'%s' %src_file,mode='rb') as f1,open(r'%s' %dst_file,mode='wb') as f2:
    for line in f1:
        f2.write(line)

* sys.path 

**打印进度条**

#=========知识储备==========
#进度条的效果
[#             ]
[##            ]
[###           ]
[####          ]

#指定宽度
print('[%-15s]' %'#')
print('[%-15s]' %'##')
print('[%-15s]' %'###')
print('[%-15s]' %'####')

#打印%
print('%s%%' %(100)) #第二个%号代表取消第一个%的特殊意义

#可传参来控制宽度
print('[%%-%ds]' %50) #[%-50s]
print(('[%%-%ds]' %50) %'#')
print(('[%%-%ds]' %50) %'##')
print(('[%%-%ds]' %50) %'###')

#=========实现打印进度条函数==========
import sys
import time

def progress(percent,width=50):
    if percent >= 1:
        percent=1
    show_str=('[%%-%ds]' %width) %(int(width*percent)*'#')
    print('\r%s %d%%' %(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')

#=========应用==========
data_size=1025
recv_size=0
while recv_size < data_size:
    time.sleep(0.1) #模拟数据的传输延迟
    recv_size+=1024 #每次收1024

    percent=recv_size/data_size #接收的比例
    progress(percent,width=70) #进度条的宽度70

六shutil模块

shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中

1 import shutil  
2 shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w')) 

shutil.copyfile(src, dst)
**拷贝文件**

1 shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
 
shutil.copymode(src, dst)
**仅拷贝权限**。内容、组、用户均不变

1 shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
 
shutil.copystat(src, dst)
**仅拷贝状态的信息**,包括:mode bits, atime, mtime, flags

1 shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
 
shutil.copy(src, dst)
**拷贝文件和权限**

1 import shutil
2  
3 shutil.copy('f1.log', 'f2.log')
 

shutil.copy2(src, dst)
**拷贝文件和状态信息**

1 import shutil
2  
3 shutil.copy2('f1.log', 'f2.log')
 

shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
**递归的去拷贝文件夹**

1 import shutil
2  
3 shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除 

import shutil

shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))

'''
通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件
'''

shutil.rmtree(path[, ignore_errors[, onerror]])
**递归的去删除文件**

1 import shutil
2  
3 shutil.rmtree('folder1')
 

shutil.move(src, dst)
**递归的去移动文件**,它类似mv命令,其实就是重命名。

1 import shutil
2  
3 shutil.move('folder1', 'folder3')
 

shutil.make_archive(base_name, format,...)

**创建压缩包并返回文件路径**,例如:zip、tar

base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如 data_bak                       =>保存至当前路径
如:/tmp/data_bak =>保存至/tmp/
format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
root_dir: 要压缩的文件夹路径(默认当前目录)
owner: 用户,默认当前用户
group: 组,默认当前组
logger: 用于记录日志,通常是logging.Logger对象

1 #将 /data 下的文件打包放置当前程序目录
2 import shutil
3 ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
  
6 #将 /data下的文件打包放置 /tmp/目录
7 import shutil
8 ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data') 

shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:

import zipfile

**# 压缩**
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close()

**# 解压**
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall(path='.')
z.close()

import tarfile

**# 压缩**
>>> t=tarfile.open('/tmp/egon.tar','w')
>>> t.add('/test1/a.py',arcname='a.bak')
>>> t.add('/test1/b.py',arcname='b.bak')
>>> t.close()

**# 解压**
>>> t=tarfile.open('/tmp/egon.tar','r')
>>> t.extractall('/egon')
>>> t.close()

七 json模块&(pickle)

之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。

1 import json("")
2 x="[null,true,false,1]"
3 print(eval(x)) #报错,无法解析null类型,而json就可以
4 print(json.loads(x))
**什么是序列化?**

我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,
在Python中叫pickling,在其他语言中也被称为serialization,marshalling,flattening等等,都是一个意思。
**为什么要序列化?**

1:持久保存状态
    需知一个软件/程序的执行就在处理一系列状态的变化,在编程语言中,
'状态'会以各种各样有结构的数据类型(也可简单的理解为变量)的形式被保存在内存中。
内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,
内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。
在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),
以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。
具体的来说,你玩使命召唤闯到了第13关,你保存游戏状态,关机走人,下次再玩,
还能从上次的位置开始继续闯关。或如,虚拟机状态的挂起等。

2:跨平台数据交互

序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,
如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,
实现了跨平台数据交互。

反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
****json模块**是将满足条件的数据结构转化成特殊的字符串,并且也可以反序列化还原回去。**

上面介绍我已经说过了,序列化模块总共只有两种用法,要不就是用于网络传输的中间环节,
要不就是文件存储的中间环节,所以json模块总共就有两对四个方法:

**用于**网络传输**:dumps、loads**

**用于**文件写读**:dump、load**

dumps、loads

import json
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic)  #序列化:将一个字典转换成一个字符串
print(type(str_dic),str_dic)  #<class 'str'> {"k1": "v1", "k2": "v2", "k3": "v3"}
#**注意**,json转换完的字符串类型的字典中的字符串是由""表示的

dic2 = json.loads(str_dic)  #反序列化:将一个字符串格式的字典转换成一个字典
#注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(type(dic2),dic2)  #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
str_dic = json.dumps(list_dic) #也可以处理嵌套的数据类型 
print(type(str_dic),str_dic) #<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
list_dic2 = json.loads(str_dic)
print(type(list_dic2),list_dic2) #<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
创建text.json文件

import json
# 将**序列化**写入文件的复杂方法
json_res=json.dumps([1,'aaa',True,False])
print(json_res,type(json_res)) # [1, "aaa", true, false] <class 'str'>
with open('test.json',mode='wt',encoding='utf-8')as f:
    f.write(json_res)

# 将序列化写入文件的简单方法(如果只是想把序列化内容写到文件里这样简单点)
with open('test.json',mode='wt',encoding='utf-8')as f:
    json.dump([1,'aaa',True,False],f)

#**反序列化**

# 从文件读取json格式的字符串反序列化的结果写入文件的复杂方法
with open('text.json',mode='rt',encoding='utf-8')as f:
    json_res=f.reas()
    l=json.loads(json_res)
    print(l,type(l)) #[1, 'aaa', True, False] <class 'list'>

# 从文件读取json格式的字符串反序列化的结果写入文件的简单方法
with open('text.json',mode='rt',encoding='utf-8')as f:
    l=json.load(f)  # 执行f.read操作-把文件内容读出来-然后调f.loads-把读出来的内容进行反解
    print(l,type(l))  #[1, 'aaa', True, False] <class 'list'>

dump、load(针对文件相关)

import json
f = open('json_file.json','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f)  #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
f.close()
# json文件也是文件,就是专门存储json字符串的文件。
f = open('json_file.json')
dic2 = json.load(f)  #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2),dic2)

八 pickle模块& (json)

pickle模块是将Python所有的数据结构以及对象等转化成bytes类型,然后还可以反序列化还原回去。

刚才也跟大家提到了pickle模块,pickle模块是只能Python语言识别的序列化模块。如果把序列化模块比喻成全世界公认的一种交流语言,也就是标准的话,json就是像是英语,全世界(python,java,php,C,等等)都遵循这个标准。而pickle就是中文,只有中国人(python)作为第一交流语言。

既然只是Python语言使用,那么它支持Python所有的数据类型包括后面我们要讲的实例化对象等,它能将这些所有的数据结构序列化成特殊的bytes,然后还可以反序列化还原。使用上与json几乎差不多,也是两对四个方法。

用于**网络传输**:dumps、loads

用于**文件写读**:dump、load

dumps、loads

import pickle
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = pickle.dumps(dic)
print(str_dic)  # bytes类型

dic2 = pickle.loads(str_dic)
print(dic2)    #字典

# 还可以序列化对象
import pickle

def func():
    print(666)
    
ret = pickle.dumps(func)
print(ret,type(ret))  # b'\x80\x03c__main__\nfunc\nq\x00.' <class 'bytes'>

f1 = pickle.loads(ret)  # f1得到 func函数的内存地址
f1()  # 执行func函数

dump、load

dic = {(1,2):'oldboy',1:True,'set':{1,2,3}}
f = open('pick序列化',mode='wb')
pickle.dump(dic,f)
f.close()
with open('pick序列化',mode='wb') as f1:
    pickle.dump(dic,f1)

pickle序列化存储多个数据到一个文件中

dic1 = {'name':'oldboy1'}
dic2 = {'name':'oldboy2'}
dic3 = {'name':'oldboy3'}

f = open('pick多数据',mode='wb')
pickle.dump(dic1,f)
pickle.dump(dic2,f)
pickle.dump(dic3,f)
f.close()

f = open('pick多数据',mode='rb')
while True:
    try:
        print(pickle.load(f))
    except EOFError:
        break
f.close()
既然pickle如此强大,为什么还要学json呢?这里我们要说明一下,json是一种所有
的语言都可以识别的数据结构。如果我们将一个字典或者序列化成了一个json存在文件里,
那么java代码或者js代码也可以拿来用。但是如果我们用pickle进行序列化,其他语言就
不能读懂这是什么了~所以,如果你序列化的内容是列表或者字典,我们非常推荐你使用
json模块,但如果出于某种原因你不得不序列化其他的数据类型,而未来你还会用python
对这个数据进行反序列化的话,那么就可以使用pickle。
**其他**

# 序列化
# 内存中的数据类型------序列化-------》格式
# 内存中的数据类型《------反序列化-------格式

# **作用**:
# 1、**存档---》pickle**
# 2、**跨平台交互数据---》json**

# ==================>**json兼容所有语言,但是不支持所有的python数据类型**
(json验证:json格式兼容所有语言通用数据类型,不能识别某一语言所独有的类型)
# ==================> dumps--->loads
# import json
#
# str_json = json.dumps({"x":1,'y':2,'z':True,'a':None})
# print(str_json)
#
# dic = json.loads(str_json)
# print(dic)

# ====================> dump--->load
# import json

# json.dump({"x":1,'y':2,'z':True,'a':None},open('a.json',mode='wt',encoding='utf-8'))

# dic = json.load(open('a.json',mode='rt',encoding='utf-8'))
# print(dic)

# ===================> **pickle只适用于python,但是可以支持所有python的数据类型**
# ====================> dumps--->loads
# import pickle
#
# res_pkl = pickle.dumps({"x":1,'y':2,'z':True,'a':None})
# print(res_pkl)
#
# dic = pickle.loads(res_pkl)
# print(dic)

# ====================> dump--->load
# import pickle
#
# # pickle.dump({"x":1,'y':2,'z':True,'a':None},open('a.pkl',mode='wb'))
#
# dic = pickle.load(open('a.pkl',mode='rb'))
# print(dic)

import pickle
import json

# res = pickle.dumps({1,2,3,4,5,6})
res = json.dumps({1,2,3,4,5,6})
print(res)

jason-->t,用的多,跨平台  , pickle-->b,只适用于python

Untitled

posted @ 2021-08-16 21:38  停在夏季  阅读(36)  评论(0)    收藏  举报
-->