一:文件路径
Python在不同系统中的文件路径编写的方法是不一样的。
1:linux 和 Mac
使用正斜杠 "/" 作为它们的路径分隔符。
2:windows
路径书写使用反斜杠 "" 作为文件夹之间的分隔符。
如果想要程序运行在所有操作系统上,在编写 Python 脚本时,就必须处理这两种情况。
那么,该如何处理下边的情况呢?
import os
myFiles = ['accounts.txt', 'details.csv', 'invite.docx']
for filename in myFiles:
print(os.path.join('C:\demo\exercise', filename))
输出:
C:\demo\exercise\accounts.txt
C:\demo\exercise\details.csv
C:\demo\exercise\invite.docx
二:绝对路径和相对路径
如下图所示:
Python为我们提供了处理路径的函数:
调用 os.path.abspath(path) 将返回 path 参数的绝对路径的字符串,这是将相对路径转换为绝对路径的简便方法。
调用 os.path.isabs(path),如果参数是一个绝对路径,就返回 True,如果参数是一个相对路径,就返回 False。
调用 os.path.relpath(path, start) 将返回从 start 路径到 path 的相对路径的字符串。如果没有提供 start,就使用当前工作目录作为开始路径。
调用 os.path.dirname(path) 将返回一个字符串,它包含 path 参数中最后一个斜杠之前的所有内容;调用 os.path.basename(path) 将返回一个字符串,它包含 path 参数中最后一个斜杠之后的所有内容。
测试一下:
cmd = os.getcwd()
print(cmd)
abspath = os.path.abspath('.')
print(abspath)
abspath1 = os.path.abspath('.\Scripts')
print(abspath1)
isabs = os.path.isabs('.')
print(isabs)
isabs1 = os.path.isabs(os.path.abspath('.'))
print(isabs1)
relpath = os.path.relpath('C:\Windows', 'C:\')
print(relpath)
relpath1 = os.path.relpath('C:\Windows', 'C:\spam\eggs')
print(relpath1)
path = 'C:\Windows\System32\calc.exe'
basename = os.path.basename(path)
print(basename)
dirname = os.path.dirname(path)
print(dirname)
# 路径是否存在
exists = os.path.exists('C:\Windows')
print(exists)
# 将 文件路径 拆分成元组
path1 = 'C:\Windows\System32\calc.exe'
tup = os.path.split(path1)
print(tup)
输出:
F:\camellia\python\testProject
F:\camellia\python\testProject
F:\camellia\python\testProject\Scripts
False
True
Windows
....\Windows
calc.exe
C:\Windows\System32
True
('C:\Windows\System32', 'calc.exe')
三:python文件基本操作
1:open 函数用于创建或打开指定文件
具体如下图所示:
以上几种模式具体的区别如下图所示:
测试一下:
# 以默认方式打开文件
f = open('log.txt')
# 输出文件是否已经关闭
print(f.closed)
# 输出访问模式
print(f.mode)
#输出编码格式
print(f.encoding)
# 输出文件名
print(f.name)
输出:
False
r
cp936
log.txt
2:read() readline() 和 readlines() 函数
log.txt文件内容:
时间里的
https://guanchao.site
(1):read() 函数:逐个字节或者字符读取文件中的内容;
正常使用:
#以 utf-8 的编码格式打开指定文件
f = open("log.txt", encoding = "utf-8")
#输出读取到的数据
print(f.read())
#关闭文件
f.close()
输出:
时间里的
https://guanchao.site
使用 size 参数,指定 read() 每次可读取的最大字符(或者字节)数,例如:
#以 utf-8 的编码格式打开指定文件
f = open("log.txt",encoding = "utf-8")
#输出读取到的数据
print(f.read(4))
#关闭文件
f.close()
输出:
时间里的
读取二进制打开的文件内容:
#以二进制形式打开指定文件,该文件编码格式为 utf-8
f = open("log.txt",'rb+')
byt = f.read()
print(byt)
print("\n转换后:")
print(byt.decode('utf-8'))
#关闭文件
f.close()
输出:
b'\xe6\x97\xb6\xe9\x97\xb4\xe9\x87\x8c\xe7\x9a\x84\r\nhttps://guanchao.site'
转换后:
时间里的
https://guanchao.site
(2):readline() 函数:逐行读取文件中的内容;
readline() 函数用于读取文件中的一行,包含最后的换行符“\n”
f = open("log.txt",encoding = "utf-8")
# 读取一行数据
byt = f.readline()
print(byt)
输出:
时间里的
在逐行读取时,还可以限制最多可以读取的字符(字节)数,例如:
#以二进制形式打开指定文件
f = open("log.txt",'rb')
# 指定读取字节数
byt = f.readline(4)
print(byt)
输出:
b'\xe6\x97\xb6\xe9'
(3):readlines() 函数:一次性读取文件中多行内容。
readlines() 函数用于读取文件中的所有行,它和调用不指定 size 参数的 read() 函数类似,只不过该函数返回是一个字符串列表,其中每个元素为文件中的一行内容。
f = open("log.txt",'rb')
byt = f.readlines()
print(byt)
输出:
[b'\xe6\x97\xb6\xe9\x97\xb4\xe9\x87\x8c\xe7\x9a\x84\r\n', b'https://guanchao.site']
3:write()和writelines():向文件中写入数据
在使用 write() 向文件中写入数据,需保证使用 open() 函数是以 r+、w、w+、a 或 a+ 的模式打开文件,否则执行 write() 函数会抛出 io.UnsupportedOperation 错误。
(1):wtite()
f = open("log.txt", 'a', encoding="utf-8")
f.write("\n写入一行新数据")
f.close()
f = open("log.txt", encoding="utf-8")
aa = f.read()
print(aa)
f.close()
输出:
时间里的
https://guanchao.site
写入一行新数据
写入文件完成后,一定要调用 close() 函数将打开的文件关闭,否则写入的内容不会保存到文件中。例如,将上面程序中最后一行 f.close() 删掉,再次运行此程序并打开 log.txt,你会发现该文件是空的。这是因为,当我们在写入文件内容时,操作系统不会立刻把数据写入磁盘,而是先缓存起来,只有调用 close() 函数时,操作系统才会保证把没有写入的数据全部写入磁盘文件中。这个很重要 要注意
但是,在完成文件操作后,我不想使用close关闭文件就像读取到他的内容该怎么操作呢?
Python为我们提供了flush函数,它可以实现将缓冲区的数据写入文件中。
f = open("log.txt", 'a', encoding="utf-8")
f.write("\n写入一行新数据flush")
f.flush()
打开文件,我们可以看到:
时间里的
https://guanchao.site
写入一行新数据
写入一行新数据flush
有的同学可能会想到,通过设置 open() 函数的 buffering 参数可以关闭缓冲区,这样数据不就可以直接写入文件中了?对于以二进制格式打开的文件,可以不使用缓冲区,写入的数据会直接进入磁盘文件;但对于以文本格式打开的文件,必须使用缓冲区,否则 Python 解释器会 ValueError 错误。例如:
f = open("log.txt", 'w',buffering = 0)
f.write("写入一行新数据---关闭缓冲区之后")
输出:
Traceback (most recent call last):
File "F:/camellia/python/testProject/main.py", line 63, in <module>
import ospath
File "F:\camellia\python\testProject\ospath.py", line 70, in <module>
f = open("log.txt", 'w',buffering = 0)
ValueError: can't have unbuffered text I/O
(2):writelines()
writelines() 函数,可以实现将字符串列表写入文件中。
f = open('log.txt', 'r', encoding="utf-8")
n = open('log1.txt','w+', encoding="utf-8")
n.writelines(f.readlines())
n.close()
f.close()
打开log1.txt:
时间里的
https://guanchao.site
写入一行新数据
写入一行新数据flush
**
**
4:close() 关闭文件
Python的文件操作中,使用open创建/打开之后,必须使用close关闭。否则在某些操作的时候会报错:
import os
# 打开 / 创建文件
f = open("log.txt",'w')
# 删除文件
os.remove("log.txt")
输出报错:
Traceback (most recent call last):
File "F:/camellia/python/testProject/main.py", line 63, in <module>
import ospath
File "F:\camellia\python\testProject\ospath.py", line 83, in <module>
os.remove("log.txt")
PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问。: 'log.txt'
5:文件指针操作函数 tell() seek()
(1):tell()判断文件指针当前所处的位置
f = open("log.txt", 'r', encoding="utf-8")
print(f.tell())
print(f.read(10))
print(f.tell())
输出:
0
https://gu
10
(2):seek()将文件指针移动至指定位置
语法:
file.seek(offset[, whence])
其中,各个参数的含义如下:
file:表示文件对象;
whence:作为可选参数,用于指定文件指针要放置的位置,该参数的参数值有 3 个选择:0 代表文件头(默认值)、1 代表当前位置、2 代表文件尾。
offset:表示相对于 whence 位置文件指针的偏移量,正数表示向后偏移,负数表示向前偏移。例如,当whence == 0 &&offset == 3(即 seek(3,0) ),表示文件指针移动至距离文件开头处 3 个字符的位置;当whence == 1 &&offset == 5(即 seek(5,1) ),表示文件指针向后移动,移动至距离当前位置 5 个字符处。
示例:
f = open('log.txt', 'r', encoding="utf-8")
# 判断文件指针的位置
print(f.tell())
# 读取一个字节,文件指针自动后移1个数据
print(f.read(1))
print(f.tell())
# 将文件指针从文件开头,向后移动到 5 个字符的位置
f.seek(5)
print(f.tell())
print(f.read(1))
# 将文件指针从当前位置,向后移动到 5 个字符的位置
f.seek(1, 0)
print(f.tell())
print(f.read(1))
# 将文件指针从文件结尾,向前移动到距离 2 个字符的位置
f.seek(5, 0)
print(f.tell())
print(f.read(1))
输出:
0
h
1
5
:
1
t
5
:
四:python with语句
使用 with as 操作已经打开的文件对象(本身就是上下文管理器),无论期间是否抛出异常,都能保证 with as 语句执行完毕后自动关闭已经打开的文件。
with表达式其实是try-finally的简写形式。但是又不是全相同。
"""
格式
with context [as var]:
pass
"""
尝试一下,我项目根目录下有一个header.jpg文件。复制一个headerCopy.jpg,代码如下:
with open("header.jpg", 'rb') as src_file:
with open("headerCopy.jpg", 'wb') as target_file:
target_file.write(src_file.read())
可以看到,通过使用 with as 语句,即便最终没有关闭文件,修改文件内容的操作也能成功。
因此,一般在操作文件的时候,我们通常采用with语句。
With除了处理文件使用之外,还可以做其他使用:
class test(object):
def __enter__(self):
print("enter方法被调用!")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("销毁中~")
def show(self):
print("show方法被调用")
with test() as src_file:
src_file.show()
输出:
enter方法被调用!
我是方法
销毁中~
有好的建议,请在下方输入你的评论。