「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」
1.读写文件
运用内置的os库
关于路径:
- 路径分隔符
- 绝对路径与相对路径
import os
# 路径拼接,用“/”
os.path.join('datawhale', 'docu')
# 获取当前目录
os.getcwd()
'/Users/lichizou/Documents/dw'
# 切换目录,切换到上一级
os.chdir('..')
os.getcwd()
'/Users/lichizou/Documents'
# 绝对路径与相对路径转换与判断
os.path.abspath(os.getcwd()) # 获取当前路径的绝对路径
'/Users/lichizou/Documents'
# 当前路径是否是据对路径
os.path.isabs('.')
False
os.path.isabs(os.path.abspath('.'))
True
os.chdir('/Users/lichizou/Documents/dw//team-learning-program/OfficeAutomation')
os.getcwd()
'/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation'
# 指定起时路径,获取相对路径
os.path.relpath('./图片/pycharm1.png','/Users/lichizou/Documents/dw/team-learning-program')
'OfficeAutomation/图片/pycharm1.png'
path = '/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/readme.md'
# 从路径获取目录和文件名
os.path.dirname(path)
'/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation'
os.path.basename(path)
'readme.md'
os.path.split(path) # 文件夹和文件名放在元祖里
('/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation',
'readme.md')
sep = os.path.sep # /
path.split(sep) # 出现空数据,如何剔除?为什么会出现?
['', 'Users', 'lichizou', '', 'Documents', 'dw', 'team-learning-program', 'OfficeAutomation', 'readme.md']
# 判断路径是否合法
# os.path.exists(path)
os.path.exists('note1.md')
False
# 根据路径判断是文件还是文件夹
os.path.isfile(path)
True
os.path.isdir(path)
False
os.path.isdir('/Users/lichizou//Documents/dw/team-learning-program/')
True
# 创建新文件夹
os.makedirs('test')
# 查看文件大小和
os.path.getsize('readme.md') # 单位:字节
2234
# 为什么是672,文件夹会出错
os.path.getsize('/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation')
672
# 查看文件夹内容
os.listdir('/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation')
['Task02 Python与Excel.md', 'Task03 python与word.md', 'Note01-file-automation.ipynb', 'Note03-word-automation.ipynb', 'Task05 爬虫入门与综合应用.md', '.DS_Store', 'Task01 文件自动化处理&邮件批量处理.md', 'test', 'Task04 Python操作PDF.md', 'PreNote03-python-built-in.ipynb', '__pycache__', '.history', 'readme.md', 'Note05-spider.ipynb', 'PreNote01-python-base.ipynb', 'Note02-excel-automation.ipynb', 'PreNote02-python-function.ipynb', 'Note04-pdf-automation.ipynb', '图片']
# 遍历获取文件夹大小,todo,存在缺陷
total_size = 0
file_size = 0
base_path = '/Users/lichizou//Documents/dw/team-learning-program/CSharpLanguage'
file_name = ''
file_list = os.listdir(base_path)
for file in file_list:
file_name = os.path.join(base_path, file)
file_size = os.path.getsize(file_name) # 这里必须判断是否是文件
print(f'{file_name}: {file_size}')
total_size += file_size
print(total_size)
/Users/lichizou//Documents/dw/team-learning-program/CSharpLanguage/02 C#面向对象设计 I.md: 15938
/Users/lichizou//Documents/dw/team-learning-program/CSharpLanguage/01 C#语言基本语法结构.md: 8684
/Users/lichizou//Documents/dw/team-learning-program/CSharpLanguage/03 C#面向对象设计 II.md: 20343
44965
# 写一个函数,获得一个文件夹或文件的大小
# todo:输出,按照一种漂亮的格式输出,类型/大小/排序
def get_dir_size(path):
total_size = 0
file_list = os.listdir(path)
file_name = ''
size = 0
for file in file_list:
file_name = os.path.join(path, file)
if os.path.isfile(file_name):
size = os.path.getsize(file_name)
total_size += size
print(f'[file]:{file}: {size}')
else:
size = get_filedir_size(file_name)
total_size += size
# print(f'[dir]{file}:{total_size}')
print(f'[dir]{file_name}:{size}')
print(f'[dir]{path}:{total_size}')
return total_size
get_dir_size('/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation')
[file]:Task02 Python与Excel.md: 7787
[file]:Task03 python与word.md: 15627
[file]:Note01-file-automation.ipynb: 21218
[file]:Note03-word-automation.ipynb: 5202
[file]:Task05 爬虫入门与综合应用.md: 26827
[file]:.DS_Store: 8196
[file]:Task01 文件自动化处理&邮件批量处理.md: 27189
[dir]/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/test:0
[file]:Task04 Python操作PDF.md: 17825
[file]:PreNote03-python-built-in.ipynb: 0
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/__pycache__/mycats.cpython-39.pyc: 233
[dir]/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/__pycache__:233
[file]:readme.md: 2234
[file]:Note05-spider.ipynb: 865
[file]:PreNote01-python-base.ipynb: 567
[file]:Note02-excel-automation.ipynb: 3910
[file]:PreNote02-python-function.ipynb: 0
[file]:Note04-pdf-automation.ipynb: 1636
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/image-20210518151332873.png: 63260
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/安装docx.png: 73576
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/image-20210518154517118.png: 22363
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/页眉页脚设置.png: 18845
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/周杰伦.jpg: 112238
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/邀请函样式.png: 28015
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/Excel.png: 57871
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/excel到word.xlsx: 9366
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/参会人名单.png: 10813
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/pycharm2.png: 131442
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/pycharm1.png: 68267
[file]:/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/图5.1.png: 26209
[dir]/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片:622265
[dir]/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation:761581
761581
# 文件打开与关闭
hello_file = open('hello.txt')
type(hello_file)
#print(hello_file)
_io.TextIOWrapper
# 文件读:读取全部和按行读
hello_content = hello_file.read()
hello_content
'1\n2\n3\n4\n5\n6\n7\n8\n9\n10'
type(hello_content)
str
hello_file.close()
hello_file = open('hello.txt')
hello_content = hello_file.readlines()
hello_content
['1\n', '2\n', '3\n', '4\n', '5\n', '6\n', '7\n', '8\n', '9\n', '10']
type(hello_content)
list
hello_file.close()
hello_file = open('hello.txt')
hello_content = hello_file.readline()
hello_content
'1\n'
hello_content = hello_file.readline() # 会逐渐向下读,因该有一个读的标签
hello_content
'3\n'
# 文件的写
bacon_file = open('bacon.txt','w')
bacon_file.write('hello bacon!') # 此时txt里还没有内容
bacon_file.close() # 此时内容写入
bacon_file = open('bacon.txt', 'a')
bacon_file.write('next line') # 尚未写入txt
bacon_file.close() # 写入txt,但是没有换行
bacon_file = open('bacon.txt')
txt = bacon_file.read()
bacon_file.close()
print(txt)
hello bacon!next line
# 文件内容转存与再利用
# 库shelve'
import shelve
# 将python变量写入shelve
shelve_file = shelve.open('mydata')
cats = ['cat1', 'cat2', 'cat3']
shelve_file['cats'] = cats
shelve_file.close()
# 读取shelve的内容
shelve_file = shelve.open('mydata') # 可读可写,不必指定
type(shelve_file)
shelve.DbfilenameShelf
shelve_file['cats']
['cat1', 'cat2', 'cat3']
type(shelve_file['cats'])
list
shelve_file['cp'] = 123
shelve_file.close()
shelve_file = shelve.open('mydata') # 可读可写,不必指定
shelve_file['cp']
123
shelve_file.close()
# 库pprint:将python变量写入py文件,成为模块方便调用
import pprint
cats = [{'name':'catname1', 'desc': 'catdesc1'},
{'name':'catname2', 'desc': 'catdesc2'}]
pprint.pformat(cats)
"[{'desc': 'catdesc1', 'name': 'catname1'},\n {'desc': 'catdesc2', 'name': 'catname2'}]"
# 将变量写入python文件,使之成为模块
file_obj = open('mycats.py', 'w')
file_obj.write('cats = ' + pprint.pformat(cats) + '\n')
file_obj.close()
import mycats # 文件名即模块名
mycats.cats
[{'desc': 'catdesc1', 'name': 'catname1'}, {'desc': 'catdesc2', 'name': 'catname2'}]
mycats.cats[0]
{'desc': 'catdesc1', 'name': 'catname1'}
mycats.cats[0]['name']
'catname1'
练习
1、如果已有的文件以写模式打开,会发生什么?
# 新建practice1.txt,填写入一些内容,然后以写模式打开
practice_1 = open('practice1.txt', 'w') # 用r模式打开会报错
practice_1.write('123143123')
practice_1.close()
# 现在再次用w模式打开, 发现文件里的内容被清空了。
practice_1 = open('practice1.txt', 'w')
practice_1.close()
2、read()和readlines()方法之间的区别是什么?
# 新建文件practice_2.txt,在里面填写一些内容
practice_2 = open('practice_2', 'w')
practice_2.write('1\n2\n3\n4\n5')
practice_2.close()
# 用read()打开
practice_2 = open('practice_2')
practice_2.read() # 返回全部内容
'1\n2\n3\n4\n5'
type(practice_2.read()) # 是字符串形式
str
# 用readlines()打开
practice_2 = open('practice_2')
practice_2.readlines() # 返回全部内容
['1\n', '2\n', '3\n', '4\n', '5']
type(practice_2.readlines()) # 是数组形式
list
综合练习
一、生成随机的测验试卷文件 假如你是一位地理老师, 班上有 35 名学生, 你希望进行美国各州首府的一个 小测验。不妙的是,班里有几个坏蛋, 你无法确信学生不会作弊。你希望随机调整 问题的次序, 这样每份试卷都是独一无二的, 这让任何人都不能从其他人那里抄袭答案。当然,手工完成这件事又费时又无聊。 好在, 你懂一些 Python。
下面是程序所做的事:
• 创建 35 份不同的测验试卷。
• 为每份试卷创建 50 个多重选择题,次序随机。
• 为每个问题提供一个正确答案和 3 个随机的错误答案,次序随机。
• 将测验试卷写到 35 个文本文件中。
• 将答案写到 35 个文本文件中。
这意味着代码需要做下面的事:
• 将州和它们的首府保存在一个字典中。
• 针对测验文本文件和答案文本文件,调用 open()、 write()和 close()。
• 利用 random.shuffle()随机调整问题和多重选项的次序。
# 分析:
# 1个问题,4个选项,包括1个固定答案,其余3个随机,且顺序随机。问题:州名,答案:首府
# 1份试卷50题
# 生成35份试卷,存到35个文本
# 州与首府的匹配
capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona': 'Phoenix',
'Arkansas': 'Little Rock', 'California': 'Sacramento', 'Colorado': 'Denver',
'Connecticut': 'Hartford', 'Delaware': 'Dover', 'Florida': 'Tallahassee',
'Georgia': 'Atlanta', 'Hawaii': 'Honolulu', 'Idaho': 'Boise', 'Illinois':
'Springfield', 'Indiana': 'Indianapolis', 'Iowa': 'Des Moines', 'Kansas':
'Topeka', 'Kentucky': 'Frankfort', 'Louisiana': 'Baton Rouge', 'Maine':
'Augusta', 'Maryland': 'Annapolis', 'Massachusetts': 'Boston', 'Michigan':
'Lansing', 'Minnesota': 'Saint Paul', 'Mississippi': 'Jackson', 'Missouri':
'Jefferson City', 'Montana': 'Helena', 'Nebraska': 'Lincoln', 'Nevada':
'Carson City', 'New Hampshire': 'Concord', 'New Jersey': 'Trenton', 'New'
'Mexico': 'Santa Fe', 'New York': 'Albany', 'North Carolina': 'Raleigh',
'North Dakota': 'Bismarck', 'Ohio': 'Columbus', 'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem', 'Pennsylvania': 'Harrisburg', 'Rhode Island': 'Providence',
'South Carolina': 'Columbia', 'South Dakota': 'Pierre', 'Tennessee':
'Nashville', 'Texas': 'Austin', 'Utah': 'Salt Lake City', 'Vermont':
'Montpelier', 'Virginia': 'Richmond', 'Washington': 'Olympia', 'West'
'Virginia': 'Charleston', 'Wisconsin': 'Madison', 'Wyoming': 'Cheyenne'}
for k,v in capitals.items():
print(f'{k}:{v}')
Alabama:Montgomery
Alaska:Juneau
Arizona:Phoenix
Arkansas:Little Rock
California:Sacramento
Colorado:Denver
Connecticut:Hartford
Delaware:Dover
Florida:Tallahassee
Georgia:Atlanta
Hawaii:Honolulu
Idaho:Boise
Illinois:Springfield
Indiana:Indianapolis
Iowa:Des Moines
Kansas:Topeka
Kentucky:Frankfort
Louisiana:Baton Rouge
Maine:Augusta
Maryland:Annapolis
Massachusetts:Boston
Michigan:Lansing
Minnesota:Saint Paul
Mississippi:Jackson
Missouri:Jefferson City
Montana:Helena
Nebraska:Lincoln
Nevada:Carson City
New Hampshire:Concord
New Jersey:Trenton
NewMexico:Santa Fe
New York:Albany
North Carolina:Raleigh
North Dakota:Bismarck
Ohio:Columbus
Oklahoma:Oklahoma City
Oregon:Salem
Pennsylvania:Harrisburg
Rhode Island:Providence
South Carolina:Columbia
South Dakota:Pierre
Tennessee:Nashville
Texas:Austin
Utah:Salt Lake City
Vermont:Montpelier
Virginia:Richmond
Washington:Olympia
WestVirginia:Charleston
Wisconsin:Madison
Wyoming:Cheyenne
keys = capitals.keys()
list_keys = list(keys)
print(list_keys)
['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'NewMexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'WestVirginia', 'Wisconsin', 'Wyoming']
import random
random.choice(list_keys)
'Missouri'
vals = capitals.values()
list_values = list(vals)
print(list_values)
['Montgomery', 'Juneau', 'Phoenix', 'Little Rock', 'Sacramento', 'Denver', 'Hartford', 'Dover', 'Tallahassee', 'Atlanta', 'Honolulu', 'Boise', 'Springfield', 'Indianapolis', 'Des Moines', 'Topeka', 'Frankfort', 'Baton Rouge', 'Augusta', 'Annapolis', 'Boston', 'Lansing', 'Saint Paul', 'Jackson', 'Jefferson City', 'Helena', 'Lincoln', 'Carson City', 'Concord', 'Trenton', 'Santa Fe', 'Albany', 'Raleigh', 'Bismarck', 'Columbus', 'Oklahoma City', 'Salem', 'Harrisburg', 'Providence', 'Columbia', 'Pierre', 'Nashville', 'Austin', 'Salt Lake City', 'Montpelier', 'Richmond', 'Olympia', 'Charleston', 'Madison', 'Cheyenne']
random.choice(list_values)
'Sacramento'
arr = [1,2,3]
arr.pop()
arr
[1, 2]
for i in range(5):
print(i)
0
1
2
3
4
chr(ord('A') + 1)
'B'
# 生成一道题
# test_question:{question: key, answer: [4]}
# test_paper: test_question[50]
#
import random
# 生成1道题
def get_question():
test_question = {}
test_question['question'] = random.choice(list_keys) # 从list里随机1个值
test_question['answer'] = random.sample(list_values, 4) # 从列表里随机几个值
ans = capitals[test_question['question']]
test_question['right'] = ans
if ans not in test_question['answer']:
test_question['answer'].pop()
test_question['answer'].append(ans)
random.shuffle(test_question['answer']) # 随机打乱
#print(test_question)
return test_question
# 生成50道题
def get_test(test_num = 50):
arr = []
for i in range(test_num):
arr.append(get_question())
return arr
# 生成一份卷子文件
def get_file(test_arr, file_name):
file = open(file_name, 'w')
q_order = 1
for i in test_arr:
file.write(str(q_order) + '.')
file.write(f'The Capital of {i["question"]} is ()?\n')
a_order = 0
for j in i['answer']:
file.write(f'{chr(ord("A") + a_order)}: {j}\n')
a_order += 1
q_order += 1
file.write('\n')
file.close()
get_question()
{'question': 'Idaho',
'answer': ['Richmond', 'Columbia', 'Springfield', 'Boise'],
'right': 'Boise'}
get_test()
[{'question': 'Georgia', 'answer': ['Oklahoma City', 'Raleigh', 'Atlanta', 'Baton Rouge'],
'right': 'Atlanta'},
{'question': 'Alabama',
'answer': ['Sacramento', 'Salem', 'Montgomery', 'Baton Rouge'],
'right': 'Montgomery'},
{'question': 'Ohio',
'answer': ['Columbus', 'Austin', 'Madison', 'Lincoln'],
'right': 'Columbus'},
{'question': 'Oklahoma',
'answer': ['Saint Paul', 'Charleston', 'Oklahoma City', 'Phoenix'],
'right': 'Oklahoma City'},
{'question': 'Colorado',
'answer': ['Baton Rouge', 'Denver', 'Trenton', 'Helena'],
'right': 'Denver'}]
new_dir = 'exam'
os.makedirs(new_dir)
# send2trash.send2trash('exam')
for i in range(1, 36):
path = 'exam' + str(i).zfill(2) + '.txt'
get_file(get_test(), os.path.join(new_dir, path))
2.文件处理
使用库shutil:复制,移动,重命名,删除文件
import shutil
# 文件复制到文件,两个文件都必须存在
# 随机在两个文件里填写不同内容。目标文件被覆盖,源文件还在
shutil.copy('src_file.txt', 'dest_file.txt')
'dest_file.txt'
# 文件复制到文件夹,若新文件夹不存在同名文件,则直接复制过去
shutil.copy('src_file.txt', './test')
'./test/src_file.txt'
# 复制到文件夹内文件,覆盖内容,保留两个文件
shutil.copy('src_file.txt', './test/dest_file.txt')
'./test/dest_file.txt'
# 复制文件夹到文件夹, 目标文件夹必须不存在
# 源文件夹里的内容被递归复制
shutil.copytree('test', 'test2')
'test2'
# 搞几个测试文件
shutil.copy('src_file.txt', 'src_file1.txt')
shutil.copy('src_file.txt', 'src_file2.txt')
shutil.copy('src_file.txt', 'src_file3.txt')
shutil.copy('src_file.txt', 'src_file4.txt')
shutil.copy('src_file.txt', 'src_file5.txt')
'src_file5.txt'
shutil.copy('dest_file.txt', 'dest_file1.txt')
shutil.copy('dest_file.txt', 'dest_file2.txt')
shutil.copy('dest_file.txt', 'dest_file3.txt')
shutil.copy('dest_file.txt', 'dest_file4.txt')
shutil.copy('dest_file.txt', 'dest_file5.txt')
'dest_file5.txt'
# 移动文件到文件,目标文件存在:源文件被删,目标文件被覆盖。重命名并删除目标文件
shutil.move('src_file1.txt', 'dest_file1.txt')
'dest_file1.txt'
# 移动到不存在的目标文件,相当于重命名。
shutil.move('src_file2.txt', 'dest_file11.txt')
'dest_file11.txt'
#移动文件夹到不存在文件夹,相当于重命名
shutil.move('./test2', 'test3')
'test3'
# 移动文件夹到已存在文件夹,只是移动
# 令目标文件夹里文件比源文件夹多
# test3比test2多1个bacon.txt
shutil.move('test2', 'test3')
'test3/test2'
#永久删除文件
os.unlink('src_file3.txt') # 废纸篓找不到
# 删除文件夹,要求文件夹必须是空的
#os.rmdir('test3')
# 递归删除,如果是空的文件夹会报空
shutil.rmtree('test3')
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
<ipython-input-74-135b3bd675a1> in <module>
1 # 递归删除
----> 2 shutil.rmtree('test3')
/usr/local/Cellar/python@3.9/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shutil.py in rmtree(path, ignore_errors, onerror)
707 orig_st = os.lstat(path)
708 except Exception:
--> 709 onerror(os.lstat, path, sys.exc_info())
710 return
711 try:
/usr/local/Cellar/python@3.9/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shutil.py in rmtree(path, ignore_errors, onerror)
705 # lstat()/open()/fstat() trick.
706 try:
--> 707 orig_st = os.lstat(path)
708 except Exception:
709 onerror(os.lstat, path, sys.exc_info())
FileNotFoundError: [Errno 2] No such file or directory: 'test3'
#安全删除文件
# 安装库: pip install send2trash
!pip3 install send2trash
Requirement already satisfied: send2trash in /usr/local/lib/python3.9/site-packages (1.5.0)
!/usr/local/opt/python@3.9/bin/python3.9 -m pip install --upgrade pip
Requirement already satisfied: pip in /usr/local/lib/python3.9/site-packages (21.1.1)
Collecting pip
Downloading pip-21.1.2-py3-none-any.whl (1.5 MB)
[K |████████████████████████████████| 1.5 MB 174 kB/s
[?25hInstalling collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 21.1.1
Uninstalling pip-21.1.1:
Successfully uninstalled pip-21.1.1
Successfully installed pip-21.1.2
import send2trash
#安全删除文件夹,可以在废纸篓里找到
send2trash.send2trash('src_file5.txt')
#遍历目录树
#遍历当前目录
path = '/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation'
total_size = 0
spath = ''
file_num = 0
for root, dir, files in os.walk(path):
for f in files: # 全部文件
print(os.path.join(root, f))
total_size += os.path.getsize(os.path.join(root, f))
file_num += 1
# for d in dir: # 全部文件夹
# print(os.path.join(root, d))
# total_size += os.path.getsize(os.path.join(root, d))
# file_num += 1
print(f'{file_num}:{total_size}')
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/dest_file3.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/mycats.py
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Task02 Python与Excel.md
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Task03 python与word.md
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Note01-file-automation.ipynb
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/src_file4.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/dest_file2.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Note03-word-automation.ipynb
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/dest_file11.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Task05 爬虫入门与综合应用.md
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/dest_file1.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/practice1.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/dest_file5.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.DS_Store
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Task01 文件自动化处理&邮件批量处理.md
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/dest_file4.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Task04 Python操作PDF.md
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/PreNote03-python-built-in.ipynb
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/src_file.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/mydata
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/readme.md
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/bacon.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/practice_2
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Note05-spider.ipynb
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/PreNote01-python-base.ipynb
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Note02-excel-automation.ipynb
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/dest_file.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/hello.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/PreNote02-python-function.ipynb
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/Note04-pdf-automation.ipynb
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/test/src_file.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/test/dest_file.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/__pycache__/mycats.cpython-39.pyc
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/hello_20210615174301.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/hello_20210615174302.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/hello_20210615174259.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/dest_file_20210615193822.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/hello_20210615174428.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/src_file1_20210615194923.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/dest_file_20210615193816.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/hello_20210615174254.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/src_file1_20210615195057.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/test/src_file_20210615193829.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/test/dest_file_20210615194134.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/test/dest_file_20210615194141.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/.history/test/src_file_20210615193710.txt
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/image-20210518151332873.png
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/安装docx.png
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/image-20210518154517118.png
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/页眉页脚设置.png
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/周杰伦.jpg
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/邀请函样式.png
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/Excel.png
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/excel到word.xlsx
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/参会人名单.png
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/pycharm2.png
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/pycharm1.png
/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片/图5.1.png
58:803341
# 压缩文件:库zipfile
# 创建和添加到zip文件
# 压缩test文件夹
import zipfile
# 新建一个zip压缩包,并添加文件
new_zip = zipfile.ZipFile('new.zip', 'w') # 写模式创建一个压缩文件,会清空
new_zip.write('bacon.txt', compress_type = zipfile.ZIP_DEFLATED) # 添加的文件要求是存在的
new_zip.close()
# 压缩一个目录:需要递归
new_zip = zipfile.ZipFile('img.zip', 'a')
path = '/Users/lichizou//Documents/dw/team-learning-program/OfficeAutomation/图片'
for root, dirs, files in os.walk(path):
for file in files:
new_zip.write(os.path.join(root, file), compress_type = zipfile.ZIP_DEFLATED) # 这样会连同文件夹目录都复制
new_zip.close()
# 读取zip文件
read_zip = zipfile.ZipFile('img.zip')
read_zip.namelist() # 返回所有文件的字符串列表
['Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/image-20210518151332873.png', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/安装docx.png', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/image-20210518154517118.png', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/页眉页脚设置.png', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/周杰伦.jpg', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/邀请函样式.png', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/Excel.png', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/excel到word.xlsx', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/参会人名单.png', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/pycharm2.png', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/pycharm1.png', 'Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/图5.1.png']
zip_info = read_zip.getinfo('Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/图5.1.png')
zip_info.file_size # 原文件大小
26209
zip_info.compress_size # 压缩后大小
24143
# 压缩率
compress_rate = round(zip_info.compress_size / zip_info.file_size, 2)
compress_rate
0.92
# 从zip中解压缩全部到指定文件夹,没有会创建
new_zip = zipfile.ZipFile('img.zip')
new_zip.extractall('img_unzip') # 只要一个参数就可以了
new_zip.close()
# 只解压单独文件
new_zip = zipfile.ZipFile('img.zip')
# 前面的路径是img.zip的路径
new_zip.extract('Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/安装docx.png', 'test')
new_zip.close()
作业
1)、编写一个程序,遍历一个目录树,查找特定扩展名的文件(诸如.pdf 或.jpg)。不论这些文件的位置在哪里, 将它们拷贝到一个新的文件夹中。
# 在src_dir里寻找特定后缀的文件,复制到dest_dir
def copy_file_by_type(src_dir, file_type, dest_dir):
if not os.path.exists(src_dir):
return
# 使用shelve缓存
tmp_path = []
for root, dir, files in os.walk(src_dir):
for file in files:
file_name = os.path.basename(file)
if file_name.endswith(file_type):
tmp_path.append(os.path.join(root, file)) # 保存新名,不进行文件操作
#shutil.copy(os.path.join(root, file), dest_dir) # src_dir与dest_dir同文件夹,会循环复制
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
# 文件操作单独开一个循环
for tmp in tmp_path:
shutil.copy(tmp, dest_dir)
# import os
# 测试1:非同一个目录下文件
src_path = '/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation'
dest_path = '/Users/lichizou/Documents/dw/team-learning-program/png2_dir'
copy_file_by_type(src_path, 'png', dest_path)
# 测试2: 同一个目录下文件
rc_path = '/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation'
dest_path = 'png2_dir'
copy_file_by_type(src_path, 'png', dest_path)
2) 、一些不需要的、 巨大的文件或文件夹占据了硬盘的空间, 这并不少见。如果你试图释放计算机上的空间, 那么删除不想要的巨大文件效果最好。但首先你必须找到它们。编写一个程序, 遍历一个目录树, 查找特别大的文件或文件夹, 比方说, 超过100MB 的文件(回忆一下,要获得文件的大小,可以使用 os 模块的 os.path.getsize())。将这些文件的绝对路径打印到屏幕上。
# 找到指定目录下文件大小大于某个值的文件,并打印绝对路径
def get_file_oversize(path, limit_size):
if not os.path.exists(path):
return
over_file = {} # 存储超过的文件及大小
for root, dir, files in os.walk(path):
for file in files:
path = os.path.join(root, file)
size = os.path.getsize(path)
#print(file_name)
if size >= limit_size:
over_file[os.path.abspath(path)] = size
for f, s in over_file.items():
print(f'{f} : {s}')
# 测试:
path = '/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation'
min_size = 100000 # 100kb
get_file_oversize(path, min_size)
/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/img.zip : 1129787
/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/png2_dir/pycharm2.png : 131442
/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/img_unzip/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/周杰伦.jpg : 112238
/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/img_unzip/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/pycharm2.png : 131442
/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/周杰伦.jpg : 112238
/Users/lichizou/Documents/dw/team-learning-program/OfficeAutomation/图片/pycharm2.png : 131442
3)、编写一个程序, 在一个文件夹中, 找到所有带指定前缀的文件, 诸如 spam001.txt,spam002.txt 等,并定位缺失的编号(例如存在 spam001.txt 和 spam003.txt, 但不存在 spam002.txt)。让该程序对所有后面的文件改名, 消除缺失的编号。作为附加的挑战,编写另一个程序,在一些连续编号的文件中,空出一些编号,以便加入新的文件。
def get_file_order(path):
return int(''.join(list(filter(str.isdigit, path))))
get_file_order('unorder_dir/spam00103.txt')
103
os.path.dirname('unorder_dir/spam00103.txt')
'unorder_dir'
os.path.basename('unorder_dir/spam00103.txt')
'spam00103.txt'
# 获取文件后缀
os.path.splitext('unorder_dir/spam00103.1.txt')[-1]
'.txt'
# 获取文件编号
n = 5
int(os.path.splitext('unorder_dir/spam00103.txt')[0][-n:])
103
s1 = 'unorder_dir/spam00103.txt'
s2 = 'unorder_dir/spam00003.txt'
s1 = s1.replace('00103','111')
s1
'unorder_dir/spam111.txt'
# 不改变原文件路径
def set_file_order(path, order, fill_num):
return path.replace(os.path.splitext(path)[0][-fill_num:], str(order).zfill(fill_num))
set_file_order('unorder_dir/spam00103.txt', 1, 5)
'unorder_dir/spam00001.txt'
for index, file in enumerate(['1','2','3'],):
print(index, file)
2 1
3 2
4 3
import time
time.strftime('%y%m%d%H%L%M%S',time.localtime(time.time()))
'21061615L3253'
# (1):
# 对指定编号文件,按照编号顺序,让后面的编号前移向前填充使编号连续
# 找到指定前缀文件,根据名称排序,这个相对顺序就是重命名后序号依据
def rename_file_by_order(path, file_prefix, fill_num):
if not os.path.exists(path):
return
# 找到带特定前缀文件,并按序号排序
file_arr = []
for root, dirs, files in os.walk(path):
for file in files:
file_path = os.path.join(root, file)
if os.path.basename(file_path).startswith(file_prefix):
file_arr.append(file_path)
file_arr.sort()
first_order = get_file_order(file_arr[0])
# 新文件路径
new_file_arr = []
for index, file in enumerate(file_arr, 0):
new_order = first_order + index - 0
new_name = set_file_order(file, new_order, fill_num)
print(f'{file}->{new_name}')
new_file_arr.append(new_name)
# 先复制到一个缓存文件夹,然后将缓存移动夹move到原文件夹覆盖
tmp_dir = time.strftime('%y%m%d%H%L%M%S',time.localtime(time.time()))
os.makedirs(tmp_dir)
for index, file in enumerate(file_arr):
shutil.copy(file, os.path.join(tmp_dir, os.path.basename(new_file_arr[index])))
# 目录移动,删除原文件夹,移动过去
send2trash.send2trash(path)
shutil.move(tmp_dir, path)
# 生成模拟数据,已经存在一律删除,重新生成新的干净数据
def get_test_file(new_dir, file_prefix, fill_num, max_range, divisor, remainder):
if os.path.exists(new_dir):
send2trash.send2trash(new_dir) # 扔到废纸篓
os.makedirs(new_dir)
for i in range(1, max_range):
if i % divisor == remainder:
path = file_prefix + str(i).zfill(fill_num) + '.txt'
#print(path)
new_file = open(path, 'w')
new_file.write(path)
new_file.close()
shutil.move(path, new_dir)
get_test_file('unorder_dir', 'spam', 5, 100, 2, 1)
rename_file_by_order('unorder_dir', 'spam', 5)
unorder_dir/spam00001.txt->unorder_dir/spam00001.txt
unorder_dir/spam00003.txt->unorder_dir/spam00002.txt
unorder_dir/spam00005.txt->unorder_dir/spam00003.txt
unorder_dir/spam00007.txt->unorder_dir/spam00004.txt
unorder_dir/spam00009.txt->unorder_dir/spam00005.txt
unorder_dir/spam00011.txt->unorder_dir/spam00006.txt
unorder_dir/spam00013.txt->unorder_dir/spam00007.txt
unorder_dir/spam00015.txt->unorder_dir/spam00008.txt
unorder_dir/spam00017.txt->unorder_dir/spam00009.txt
unorder_dir/spam00019.txt->unorder_dir/spam00010.txt
unorder_dir/spam00021.txt->unorder_dir/spam00011.txt
unorder_dir/spam00023.txt->unorder_dir/spam00012.txt
unorder_dir/spam00025.txt->unorder_dir/spam00013.txt
unorder_dir/spam00027.txt->unorder_dir/spam00014.txt
unorder_dir/spam00029.txt->unorder_dir/spam00015.txt
unorder_dir/spam00031.txt->unorder_dir/spam00016.txt
unorder_dir/spam00033.txt->unorder_dir/spam00017.txt
unorder_dir/spam00035.txt->unorder_dir/spam00018.txt
unorder_dir/spam00037.txt->unorder_dir/spam00019.txt
unorder_dir/spam00039.txt->unorder_dir/spam00020.txt
unorder_dir/spam00041.txt->unorder_dir/spam00021.txt
unorder_dir/spam00043.txt->unorder_dir/spam00022.txt
unorder_dir/spam00045.txt->unorder_dir/spam00023.txt
unorder_dir/spam00047.txt->unorder_dir/spam00024.txt
unorder_dir/spam00049.txt->unorder_dir/spam00025.txt
unorder_dir/spam00051.txt->unorder_dir/spam00026.txt
unorder_dir/spam00053.txt->unorder_dir/spam00027.txt
unorder_dir/spam00055.txt->unorder_dir/spam00028.txt
unorder_dir/spam00057.txt->unorder_dir/spam00029.txt
unorder_dir/spam00059.txt->unorder_dir/spam00030.txt
unorder_dir/spam00061.txt->unorder_dir/spam00031.txt
unorder_dir/spam00063.txt->unorder_dir/spam00032.txt
unorder_dir/spam00065.txt->unorder_dir/spam00033.txt
unorder_dir/spam00067.txt->unorder_dir/spam00034.txt
unorder_dir/spam00069.txt->unorder_dir/spam00035.txt
unorder_dir/spam00071.txt->unorder_dir/spam00036.txt
unorder_dir/spam00073.txt->unorder_dir/spam00037.txt
unorder_dir/spam00075.txt->unorder_dir/spam00038.txt
unorder_dir/spam00077.txt->unorder_dir/spam00039.txt
unorder_dir/spam00079.txt->unorder_dir/spam00040.txt
unorder_dir/spam00081.txt->unorder_dir/spam00041.txt
unorder_dir/spam00083.txt->unorder_dir/spam00042.txt
unorder_dir/spam00085.txt->unorder_dir/spam00043.txt
unorder_dir/spam00087.txt->unorder_dir/spam00044.txt
unorder_dir/spam00089.txt->unorder_dir/spam00045.txt
unorder_dir/spam00091.txt->unorder_dir/spam00046.txt
unorder_dir/spam00093.txt->unorder_dir/spam00047.txt
unorder_dir/spam00095.txt->unorder_dir/spam00048.txt
unorder_dir/spam00097.txt->unorder_dir/spam00049.txt
unorder_dir/spam00099.txt->unorder_dir/spam00050.txt
# (2)对指定前缀带顺序编号文件夹,在一些连续编号的文件中,空出一些编号,以便加入新的文件
# 即在重新编排文件名时,某个顺序段空出来不允许使用
# 在rename_file_by_orde基础上增加两个参数,兼容原来函数
def rename_file_by_order_with_space(path, file_prefix, fill_num, star_space = 0, end_space = 0):
if not os.path.exists(path):
return
# 找到带特定前缀文件,并按序号排序
file_arr = []
for root, dirs, files in os.walk(path):
for file in files:
file_path = os.path.join(root, file)
if os.path.basename(file_path).startswith(file_prefix):
file_arr.append(file_path)
file_arr.sort()
first_order = get_file_order(file_arr[0])
#print(f'{first_order}')
# 新文件路径
new_file_arr = []
#new_file_arr.append(file_arr[0])
for index, file in enumerate(file_arr, 0):
new_order = first_order + index - 0
if star_space < end_space and new_order >= star_space: # 这里修改order,统一往end_space后挪
new_order = new_order + (end_space - star_space) + 1
new_name = set_file_order(file, new_order, fill_num)
#print(f'{file}->{new_name}')
new_file_arr.append(new_name)
# 先复制到一个缓存文件夹,然后将缓存移动夹move到原文件夹覆盖
tmp_dir = time.strftime('%y%m%d%H%L%M%S',time.localtime(time.time()))
os.makedirs(tmp_dir)
for index, file in enumerate(file_arr):
shutil.copy(file, os.path.join(tmp_dir, os.path.basename(new_file_arr[index])))
# 目录移动,删除原文件夹,移动过去
send2trash.send2trash(path)
shutil.move(tmp_dir, path)
get_test_file('unorder_space_dir', 'spam', 4, 100, 3, 0)
rename_file_by_order_with_space('unorder_space_dir', 'spam', 4, 5, 10)
3.自动发邮件
SMTP协议
# smtplib:发送邮件
# email: 构造邮件格式和内容
# 1.导入库
import smtplib
from smtplib import SMTP_SSL # 加密邮件内容,防止中途被截获
from email.mime.text import MIMEText # 构造邮件正文
from email.mime.image import MIMEImage # 构造邮件图片
from email.mime.multipart import MIMEMultipart # 邮件主体
from email.header import Header # 邮件文件头,标题,收件人
# 2.设置邮箱域名,发件人邮箱,邮箱授权码,收件人邮箱
host_server = 'smtp.126.com'
sender_126 = 'zymb_1704@126.com' # 发送人邮箱
pwd = 'PGJDEVEPSXWYQOQL' # 邮箱授权码
#receiver = 'chizou1735@gamil.com' # 收件人,被退回
receiver = 'zuoyi1268@126.com' # 收件人
# 3.构建MIMEMultipart对象,即邮件,可以往里面添加文本,附件,图片等
msg = MIMEMultipart()
# 4. 设置邮件头部内容
mail_title = 'python办公自动化-自动发邮件'
msg['Subject'] = Header(mail_title, 'utf-8')
msg['From'] = sender_126
msg['To'] = Header(receiver, 'utf-8')
# 5. 添加正文文本
mail_content = '哈哈哈哈,这是我用python脚本写的自动发邮箱,快看收到了吗,来自126'
# 构造文本:正文,文本格式,编码方式
message_text = MIMEText(mail_content, 'plain', 'utf-8')
msg.attach(message_text) # 添加文本到邮件
# 6. 添加图片
image_add = open('./图片/Excel.png', 'rb') # 二进制读取图片
message_image = MIMEImage(image_add.read()) # 获取图片二进制数据
image_add.close()
msg.attach(message_image) # 添加图片到邮件
# 7. 添加附件
path = './图片/excel到word.xlsx'
atta = MIMEText(open(path, 'rb').read(), 'base64', 'utf-8') # 构造附件
atta['Content-Disposition'] = 'attachment; filename = ' + path # 设置附件
msg.attach(atta) # 添加附件到邮件
# 8. 发送邮件
smtp = SMTP_SSL(host_server)
smtp.login(sender_126, pwd)
smtp.sendmail(sender_126, receiver, msg.as_string())
smtp.quit()
(221, b'Bye')