Python文件读写通过open函数及多种模式,使用read、write、readlines等方法操作数据,支持文件指针定位、备份、重命名、删除和文件夹管理,并涉及模块与包的导入、发布和安装,常搭配with语句自动关闭,还可处理文本与二进制文件及编码设置。
很多人都听过那句话:“好记性不如烂笔头”。
计算机也是同样的道理——程序运行大半天,终于算出结果,若不将数据保存下来,重启后一切归零,损失难以挽回。由此可见,数据持久化存储的重要性不言而喻。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
文件的核心作用就是让数据能够被持久化保存,下次程序启动时直接复用,避免重复计算,大大节省时间和精力。
在Python中,使用open函数可以打开已有文件或创建新文件。
f = open('test.txt', 'w')
参数说明:第一个参数是文件名,第二个参数是访问模式。模式决定了可以对文件执行哪些操作。下表列出了常见的访问模式:
| 访问模式 | 说明 |
|---|---|
| r | 以只读方式打开文件,文件指针位于文件开头,为默认模式。 |
| w | 以只写方式打开文件,若文件已存在则覆盖,若不存在则创建新文件。 |
| a | 以追加方式打开文件,若文件已存在,文件指针位于文件末尾,新内容写入已有内容之后;若文件不存在则创建新文件。 |
| rb | 以二进制格式只读打开文件,文件指针位于文件开头,为默认模式。 |
| wb | 以二进制格式只写打开文件,若文件已存在则覆盖,若不存在则创建新文件。 |
| ab | 以二进制格式追加打开文件,若文件已存在,文件指针位于文件末尾,新内容写入已有内容之后;若不存在则创建新文件。 |
| r+ | 以读写方式打开文件,文件指针位于文件开头。 |
| w+ | 以读写方式打开文件,若文件已存在则覆盖,若不存在则创建新文件。 |
| a+ | 以读写方式打开文件,若文件已存在,文件指针位于文件末尾,以追加模式操作;若不存在则创建新文件。 |
| rb+ | 以二进制格式读写打开文件,文件指针位于文件开头。 |
| wb+ | 以二进制格式读写打开文件,若文件已存在则覆盖,若不存在则创建新文件。 |
| ab+ | 以二进制格式追加读写打开文件,若文件已存在,文件指针位于文件末尾;若不存在则创建新文件。 |
打开文件后必须及时关闭,否则可能导致资源泄漏。示例如下:
# 新建一个文件,文件名为:test.txt
f = open('test.txt', 'w')
# 关闭这个文件
f.close()
任务很简单:输入一个文件名,程序自动生成它的备份文件。下面两张图展示了备份前后的效果:


