目录

文件操作

文件备份

文件定位

模块导入

os模块制作


文件操作

文件操作的一般步骤:

打开文件、读/写文件 、保存文件 、关闭文件

打开文件用open函数,一般我们默认的编码是gbk,最好的习惯是我们再打开一个文件给他指定一个编码类型。

写文件(w)

fobj=open('./Test.txt','w',encoding='utf-8') #前面是路径,后面是打开方式 w只写
#开始操作 读/写操作
fobj.write('在苍茫的大海上')
fobj.write('狂风卷积着乌云')
fobj.close() #关闭文件后,才能写到文件上


以二进制的形式去写数据(wb)


fobj=open('Test_1.txt','wb')#wb以二进制的方式写入
fobj.write('在乌云和大海之间'.encode('utf-8'))
fobj.close()

追加(a)

fobj=open('Test.txt','a')#a追加,不会覆盖  ab以二进制方式追加
fobj.write('在苍茫的大海上')
fobj.write('狂风卷积着乌云')
fobj.write('在乌云和大海之间\n')
fobj.write('海燕像黑色的闪电\n')
fobj.close()

读数据(r)

f=open('Test.txt','r')
print(f.read()) #read读取了所有数据
print(f.read(10)) #读取的字符个数为10
print(f.read())#当上面读完10个字节后,接着后面的读
print(f.readline())#读一行
print(f.readlines())#读取所有行,返回一个列表
f.close()

以二进制的形式去读数据(wb)

f=open('Test.txt','rb')
data=f.read()
print(data)
print(data.decode('gbk')) #解码
f.close()

with是上下文管理对象

它的优点是可以自动的释放打开关联的对象

with open('Test.txt','a') as f:
    #print(f.read())
    f.write('我觉的python非常好学\n')

总结:

文件读写的几种操作方式 read r r+ rb rb+.

r r+ 只读 适用于普通场景.

rb rb+ 适用于文件、图片、视频、音频这样的文件.

write w w+ wb+ wb a ab w.

wb+ w+ 每次都会去创建文件.

二进制读写的时候,要注意编码问题,默认情况下,我们写入的文件是gbk.

a ab a+ 在原有的文件的基础上追加(文件指针末尾)追加,并不会每次都创建一个新的文件.

文件备份 

利用脚本完成自动备份,要求用户输入文件名称,完成自动备份

#文件的备份
def copyfile():
    #接受用户输入的文件名
    old_file=input('请输入要备份的文件名:')
    file_list=old_file.split('.') #分隔文件名和后缀
    #构造新的文件名.加上备份的后缀
    new_file=file_list[0]+'_备份.'+file_list[1]
    old_f=open(old_file,'r') #打开需要备份的文件
    new_f=open(new_file,'w') #以写的模式去打开新文件,如果这文件不存在则创建
    content=old_f.read() #将文件内容读取出来
    new_f.write(content) #将内容写入到备份文件当中
    old_f.close()
    new_f.close()
    pass

copyfile()

对上面的代码可以优化

def copyBigfile():
    #接受用户输入的文件名
    old_file=input('请输入要备份的文件名:')
    file_list=old_file.split('.') #分隔文件名和后缀
    #构造新的文件名.加上备份的后缀
    new_file=file_list[0]+'_备份.'+file_list[1]
    try:
        #监视要处理的逻辑
        with open(old_file,'r') as old_f,open(new_file,'w') as new_f:
            while True:
                content=old_f.read(1024) #一次性读取1024个字符
                new_f.write(content)
                if len(content)<1024:
                    break
    except Exception as msg:
        print(msg)

    pass

copyBigfile()

文件定位

文件定位,指的是当前文件指针读取到的位置,光标位置。在读写文件的过程中,如果想知道当前的位置,可以使用tell()来获取。

with open('Test.txt','r') as f:
    print(f.read(3))
    print(f.tell()) #6
    print(f.read(2))
    print(f.tell()) #10
    pass

如果读中文,一个字相当于两个字节

truncate函数 可以对源文件进行截取操作

