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的大小
在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。 >>> os.path.normcase(‘c:/windows\\system32\\‘) ‘c:\\windows\\system32\\‘ 规范化路径,如..和/ >>> os.path.normpath(‘c://windows\\System32\\../Temp/‘) ‘c:\\windows\\Temp‘ >>> a=‘/Users/jieli/test1/\\\a1/\\\\aa.py/../..‘ >>> print(os.path.normpath(a)) /Users/jieli/test1
#过滤出顶级目录 添加sys.path的时候用
‘‘‘
1.os.path.abspath(path) 返回path规范化的绝对路径
2.将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.join(path1[, path2[, ...]])
3.规范化路径,如..和/
os.path.normpath(‘c://windows\\System32\\../Temp/‘)
‘c:\\windows\\Temp‘
os.pardir ..
‘‘‘
#当前文件的绝对路径
# print(os.path.abspath(__file__))
#E:\python\s17\day06\os+sys模块.py
#定位到顶级目录 目前路径还不规范
#print(os.path.join(os.path.abspath(__file__)),os.pardir,os.pardir,os.pardir)
#E:\python\s17\day06\os+sys模块.py .. ..
#规范化路径
# possible_topdir = os.path.normpath(os.path.join(
# os.path.abspath(__file__),
# os.pardir, #上一级
# os.pardir,
# os.pardir
# ))
# print(possible_topdir) #E:\python
#方式二:不推荐使用 os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
time模块
import time
时间戳 time.time()
格式化 time.strftime(‘%Y-%m-%d %X‘)
结构化 time.localtime() time.gmtime()
- 时间戳
print(time.time()) #时间戳 float
打印结果:
1496551809.2893198
2. 格式化时间
print(time.strftime(‘%Y-%m-%d %X‘)) #格式化字符串 X就是时分秒 格式自定义
打印结果:
2017-06-04 12:50:09
3.结构化时间
本地时区:
print(time.localtime())#本地时区的struct_time 平时时间
打印结果:
time.struct_time(tm_year=2017, tm_mon=6, tm_mday=4, tm_hour=12, tm_min=50, tm_sec=9, tm_wday=6, tm_yday=155, tm_isdst=0)
UTC时区:
print(time.gmtime()) #UTC时区的struct_time 少8个小时
打印结果:
time.struct_time(tm_year=2017, tm_mon=6, tm_mday=4, tm_hour=4, tm_min=50, tm_sec=9, tm_wday=6, tm_yday=155, tm_isdst=0)
时间戳 time.time()
格式化 time.strftime(‘%Y-%m-%d %X‘)
结构化 time.localtime() time.gmtime()
1.将时间戳转为结构化本地时间和utc时间
# print(time.time())
# print(time.localtime(1473525444.037215))
# print(time.gmtime(1473525444.037215))
2.将结构化的时间转为时间戳
# print(time.mktime(time.localtime()))
# print(time.mktime(time.gmtime()))
3.将结构化时间格式化
# print(time.localtime())
# print(time.gmtime())
# print(time.strftime(‘%Y-%m-%d %X‘,time.localtime()))
# print(time.strftime(‘%Y-%m-%d %X‘,time.gmtime()))
4.将格式化时间结构化
# print(time.strftime(‘%Y-%m-%d %X‘))
# print(time.strptime(‘2017-06-04 13:14:10‘,‘%Y-%m-%d %X‘))
#在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
# print(time.asctime())
# print(time.ctime())
# ‘‘‘
# 打印结果是一样的:
# Sun Jun 4 13:18:47 2017
# Sun Jun 4 13:18:47 2017
# ‘‘‘
# print(time.ctime(time.time())) #将时间戳转为上边的格式
# import subprocess
#subprocess.Popen(‘命令‘,命令的类型 标准正确输出 到 管道)
# res=subprocess.Popen(‘dir‘,shell=True,stdout=subprocess.PIPE)
# print(res) #<subprocess.Popen object at 0x00000207E09AD198>
# print(res.stdout.read().decode(‘gbk‘))
#拿到管道里的结果显示到终端 bytes格式
#那么就需要decode 以当前系统的编码格式解码
‘‘‘
驱动器 E 中的卷是 新加卷
卷的序列号是 BA41-6DC8
E:\python\s17\day06 的目录
2017/06/09 14:03 <DIR> .
2017/06/09 14:03 <DIR> ..
2017/06/07 14:22 108 a.cfg
2017/06/07 10:21 64 aa.txt
....省略部分
18 个文件 14,207 字节
2 个目录 235,944,165,376 可用字节
‘‘‘
#如果命令是错误的
# import subprocess
# res=subprocess.Popen(‘fjdfdljfdlkfjd‘,shell=True,
# stderr=subprocess.PIPE, #将错误信息放到这里 不是终端
# stdout=subprocess.PIPE)
# #print(res)
# print("这里的结果",res.stdout.read())
# print(res.stderr.read().decode(‘gbk‘))
# ‘‘‘
# ‘fjdfdljfdlkfjd‘ 不是内部或外部命令,也不是可运行的程序
# 或批处理文件。
# ‘‘‘
##stdin
#ls | grep txt$
# import subprocess
# res1=subprocess.Popen(r‘dir E:\python\s17\day06‘,shell=True,stdout=subprocess.PIPE) #先拿出目录下的所有
# # print(res1.stdout.read().decode(‘gbk‘))
# res=subprocess.Popen(r‘findstr txt*‘,shell=True,
# stdin=res1.stdout, #将上边的输出,作为这里的输入 模拟了管道的功能
# stderr=subprocess.PIPE,
# stdout=subprocess.PIPE)
# print(res.stdout.read().decode(‘gbk‘))
# ‘‘‘
# 2017/06/07 10:21 64 aa.txt
# 2017/06/07 10:19 154 bb.txt
# 2017/06/07 10:41 22 sheve.txt.bak
# 2017/06/07 10:41 99 sheve.txt.dat
# 2017/06/07 10:41 22 sheve.txt.dir
# ‘‘‘
#思路: 做爬虫的话 可以 一个程序用来爬内容 一个程序处理爬的内容
#!/usr/bin/python
#-*-coding:utf-8 -*-
import xml.etree.ElementTree as ET
tree=ET.parse(‘xmltest‘)
root=tree.getroot()
#关于搜索的 搜索范围
# print(root.iter(‘year‘)) #全文搜索 year
# print(next(root.iter(‘year‘))) #迭代器
#
# print(next(root.find(‘country‘))) #在 root的子节点找 只找一个
#
# print(next(root.findall(‘country‘))) #在 root的子节点找 找所有的
#功能
# for i in root.iter(‘year‘):
#print(i)
#例如这段内容 <year update=‘yes‘>2008</year>
# print(i.tag) #标签名 这里year就是标签名
# print(i.text) #内容 中间的2008就是内容
# print(i.attrib) #属性 update=‘yes‘ 就是属性
# #遍历xmltest文档
# for country in root:
# print(‘=========>‘,country.tag,country.attrib,country.attrib[‘name‘])
# for child in country:
# print(child.tag,child.text,child.attrib)
#只是遍历 year节点
# for i in root.iter(‘year‘):
# print(i.tag,i.text,i.attrib)
#修改
# for node in root.iter(‘year‘):
# new_year=int(node.text)+1
# node.text=str(new_year)
# node.set(‘update‘,‘yes‘) #设置增加属性
# node.set(‘version‘,‘1.0‘) #设置增加属性
# tree.write(‘xmltest‘)
##删除 node
# for country in root.findall(‘country‘):
# #print(country)
# rank=int(country.find(‘rank‘).text)
# #print(rank)
# if rank > 50:
# root.remove(country)
# tree.write(‘xmltest‘)
#
#在country 内添加(append)节点year2
# for country in root.findall(‘country‘):
# for year in country.findall(‘year‘):
# #print(year)
# if int(year.text) > 2000:
# year2=ET.Element(‘year2‘)
# #print(year2)
# year2.text=‘new year‘
# year2.attrib={‘update‘:‘yes‘}
# country.append(year2)
# tree.write(‘xmltest‘)
##用代码写出以下文件的内容
‘‘‘
<?xml version=‘1.0‘ encoding=‘utf-8‘?>
<namelist><name enrolled="yes"><sex>33</sex></name><age checked="no" /><name enrolled="no"><age>19</age></name></namelist>
‘‘‘
import xml.etree.ElementTree as ET
new_xml=ET.Element(‘namelist‘)
name=ET.SubElement(new_xml,‘name‘,attrib={‘enrolled‘:‘yes‘})
age=ET.SubElement(new_xml,‘age‘,attrib={‘checked‘:‘no‘})
sex=ET.SubElement(name,"sex")
sex.text=‘33‘
name2=ET.SubElement(new_xml,‘name‘,attrib={‘enrolled‘:‘no‘})
age=ET.SubElement(name2,‘age‘)
age.text=‘19‘
et=ET.ElementTree(new_xml)
et.write(‘test22.xml‘,encoding=‘utf-8‘,xml_declaration=True)
ET.dump(new_xml)
‘‘‘
hash:一种算法 ,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
三个特点:
1.内容相同则hash运算结果相同,内容稍微改变则hash值则变
2.不可逆推
3.相同算法:无论校验多长的数据,得到的哈希值长度固定。
‘‘‘
import hashlib
#就是这样的格式
m=hashlib.md5()
m.update(‘hello‘.encode(‘utf-8‘))
print(m.hexdigest()) #5d41402abc4b2a76b9719d911017c592
‘‘‘
注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样
但是update多次为校验大文件提供了可能。
‘‘‘
‘‘‘
以上加密算法虽然依然非常厉害,但时候存在缺陷,
即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
‘‘‘
import hashlib
hash=hashlib.sha256(‘382hjejfbbv‘.encode(‘utf-8‘))
hash.update(‘hello‘.encode(‘utf-8‘))
print(hash.hexdigest()) #41be5b2550530511928ec5f03b53f8cc23e1dd419dbfd3f108652bd76613937e
‘‘‘
处理 key value对应的文件
‘‘‘
‘‘‘
a.cfg内容如下
# 注释1
; 注释2
[section1]
k1 = v1
k2:v2
user=egon
age=18
is_admin=true
salary=31
[section2]
k1 = v1
‘‘‘
- ##############查看####################
# import configparser
# config=configparser.ConfigParser()
# config.read(‘a.cfg‘)
#1.查看所有的标题 也就是大节点
# res=config.sections()
# print(res) #[‘section1‘, ‘section2‘]
#2.查看标题section1下所有key=value的key
# options=config.options(‘section1‘) ##填写文件中的实际标题
# print(options)
# #[‘k1‘, ‘k2‘, ‘user‘, ‘age‘, ‘is_admin‘, ‘salary‘] 以列表的形式显示key
#3.查看标题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‘)]
#4.查看某个标题下某个key的值
#str形式 int形式 bool形式 float形式
‘‘‘
针对下边这段内容练习
[section1]
k1 = v1
k2:v2
user=egon
age=18
is_admin=true
salary=31.22
‘‘‘
# 1》str 查看标题section1下user的值
# print(res,type(res)) #egon <class ‘str‘>
# 2》int 查看标题section1下age的值
# res=config.getint(‘section1‘,‘age‘)
# print(res) #18
# 3》bool 查看标题section1下is_admin的值
# res=config.getboolean(‘section1‘,‘is_admin‘)
# print(res) #true
# 4》float 查看标题section1下salary的值
# res=config.getfloat(‘section1‘,‘salary‘)
# print(res) #31.22
- #############修改####################
# import configparser
# config=configparser.ConfigParser()
# config.read(‘a.cfg‘)
# #1.删除整个标题section2
# config.remove_section(‘section2‘)
# #2.删除标题section1下的某个k1和k2
# config.remove_option(‘section1‘,‘k1‘)
# config.remove_option(‘section1‘,‘k2‘)
# #3.判断是否存在某个标题
# print(config.has_section(‘section1‘))
# #4.判断section1标题下是否存在user这个key
# print(config.has_option(‘section1‘,‘user‘))
# #5.添加一个标题
# config.add_section(‘section55‘)
# #6.在标题egon下添加name=egon,age=18的配置
# config.set(‘section55‘,‘name‘,‘egon‘)
# config.set(‘section55‘,‘age‘,‘18‘) #报错,必须是字符串
# #****最后将修改写入文件 这样写入才会生效哦
# config.write(open(‘a.cfg‘,‘w‘))
#练习
‘‘‘
test.ini的内容如下
[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
[bitbucket.org]
User = hg
[topsecret.server.com]
Port = 50022
ForwardX11 = no
‘‘‘
# import configparser
# config=configparser.ConfigParser()
# config.read(‘test.ini‘,encoding=‘utf-8‘)
#1.获取所有节点
# res=config.sections()
# print(res)
‘‘‘
打印结果
[‘bit
bucket.org‘, ‘topsecret.server.com‘] 不包括DEFAULT
‘‘‘
#2.获取指定节点下所有的键值对
# res=config.items(‘bitbucket.org‘)
# print(res)
‘‘‘
打印结果:
[(‘serveraliveinterval‘, ‘45‘), (‘compression‘, ‘yes‘), (‘compressionlevel‘, ‘9‘), (‘forwardx11‘, ‘yes‘), (‘user‘, ‘hg‘)]
‘‘‘
#3.获取指定节点下所有的键
# res=config.options(‘bitbucket.org‘)
# print(res)
‘‘‘
打印结果:
[‘user‘, ‘serveraliveinterval‘, ‘compression‘, ‘compressionlevel‘, ‘forwardx11‘]
‘‘‘
#4.获取指定节点下指定key的值
# res1=config.get(‘bitbucket.org‘,‘user‘)
# res2=config.getint(‘topsecret.server.com‘,‘port‘)
# res3=config.getfloat(‘topsecret.server.com‘,‘port‘)
# res4=config.getboolean(‘topsecret.server.com‘,‘ForwardX11‘)
#
# print(res1)
# print(res2)
# print(res3)
# print(res4)
#5.检查 删除 添加节点
#检查
# has_res=config.has_section(‘bitbucket.org‘)
# print(has_res) #True
#添加节点
# config.add_section(‘egon‘)
# config[‘egon‘][‘username‘]=‘qiqige‘
# config[‘egon‘][‘age‘]=‘18‘
# config.write(open(‘test.ini‘,‘w‘))
#删除节点
# config.remove_section(‘egon‘)
# config.write(open(‘test.ini‘,‘w‘))
#6.设置指定组内的键值对
# import configparser
# config=configparser.ConfigParser()
# config.read(‘test.ini‘,encoding=‘utf-8‘)
#
# config.set(‘bitbucket.org‘,‘user‘,‘mamamiya‘)
# config.write(open(‘test.ini‘,‘w‘))
‘‘‘
写一个文件qiqi.ini 内容如下:
[DEFAULT]
serveraliveinterval = 45
compression = yes
compressionlevel = 9
forwardx11 = yes
[bitbucket.org]
user = hg
[topsecret.server.com]
host port = 50022
forwardx11 = no
‘‘‘
import configparser
config = 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‘ # mutates the parser
topsecret[‘ForwardX11‘] = ‘no‘ # same here
config[‘DEFAULT‘][‘ForwardX11‘] = ‘yes‘
with open(‘qiqi.ini‘, ‘w‘) as configfile:
config.write(configfile)
内存断电,内容丢失,所以有把内容存入硬盘的需求
代码文件各种数据类型,在内存中可以存放各种数据类型,保存完好的数据结构
但是存放到硬盘的时候,代码文件也是普通的文件,里边的内容都是普通的字符串,
这样拿出来用的时候,没有了数据结构和特定的含义,可怎么好呢,这就涉及到
一个转换 这样转换为硬盘存储的就是 序列化
json 各个语言之间的通道 适用范围广
pickle 仅仅针对python
eval 小功能更是 把字符串的内容拿出来执行一下
什么是序列化?
我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
为什么要序列化?
1:持久保存状态
需知一个软件/程序的执行就在处理一系列状态的变化,在编程语言中,‘状态‘会以各种各样有结构的数据类型(也可简单的理解为变量)的形式被保存在内存中。
内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。
在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。
具体的来说,你玩使命召唤闯到了第13关,你保存游戏状态,关机走人,下次再玩,还能从上次的位置开始继续闯关。或如,虚拟机状态的挂起等。
2:跨平台数据交互
序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。
如何序列化之json和pickle:
json
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:
#import json
######序列化#########
‘‘‘
过程:
dic---->res=json.dumps(dic)---->f.write(dic)
‘‘‘
# dic={
# ‘name‘:‘alex‘,
# ‘height‘:155,
# ‘sex‘:‘male‘,
# }
# res=json.dumps(dic)
# print(res,type(res))
‘‘‘
打印结果:
{"name": "alex", "height": 155, "sex": "male"} <class ‘str‘>
‘‘‘
# with open(‘a.json‘,‘w‘) as f:
# f.write(res)
#######反序列化###########
‘‘‘
过程:
res=f.read()---->json.loads(res)---->dic
‘‘‘
# with open(‘a.json‘,‘r‘) as f:
# dic=json.loads(f.read())
# print(dic,type(dic))
‘‘‘
打印结果:
{‘name‘: ‘alex‘, ‘height‘: 155, ‘sex‘: ‘male‘} <class ‘dict‘>
‘‘‘
#**********json的简化操作 dump load *************
# import json
# dic={
# ‘name‘:‘alex‘,
# ‘height‘:155,
# ‘sex‘:‘male‘,
# }
# json.dump(dic,open(‘b.json‘,‘w‘))#序列化
# res=json.load(open(‘b.json‘,‘r‘))#反序列化
# print(res,type(res))
‘‘‘
针对python自己的序列化和反序列化
‘‘‘
import pickle
# dic={‘name‘:‘alvin‘,‘age‘:23,‘sex‘:‘male‘}
# res=pickle.dumps(dic) #bytes格式
# print(res,type(res))
# ‘‘‘
# b‘\x80\x03}q\x00(X\x0x03\x00\x00maleq\x05u.‘ <class ‘bytes‘>
# ‘‘‘
#以bytes格式写入文件
# with open(‘aa.txt‘,‘wb‘) as f:
# f.write(res)
# #或者
# pickle.dump(dic,f)
- ##########反序列化############
# with open(‘aa.txt‘,‘rb‘) as f:
# res=pickle.loads(f.read())
# print(res)
#或者
# print(pickle.load(open(‘aa.txt‘,‘rb‘)))
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)之间的整数
# print(random.choice([1,‘23‘,[4,5]])) #每个项目随机出现
# print(random.choice([1,2,3])) #列表的格式
# print(random.sample([‘hello‘,‘qiqi‘,‘yangyang‘],3)) #3(自定义)个随机组合
‘‘‘
打印结果之一:
[‘qiqi‘, ‘yangyang‘, ‘hello‘]
‘‘‘
# print(random.uniform(1,3)) #(1,3)之间的小数 范围自定义
#打乱顺序 随机排列顺序 ‘洗牌‘
# l=[1,2,3,4,5]
# random.shuffle(l)
# print(l)
‘‘‘
应用:
随机生成验证码
‘‘‘
import random
def v_code():
code = ‘‘
for i in range(5):
num=random.randint(0,9)
alf=chr(random.randint(65,90))
add=random.choice([num,alf])
code += str(add)
return code
print(v_code())
#import shutil
#1.cp文件内容 新文件有则覆盖,无则创建
#shutil.copyfileobj(open(‘old.txt‘,‘r‘),open(‘new.txt‘,‘w‘))
#2.cp文件 目标文件无需存在
#shutil.copyfile(‘old.txt‘,‘aa.txt‘)
#3.仅拷贝权限。内容、组、用户均不变
#shutil.copymode(‘f1.log‘, ‘f2.log‘) #目标文件必须存在
#4.仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
#shutil.copystat(‘f1.log‘, ‘f2.log‘) #目标文件必须存在
#5.cp文件和权限
#shutil.copy(‘f1.log‘, ‘f2.log‘)
#6.cp文件和状态信息
#shutil.copy2(‘f1.log‘, ‘f2.log‘)
#7.递归cp文件夹 目标目录不能存在
#shutil.copytree(‘first‘,‘two‘)
#排除不想cp的文件
#shutil.copytree(‘two‘,‘newtwo‘,ignore=shutil.ignore_patterns(‘*.py‘,‘tmp*‘))
#cp软连接 通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件
#shutil.copytree(‘f1‘, ‘f2‘, symlinks=True, ignore=shutil.ignore_patterns(‘*.pyc‘, ‘tmp*‘))
#8.递归的删除文件夹
#shutil.rmtree(‘newtwo‘)
#9.递归的移动目录 相当于mv
#shutil.move(‘two‘,‘three‘)
#压缩
# shutil.make_archive(‘two.bak‘,‘gztar‘,‘three‘) #two.bak.tar.gz
# shutil.make_archive(‘/tmp/two.bak‘,‘bztar‘,‘three‘) #two.bak.tar.bz2
# #新文件名,默认是当前目录 压缩方式 要压缩的文件
#shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
#zipfile压缩解压缩
#压缩: 目标压缩文件可存在可不存在,无则创建,有则加入新文件到压缩包里
#import zipfile
# z=zipfile.ZipFile(‘zz.zip‘,‘w‘)
# z.write(‘aa.txt‘)
# z.write(‘old.txt‘)
# z.write(‘test.py‘)
# z.close()
#解压缩
# z=zipfile.ZipFile(‘zz.zip‘,‘r‘)
# z.extractall(path=‘.‘)
# z.close()
#tarfile压缩解压缩
#import tarfile
#压缩
# t=tarfile.open(‘/tmp/egon.tar‘,‘w‘)
# t.add(‘/test1/a.py‘,arcname=‘a.bak‘) #加上 arcname 是只压缩文件,非递归压缩,指定别名
# t.add(‘/test1/b.py‘,arcname=‘b.bak‘)
# t.close()
# 解压
# t=tarfile.open(‘/tmp/egon.tar‘,‘r‘)
# t.extractall(‘/egon‘)
# t.close()