参考代码:
# 提示输入文件
oldFileName = input("请输入要拷贝的文件名字:")
# 以读的方式打开文件
oldFile = open(oldFileName,'rb')
# 提取文件的后缀
fileFlagNum = oldFileName.rfind('.')
if fileFlagNum > 0:
fileFlag = oldFileName[fileFlagNum:]
# 组织新的文件名字
newFileName = oldFileName[:fileFlagNum] + '[复件]' + fileFlag
# 创建新文件
newFile = open(newFileName, 'wb')
# 把旧文件中的数据,一行一行的进行复制到新文件中
for lineContent in oldFile.readlines():
newFile.write(lineContent)
# 关闭文件
oldFile.close()
newFile.close()
使用write()可以向文件写入数据。注意:若文件不存在,会自动创建新文件;若文件已存在,会先清空原有内容再写入。
f = open('test.txt', 'w')
f.write('i am here!')
f.close()
read(num)可以读取指定字节数的数据,不传参数则读取整个文件。多次读取时,第二次会从上次结束的位置继续读取。
f = open('test.txt', 'r')
content = f.read(5)
print(content)
print("-"*30)
content = f.read()
print(content)
f.close()
注意:如果open只写文件名而不指定模式,默认使用只读模式,即open('test.txt')等价于open('test.txt', 'r')。
readlines()会一次性读取整个文件的所有行,返回一个列表,其中每一行是列表中的一个元素。
#coding=utf-8
f = open('test.txt', 'r')
content = f.readlines()
print(type(content))
i=1
for temp in content:
print("%d:%s"%(i, temp))
i+=1
f.close()
readline()每次只读取一行,适合处理大文件时逐行读取。
#coding=utf-8
f = open('test.txt', 'r')
content = f.readline()
print("1:%s"%content)
content = f.readline()
print("2:%s"%content)
f.close()
使用tell()可以获取当前文件指针的位置(字节偏移量)。
# 打开一个已经存在的文件
f = open("test.txt", "r")
str = f.read(3)
print "读取的数据是 : ", str
# 查找当前位置
position = f.tell()
print "当前文件位置 : ", position
str = f.read(3)
print "读取的数据是 : ", str
# 查找当前位置
position = f.tell()
print "当前文件位置 : ", position
f.close()
使用seek(offset, from)可以移动文件指针。参数说明:
offset:偏移量from:方向,0表示文件开头,1表示当前位置,2表示文件末尾将位置设置为从文件开头偏移5个字节:
# 打开一个已经存在的文件
f = open("test.txt", "r")
str = f.read(30)
print "读取的数据是 : ", str
# 查找当前位置
position = f.tell()
print "当前文件位置 : ", position
# 重新设置位置
f.seek(5,0)
# 查找当前位置
position = f.tell()
print "当前文件位置 : ", position
f.close()
将位置设置为离文件末尾3字节处:
# 打开一个已经存在的文件
f = open("test.txt", "r")
# 查找当前位置
position = f.tell()
print "当前文件位置 : ", position
# 重新设置位置
f.seek(-3,2)
# 读取到的数据为:文件最后3个字节数据
str = f.read()
print "读取的数据是 : ", str
f.close()
使用os.rename()可以重命名文件。
import os
os.rename("毕业论文.txt", "毕业论文-最终版.txt")
使用os.remove()可以删除文件。
import os
os.remove("毕业论文.txt")
import os os.getcwd()
import os os.getcwd()
import os
os.chdir("../")
import os
os.listdir("./")
import os
os.rmdir("张三")
当两个模块功能相关时,将它们放在同一个文件夹下便于管理。


可以使用import 文件夹.模块的方式导入:

也可以使用from 文件夹 import 模块的方式:

在msg文件夹下创建__init__.py文件:

在__init__.py中写入内容:

重新使用from 文件夹 import 模块导入:

总结:包是将相关模块放在同一文件夹下,并在该文件夹中创建名为__init__.py的文件,该文件夹即成为一个包。这样可以有效避免模块名称冲突,并使项目结构更加清晰。
__init__.py文件的作用
该文件控制包的导入行为:
__init__.py为空,则导入包时不会自动导入包中的模块。__all__变量,它会控制from 包名 import *时导入哪些模块。__init__.py中编写代码,导入时这些代码会被执行。以下是一些实际案例的截图:


可以控制导入其他模块。
目录结构:

sendmsg.py 和 recvmsg.py 中的内容:

Python2导入失败:

Python3导入成功,但不能使用模块:

在文件夹下创建一个文件:

Python2导入成功,但不能使用:

Python3导入成功,但不能使用:

解决Python2不能使用的方式:

Python2的解决方式对Python3不生效:

解决Python3不能使用的方式:

