目录
文件打开模式:w w+ wb+ (二进制格式打开文件) [写文件]
文件打开模式:r r+(只读) rb rb+(二进制格式打开文件) [读文件]
文件打开模式:a a+ ab+ (二进制格式打开文件) [文件追加内容]
一、文件操作
文件操作是很常见的功能,python自带文件的基本操作方法,但是借助os等模块更加方便快捷。
- 通过使用文件的打开关闭、读写等,完成文件备份脚本(重点)
- 通过文件定位的相关方法,完成精确控制文件读写
- 使用os模块操作文件,提高效率(重点)
- 使用time、datetime模块完成时间相关操作(重点)
- 通过模块的制作、发布、安装,进一步明白模块的意义
(一)文件打开和关闭
打开文件: f = open( '文件名称' , '打开方式' )
文件打开模式:
关闭文件:f . close( )
注意:打开一个文件之后,一定要关闭,否则后面无法继续操作这个文件;使用with上下文管理 更加方便,不需要手动关闭文件,不管在处理文件过程中是否发生异常,都能保证with语句执行完毕之后已经关闭打开的文件句柄。
(二)文件读写
文件打开模式:w w+ wb+ (二进制格式打开文件) [写文件]
中文字符的默认编码是GBK; 二进制格式打开文件后,输入中文字符需要转化为utf-8格式,即.encode('utf-8')
write( ' 参数 ' ) :参数就是需要写入的内容
writelines( [ '我','爱' ,'我的' ,'祖国' ] ) : 可传入一个可迭代对象
F=open('Test.txt','w') # 打开一个文件只用于写入;文件存在即覆盖,不存在即创建
F.write('在苍茫的大海上')
F.write('狂风卷积着乌云') #将这两句写入文件'Test.txt'
F.close()
F=open('Test.txt','wb') # 以二进制的格式打开一个文件只用于写入;文件存在即覆盖,不存在即创建
F.write('在苍茫的大海上'.encode('utf-8'))
F.write('狂风卷积着乌云'.encode('utf-8')) # 二进制写入中文字符数时必须加 .encode('utf-8')
F.close()
文件打开模式:r r+(只读) rb rb+(二进制格式打开文件) [读文件]
- 图片、视频、音频都会用到二进制的读取并!
- 使用二进制模式打开文件时,输出的是二进制,要想看到字符需要先解码转化成gbk格式: . decode( ' gbk ' )。不适用二进制格式打开文件时,不需要decode解码。
读取文件read( ),将文件的内容全部读取出来。
f=open('test.txt','r')
f.read() # 一次性将文件内容全部取出
f.close()
读取指定字符个数: read(num )传入一个数字做参数,表示读取指定字符个数。
f=open('test.txt','r')
content = f.read(2) # 读取两个字符
print(content)
content = f.read()
print(content) # 第二次读取将从第一次读取的位置继续读取
f.close
按行读取 readlines ( ):一次性读取所有内容,返回一个列表,每一行内容作为一个元素。
f=open('test.txt','w')
f.write('hello world\nhello world\nhello world\n') # 写入多行hello world
f.close
f=open('test.txt','rb')
content=f.readlines() # 一次性读取所有内容,返回一个列表,列表元素为每一行内容
print(content.decode('gbk'))
f.close
按行读取readline (): 但是每次只读取一行
f = open('test.txt', 'rb')
content = f.readline() # 按行读取,一次读取一行
print(content.decode('gbk'))
f.close() # 关闭文件
文件打开模式:a a+ ab+ (二进制格式打开文件) [文件追加内容]
注意:
- 在原有文件的的基础之后去追加,不会每次都去创建新文件。
- 打开模式是ab+时(二进制格式打开文件),此时需要将我们追加的字符转化为二进制格式后再追加到文件中: . encode( ' utf-8 ' ) 。不使用二进制格式打开文件时不需要encode。
f=open('test.txt','ab')
f.write('我和我的祖国\n'.encode('utf-8'))
f.write('狂风卷积着乌云\n'.encode('utf-8'))
f.write('我和我的祖国\n'.encode('utf-8'))
f.close()
(三)文件备份
文件较小:
def copyFile():
old_File=input('请输入你需要备份的文件:') # 接受用户输入的文件名
if not old_File:
print('[error]请输入正确的文件路径')
return old_FileList=old_File.split('.')
if len(old_File)<2:
new_File=old_FileList[0]+'_备注'
else:
new_File=old.FileList[0]+'_备注'+old.FileList[1]
old_f=open(old_File,'r') # 文件操作:打开老文件,读取老文件,将老文件的内容读取出来,写入新文件
new_f=open(new_File,'w')
content=old_f.read()
new_f.write(content)
print(new_f)
old_f.close() #所有文件打开必须关闭
new_f.close()
pass
copyFile()
超大文件:限定每次读取的数据量,利用一个循环。
def copyfile():
old_file = input('请输入要备份的文件名:'0 # 接收用户输入的文件名
if not old_file: # 如果没有输入文件名则打印提示
print('[ERROR]: 请输入正确的文件路径')
return file_list = old_file.split(".") # 构造新的文件名,加上备份后缀
if len(file_list) < 2:
new_file = file_list[0] + '_备份.'
else: # 文集名没有后缀的情况
new_file = file_list[0] + '_备份.' + file_list[1]
try: #监视要处理的逻辑,以防出错,try-except
with open(old_file,'r') as old_f,open(new_file,'w') as new_f: # 利用with上下文管理打开新旧文件
while True: # 根据需要多循环几次
content=old_f.read(1024) # 设置读取的数据量--read(num):一次性读取num个字符
new_f.write(content)
if len(content)<1024:
break
except Exception as msg:
print(msg)
pass
coppyFile()
复制一个文件夹或者拷贝一个文件中的某些部分,都可以通过这种方式完成。
(四)文件定位---- tell( )、seek( )
文件定位,指的就是指的是当前文件指针读取到的位置,光标位置。
1. 在读写文件的过程中,如果想知道当前的位置,可以使用tell()来获取。
with open('Test.txt','r') as f:
f.read(3)
print(f.tell()) #输出6,一个中文字符等于6个字节
f.read(2)
print(f.tell()) #输出10
pass
2. 对原文件的截取操作:truncate(num)----截取原文件前num个字节的内容更新原文件,即只保留文件的前num字节的内容。
f=open('Test.txt','r+') #要用文件的截取操作truncate,使用打开模式r+
f.truncate(6) #截取fobjB前6个字节的内容。之后相当于更新了文件fobjB
print(f.read()) #此时输出的是原文件中前6个字节的数据
f.close()
3. 在操作文件的过程中,需要定位到其他位置进行操作,用seek(offset,from)。
offset :偏移量单位字节,负数是往回偏移,正数是往前偏移。
from位置:0表示文件开头,1表示当前位置,2表示文件末尾。
打开模式是 rb 时,规则如上。
打开模式是 r 时,它只允许从文件的开头【from=0】计算相对位置。从文件尾部或当前位置开始计算相对位置就会发生异常。
with open('test.txt','rb') as f: #打开模式是rb
f.read(3)
print(f.tell()) #输出:3-----> 3个英文字符
f.seek(-2,1) #从当前位置开始,往左移2个字节
print(f.tell()) #输出:1
f.seek(4,0) #从开头开始,往右移4个字节
print(f.tell()) #输出:8
pass
二、模块
(一)模块介绍
内置模块、自定义模块、第三方模块
导入模块三种方法:
- import time as mytime #导入time中的全部函数; as 用于给函数取别名
- from time import ctime,time #导入time中的部分函数---ctime,time
- from time import * #导入time中的全部函数
【 import xxx ]首次导入模块的时候,就发生如下三个步骤:
- 打开模块文件
- 执行模块对应的文件,将执行过程中产生的名字都丢到模块的名称空间里去
- 在程序中会有一个模块的名称【time . 】指向模块的名称空间去【time.ctime】
【 from xxx import xx 】首次导入模块会发生的三个步骤:
- 以模块为准创造一个模块的名称空间
- 执行模块对应的文件,将执行过程中产生的名字都丢到模块对应的名称空间中去
- 在当前执行文件的名称空间中拿到一个名字【ctime】,该名字直接指向模块中某个名字:意味着直接指向模块中的某个名字,不需要加任何前缀而直接使用-----优点:不需要加任何前缀,代码简洁; 缺点:容易与当前执行文件中名称空间中的名字其冲突
调用模块方法: 模块名 . 函数名()
- time.ctime() #第一种导入方法:调用time中的ctime函数
- 或 mytime.time #用as取别名时,利用模块的【别名】调用函数
- ctime() #第二种、第三种导入方法
import xx 需要加前缀; from xx from xx 不需要加前缀。
如何查看电脑的python安装的目录:
在cmd中,输入【where python】即可获得python的安装目录
(二)os模块操作文件
- 对文件进行重命名、删除等一些操作,在python中可以利用os模块。
- os模块提供一些系统级别的操作命令。
方法 | 解释 |
os.getcwd() | 获取当前工作目录,即当前python脚本工作的目录路径 |
os.chdir("dirname") | 改变当前脚本工作目录;相当于shell下cd |
os.curdir | 返回当前目录: ('.') |
os.pardir | 获取当前目录的父目录字符串名:('..') |
os.makedirs('dir1/dir2') | 可生成多层递归目录 |
os.removedirs('dirname1') | 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 |
os.mkdir('dirname') | 生成单级目录;相当于shell中mkdir dirname。例如:os.mkdir('gl') |
os.rmdir('dirname') | 删除单级空目录,若目录不为空则无法删除,报错。例:os.rmdir('gl') |
os.listdir('dirname') | 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 |
os.remove("dirname ") | 删除一个文件。例如:os.remove('3.py') |
os.rename("oldname","new") | 重命名文件/目录。例如:os.rename('1.py','666.py') |
os.stat('path/filename') | 获取文件/目录信息 |
os.sep | 操作系统特定的路径分隔符,win下为"\\",Linux下为"/" |
os.linesep | 当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" |
os.pathsep | 用于分割文件路径的字符串 |
方法 | 解释 |
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.join(os.getcwd(),'gl') |
os.path.getatime(path) | 返回path所指向的文件或者目录的最后存取时间 |
os.path.getmtime(path) | 返回path所指向的文件或者目录的最后修改时间 |
- os.rename('Test.txt','Test_重命名.txt') #修改文件名
- os.remove('Test.txt') #删除文件,前提是文件必须存在
- os.mkdirs('Test.txt') #在当前路径下创建一级文件夹目录
- os.makedirs( ) #在当前路径下创建多级文件夹目录
- os.mkdir('e:/Python编程') #在e盘(其他路径)下创建文件夹
- os.rmdir('Test.txt') #当前路径下删除空目录
- shutil.rmdir('e:/python') #import shutil:删除非空目录
- print(os.getwd( )) #获取当前工作目录
- os.path.join(os.getwd , 'Test.txt ') #路径的拼接:当前目录和文件Test拼接
- os.listdir( 'd:/' ) #列出D盘中所有文件和子目录(一级目录),以列表格式输出
- os.scandir( 'd:/' ) #和with上下文管理器一起使用,返回的是迭代器对象,也是目标路径写的所有子目录和文件
# 老版本 .listdir() 用法
ListRs=os.listdir('d:/')
print(ListRs)
for item in ListRs:
print(item)
#新版本 .scandir() 用法;和with上下文管理器结合使用
with os.scandir('d:/') as entries: #entries是一个迭代器,也需要for遍历
for entry in entries:
print(entry) #输出的时字典
print(entry.name) #输出字典的name--->文件名、目录名
打印某个路径下的文件、目录:
basePath='e:/' #确定路径
for entry in os.listdir(basePath):
#判断 os.path.join(basePath,entry) 是否是文件
if os.path.isFile(os.path.join(basePath,entry)):
print(entry)
pass
判断 os.path.join(basePath,entry) 是否是目录---文件夹
if os.path.isdir(os.path.join(basePath,entry)):
print(entry)
pass
(三)time、datetime模块
import timetime.sleep(num) #让程序执行暂停num秒,num单位是秒
datetime模块主要用于时间计算
- import datetime
- #返回 2017-12-08 15:00:18.312624
- print(datetime.datetime.now())
- #时间戳直接(1512715165.0285344)转成日期格式 2017-12-08
- print(datetime.date.fromtimestamp(time.time()))
- print(datetime.datetime.now() )
- #当前时间+3天
- print(datetime.datetime.now() + datetime.timedelta(3))
- #当前时间-3天
- print(datetime.datetime.now() + datetime.timedelta(-3))
- #当前时间+3小时
- print(datetime.datetime.now() + datetime.timedelta(hours=3))
- #当前时间+30分.
- print(datetime.datetime.now() + datetime.timedelta(minutes=30))
- #当前时间+1小时30分.
- print(datetime.datetime.now() + datetime.timedelta(hours=3,minutes=30))
(四)模块制作(自定义模块)
模块定义: 在python当中,一个 .py文件就是一个模块。 python文件都可以作为一个模块,模块的名字就是文件名。
作用: 可以使我们有逻辑的去组织我们的python代码。以库的形式去封装功能,非常方便的去让调用者去使用。模块内可以定义函数 类 变量,也能包含可执行的代码
注意:不同的模块可以定义相同的变量名,但是每个模块中的变量名的作用域只是在本模块中。
(1)Python文件都可以作为一个模块,模块的名字就是文件的名字。 比如创建一个test.py文件,文件中创建一个add函数。test.py就是一个模块。
(2)调用test.py模块
(3)模块测试 :一般写完模块之后都会进行测试,下面来看下这个例子 写好模块之后,在模块中写了一段测试的代码。
在main.py 导入test模块,执行时模块中的测试代码也执行了。
(4)为了避免这种情况使用到一个__name__的变量。
在main.py中导入执行
知道__name__变量的原理之后,就可以很好的处理测试代码了。 将测试的代码放到 if __name__ = '__main__':
if __name__=="__main__"
res=add(3,4)
print('模块__name__变量=%s'%__name__)
#此时在文件A中导入该模块,只会出现A中的答案;不会出现原文件模块中的测试结果。
如果模块文件中存在__all__魔术变量时,并且文件A中使用【from xx import *】导入模块时,只有__all__变量声明过的函数才能被允许调用。有all变量import方式导入,可以无异常,可以正常使用
(五)模块的发布
平时使用的第三方模块都是其他开发者发布出来的,需要安装后调用。安装步骤如下:
from distutils.core import setup
# name 模块名称(最后的压缩包的名字)
# version 版本号
# description 描述
# author 作者
# py_modules 要发布的内容
setup(name="yaofabudebao", version="1.0", description="文件统计模块",
author="lilei", py_modules=['makingmode'})
(3)创建模块
- 打开终端:python右下角的Terminal---->输入模块的文件名---->输入:python setup.py build
- 出现如下代码,说明完成该步骤:
running build
running build_py
creating build
creating build\lib
copying makingmode.py -> build\lib
(4)生成压缩包
在上一步的终端处,接着输入:Python setup.py sdist,然后运行即可生成压缩包。
(5) 看makingmode目录中dist里是否有压缩包,即jiaoxue/目录下dist中是否有压缩包my_module-1.0.tar.gz,这个压缩包就可以发布给别人安装。
(六)模块的安装
(1)pycharm中新建一个new project:SetupTestPro
(2)放在一个文件夹A中(假设在D盘),可以不解压,python解释器会自动解压
(3)在SetupTestPro中,进入终端Terminal,先进入D盘-----> d:
D盘有很多文件,找到我们的模块压缩包进行下载:【pip install yaofabudebao-1.0.tar.gz】
(4)安装成功就可以调用了!