fobjB=open('Test.txt','r')
print(fobjB.read())
fobjB.close()
print('截取之后的数据........')

fobjA=open('Test.txt','r+')
fobjA.truncate(15) #保留前15个字符
print(fobjA.read())
fobjA.close()

如果在操作文件的过程,需要定位到其他位置进行操作,用seek()。 seek(offset, from)有2个参数,offset,偏移量单位字节,负数是往回偏移,正数是往前偏移,from位置:0表示文件开头,1表示当前位置,2表示文件末尾。

with open('Test_备份.txt','rb') as f:
    f.seek(4,0) #光标是从0的位置开始 像前【右】移动 4个字符
    data=f.read(2)
    print(data.decode('gbk'))
    f.seek(-2,1) #相当于光标又设置到了0的位置
    print(f.read(4).decode('gbk'))
    f.seek(-6,2) #2 表示光标在末尾处  往回移动了6个字符
    print(f.read(4).decode('gbk'))
    pass

1对于上面这种情况 用'r'这种模式打开文件,在文本文件中,没有使用二进制的选项打开文件, 只允许从文件的开头计算相对位置,从文件尾部计算或者当前计算的话 就会引发异常。

模块导入

模块导入有两种方法:

1.import xxx

import 在首次导入模块的时候 会发生如下3步操作

1,打开模块文件

2.执行模块对应的文件,将执行过程中产生的名字都丢到模块的名称空间 

3.在程序会有一个模块的名称指向模块的名称空间去。

2.from...import

 from...import 首次导入发生了3个步骤

1.以模块为准创建一个模块的空间

 2.执行模块对应的文件,将执行过程中产生的名字都丢到模块的名称空间

 3.在当前执行文件的名称空间中拿一个名字,改名字直接指向模块中的某一个名字,意味着可以不用加任何的前缀,而是直接使用

 优点:不用加前缀,代码更加简洁了

缺点:容易与当前执行文件中名称空间中的名字冲突

俩种方法的相同点:

1.都会执行模块对应的文件,都会产生模块的名称空间

2.两者在调用功能时,都需要转到定义时寻找作用域关系

不同点:

import需要加前缀,from...import不需要加前缀

from time import * #全部导入

import导入方式

import time
print(time.ctime()) #调用模块中的函数

from...import导入方式

from time import ctime,time #部分导入
print(ctime()) #直接使用

os模块制作 

os模块就是对文件进行操作,我们以代码形式讲解os模块里面部分函数的用法。

os.rename('Test.txt','Test_重命名.txt') #文件重命名
os.remove('要删除的文件.py') #删除文件
os.mkdir('TestCJ')#创建文件夹,只能创建一级目录
os.rmdir('TestCJ') #删除文件夹,只能删除空目录
os.makedirs('d:/python/sub') #创建多级文件目录

#如果想要删除非空目录,要调用shutil模块
shutil.rmtree('d:/python/sub') #非空删除

#获取当前目录
print(os.getcwd())
#路径的拼接
print(os.path) #os模块的路径
print(os.path.join(os.getcwd(),'venv'))

获取python中的目录列表有两种方法

方法1:

listRs=os.listdir('G:/') #方法1
for dirname in listRs:
    print(dirname)
    pass

方法2:scandir和with一起使用,这样的话,上下文管理器会在迭代器遍历完成后自动的去释放资源

with os.scandir('G:/') as entries:
    for entry in entries:
        print(entry.name)
        pass
    pass

打印目录下的文件

basePath='g:/'
for entry in os.listdir(basePath):
    # if os.path.isfile(os.path.join(basePath,entry)): #判断是否为文件
    #     print(entry)
    if os.path.isdir(os.path.join(basePath,entry)): #判断是否为目录
        print(entry)

下面简单补充几个知识:

1.all变量的作用,如果在一个文件存在__all__变量,那么也就意味着这个变量的元素会被from xxx import *时会被导入,对于import xxx all是不影响的

2.if __name__=='__main__' 这个代码是为了保证在别的地方调用时,不会执行if下面的代码。