有C语言经验的朋友都知道,要使用sqrt函数,需要先#include 。Python中类似,要调用某个函数,需要先用import关键字引入对应的模块。模块相当于一个工具包,其中的函数就是工具,必须先导入才能使用。
使用import 模块名可以引入整个模块。调用时需要使用模块名.函数名的格式。
import module1,mudule2...
如果只想引入某个模块中的特定函数,可以使用from 模块名 import 函数名。这样调用时直接写函数名即可,但需注意:如果两个模块中有同名函数,后引入的会覆盖先引入的。
如果想一次性引入模块中的所有内容,可以使用from math import *。
这个语法可以从模块中导入指定的部分到当前命名空间:
from modname import name1[, name2[, ... nameN]]
例如:
from fib import fibonacci
注意:这不会将整个fib模块导入,只会导入fibonacci这个函数。
将模块的所有内容都导入到当前命名空间,简单但不推荐多用,容易造成命名冲突。
from modname import *
可以使用as给模块或函数起别名,方便使用:
In [1]: import time as tt In [2]: time.sleep(1) # 会报错,因为time已经被重命名为tt In [4]: from time import sleep as sp In [6]: sp(1) # 正常工作
Python解释器导入模块时,按以下顺序搜索:
PYTHONPATH中的每个目录/usr/local/lib/python/)这些搜索路径存储在sys.path变量中。
假设你的模块目录结构如下:
├── setup.py ├── suba │ ├── aa.py │ ├── bb.py │ └── init.py └── subb ├── cc.py ├── dd.py └── init.py
在setup.py中指明需要包含的模块:
from distutils.core import setup setup(name="dongGe", version="1.0", description="dongGe's module", author="dongGe", py_modules=['suba.aa', 'suba.bb', 'subb.cc', 'subb.dd'])
运行python setup.py build,构建后的目录结构:
├── build │ └── lib.linux-i686-2.7 │ ├── suba │ │ ├── aa.py │ │ ├── bb.py │ │ └── init.py │ └── subb │ ├── cc.py │ ├── dd.py │ └── init.py ├── setup.py ├── suba │ ├── aa.py │ ├── bb.py │ └── init.py └── subb ├── cc.py ├── dd.py └── init.py
运行python setup.py sdist,生成dongGe-1.0.tar.gz,最终目录结构:
├── build │ └── lib.linux-i686-2.7 │ ├── suba │ │ ├── aa.py │ │ ├── bb.py │ │ └── init.py │ └── subb │ ├── cc.py │ ├── dd.py │ └── init.py ├── dist │ └── dongGe-1.0.tar.gz ├── MANIFEST ├── setup.py ├── suba │ ├── aa.py │ ├── bb.py │ └── init.py └── subb ├── cc.py ├── dd.py └── init.py
python setup.py install如果需要指定安装路径,可以加参数:python setup.py install --prefix=安装路径
安装后,使用from 模块名 import 模块名或from 模块名 import *即可使用。





总结:如果一个文件中定义了__all__变量,那么使用from xxx import *时,只会导入__all__中列出的内容。
每个Python文件都可以作为一个模块,模块名就是文件名。例如test.py中定义了一个函数:
def add(a,b):
return a+b
在其他文件中,可以使用import test然后调用test.add(),或者使用from test import add直接导入函数。
import test result = test.add(11,22) print(result)
开发者编写模块后,通常会在模块内部加入测试代码。例如:
def add(a,b):
return a+b
# 用来进行测试
ret = add(12,22)
print('int test.py file,,,,12+22=%d'%ret)
但如果其他文件import test,这段测试代码也会被执行——这显然不是我们所期望的。测试代码应该只在直接运行test.py时执行。
Python提供了一个内置变量__name__来解决这个问题。当直接运行该文件时,__name__的值是'__main__';当被其他文件导入时,__name__的值是模块名(例如'test')。



因此,可以利用__name__来判断,只在直接运行时执行测试代码:

运行程序之前:

运行程序之后:

#coding=utf-8
# 批量在文件名前加前缀
import os
funFlag = 1 # 1表示添加标志 2表示删除标志
folderName = './renameDir/'
# 获取指定路径的所有文件名字
dirList = os.listdir(folderName)
# 遍历输出所有文件名字
for name in dirList:
print name
if funFlag == 1:
newName = '[你好]-' + name
elif funFlag == 2:
num = len('[你好]-')
newName = name[num:]
print newName
os.rename(folderName+name, folderName+newName)
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述