5-Python-文件操作、异常、模块
来源:互联网 发布:南风知我意琰阙 编辑:程序博客网 时间:2024/05/16 14:37
- 知识点
知识点
--Python-文件操作、异常、模块
- 文件操作
<1>打开文件
在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件
open(文件名,访问模式)
示例如下:- f = open('test.txt', 'w')
说明:
<2>关闭文件
close( )
示例如下:
# 新建一个文件,文件名为:test.txt
f = open('test.txt', 'w')
# 关闭这个文件
f.close()
- 文件的读写
文件的读写
<1>写数据(write)
使用write()可以完成向文件写入数据
demo:
f = open('test.txt', 'w')
f.write('hello world, i am here!')
f.close()
运行现象:
<2>读数据(read)
使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据
demo:
f = open('test.txt', 'r')
content = f.read(5)
print(content)
print("-"*30)
content = f.read()
print(content)
f.close()
运行现象:
<3>读数据(readlines)
就像read没有参数时一样,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()
运行现象:
<4>读数据(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()
想一想:
如果一个文件很大,比如5G,试想应该怎样把文件的数据读取到内存然后进行处理呢?
- 应用1:制作文件的备份
任务描述
输入文件的名字,然后程序自动完成对文件进行备份
参考代码
#coding=utf-8
oldFileName = raw_input("请输入要拷贝的文件名字:")
oldFile = open(oldFileName,'rb')
# 如果打开文件
if oldFile:
# 提取文件的后缀
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()
- 文件的定位读写
<1>获取当前读写的位置
在读写文件的过程中,如果想知道当前的位置,可以使用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()
<2>定位到某个位置
如果在读写文件的过程中,需要从另外一个位置进行操作的话,可以使用seek()
seek(offset, from)有2个参数
offset:偏移量
from:方向
0:表示文件开头
1:表示当前位置
2:表示文件末尾
demo:把位置设置为:从文件开头,偏移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()
demo:把位置设置为:离文件末尾,3字节处# 打开一个已经存在的文件
f = open("test.txt", "r")
# 查找当前位置
position = f.tell()
print "当前文件位置 : ", position
# 重新设置位置
f.seek(-3,2)
# 读取到的数据为:文件最后3个字节数据
str = f.read()
print "读取的数据是 : ", str
f.close()
- 文件重命名、删除
有些时候,需要对文件进行重命名、删除等一些操作,python的os模块中都有这么功能
<1>文件重命名
os模块中的rename()可以完成对文件的重命名操作
rename(需要修改的文件名, 新的文件名)
import os
os.rename("毕业论文.txt", "毕业论文-最终版.txt")
<2>删除文件
os模块中的remove()可以完成对文件的删除操作
remove(待删除的文件名)
import os
os.remove("毕业论文.txt")
- 文件夹的相关操作
文件夹的相关操作
实际开发中,有时需要用程序的方式对文件夹进行一定的操作,比如创建、删除等
就像对文件操作需要os模块一样,如果要操作文件夹,同样需要os模块
<1>创建文件夹
import os
os.mkdir("张三")
<2>获取当前目录import os
os.getcwd()
<3>改变默认目录import os
os.chdir("../")
<4>获取目录列表import os
os.listdir("./")
<5>删除文件夹import os
os.rmdir("张三")
- 应用2:批量修改文件名
应用:批量修改文件名
<1>运行过程演示
运行程序之前
运行程序之后
<2>参考代码
#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)
- 异常介绍
异常
<1>异常简介
看如下示例:
print '-----test--1---'
open('123.txt','r')
print '-----test--2---'
运行结果:
说明:
打开一个不存在的文件123.txt,当找不到123.txt 文件时,就会抛出给我们一个IOError类型的错误,No such file or directory:123.txt (没有123.txt这样的文件或目录)
异常:
当Python检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"
- 捕获异常
案例剖析
<1>捕获异常 try...except...
看如下示例:
try:
print '-----test--1---'
open('123.txt','r')
print '-----test--2---'
except IOError:
pass
运行结果:
说明:
此程序看不到任何错误,因为用except 接收了产生IOError错误,并添加了处理错误的方法
pass 表示实现了相应的实现,但什么也不做;如果把pass改为print语句,那么就会输出其他信息
小总结:
<2>获取异常的信息描述
看如下示例:
try:
print num
except IOError:
print '产生错误了;'
运行结果如下:
想一想:
上例程序,已经使用except来捕获异常了,为什么还会看到错误的信息提示?
答:
except捕获的错误类型是IOError,而此时程序产生的异常为 NameError ,所以except没有生效
修改后的代码为:
try:
print num
except NameError:
print '产生错误了;'
运行结果如下:
想一想:
上例程序中,已经能够捕获到异常了,那么这个NameError异常,有没有一些信息描述呢?那又该怎样查看?
- 答:
在接收错误类型的后面定义一个变量(例如:errorMsg)用于接收具体错误信息, 然后将接收的错误信息打印即可
修改后的代码为:
try:
print num
except NameError, errorMsg:
print '产生错误了;', errorMsg
运行结果如下:
<3> except捕获多个异常
#coding=utf-8
try:
print '-----test--1---'
# 如果123.txt文件不存在,那么会产生 IOError 异常
open('123.txt','r')
print '-----test--2---'
# 如果num变量没有定义,那么会产生 NameError 异常
print num
except (IOError,NameError), errorMsg:
#如果想通过一次except捕获到多个异常可以用一个元组的方式
# errorMsg里会保存捕获到的错误信息
print errorMsg
注意:
如果想捕获所有的异常,可以省略 except后面的变量
但是这种方法不建议大家使用,会隐藏一些开发者没有想到的异常情况
<4> try...finally...
try...finally...语句用来表达这样的情况
不管线捕捉到的是什么错误,无论错误是不是发生,这些代码“必须”运行,比如文件关闭,释放锁,把数据库连接返还给连接池等
demo:
import time
try:
f = file('poem.txt')
while True: # our usual file-reading idiom
line = f.readline()
if len(line) == 0:
break
time.sleep(2)
print line,
finally:
f.close()
print 'Cleaning up...closed the file'
说明:
程序读poem.txt文件中每一行数据打印,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样做的原因是让程序运行得慢一些。在程序运行的时候,按Ctrl-c中断/取消程序。
我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执行,把文件关闭。
<4> else
咱们应该对
else
并不陌生,在if中,它的作用是当条件不满足时执行的实行;同样在try...except...中也是如果,即如果没有捕获到异常,那么就执行else中的事情try:
num = 100
print num
except NameError, errorMsg:
print('产生错误了:%s'%errorMsg)
else:
print('没有捕获到异常,真高兴')
finally:
print('我一定会执行的哦')
运行结果如下:
- 抛出异常
抛出异常
你可以用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类
下面是一个引发异常的例子:
class ShortInputException(Exception):
'''你定义的异常类。'''
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
try:
s = raw_input('请输入 --> ')
if len(s) < 3:
# raise引发一个你定义的异常
raise ShortInputException(len(s), 3)
except EOFError:
print '/n你输入了一个结束标记EOF'
except ShortInputException, x:#x这个变量被绑定到了错误的实例
print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% (x.length, x.atleast))
else:
print '没有异常发生.'
运行结果如下:
$ python raising.py
请输入 -->
你输入了一个结束标记EOF
$ python raising.py
请输入 --> --> ab
ShortInputException: 输入的长度是 2, 长度至少应是 3
$ python raising.py
请输入 --> abc
没有异常发生.
- 模块介绍
<1>Python中的模块
有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt这个函数,必须用语句"#include"引入math.h这个头文件,否则是无法正常进行调用的。那么在Python中,如果要引用一些内置的函数,该怎么处理呢?
在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。
说的通俗点:模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块
<2>import
在Python中用关键字import来引入某个模块,比如要引用模块math,就可以在文件最开始的地方用import math来引入。
形如:
import module1,mudule2...
当解释器遇到import语句,如果模块在当前的搜索路径就会被导入。
在调用math模块中的函数时,必须这样引用:
模块名.函数名
想一想:
为什么必须加上模块名这样调用呢?
答:
因为可能存在这样一种情况:在多个模块中含有相同名称的函数,此时如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数。所以如果像上述这样引入模块的时候,调用函数必须加上模块名
模块名.函数名
有时候我们只需要用到模块中的某个函数,只需要引入该函数即可,此时可以以下方法实现
from 模块名 import 函数名1,函数名2....
不仅可以引入函数,还可以引入一些变量
注意:
通过这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名,但是当两个模块中含有相同名称函数的时候,后面一次引入会覆盖前一次引入。也就是说假如模块A中有函数function( ),在模块B中也有函数function( ),如果引入A中的function在先、B中的function在后,那么当调用function函数的时候,是去执行模块B中的function函数。
如果想一次性引入math中所有的东西,还可以通过from math import *来实现,但是不建议这么做
<3>from…import
Python的from语句让你从模块中导入一个指定的部分到当前命名空间中。
语法如下:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块fib的fibonacci函数,使用如下语句:
from fib import fibonacci
这个声明不会把整个fib模块导入到当前的命名空间中,它只会将fib里的fibonacci单个引入
<4>from … import *
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:
from modname import *
这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
<5>定位模块
当你导入一个模块,Python解析器对模块位置的搜索顺序是:
当前目录
如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
- 模块制作
<1>定义自己的模块
在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。
比如有这样一个文件test.py,在test.py中定义了函数add
test.py
def add(a,b):
return a+b
<2>调用自己定义的模块
那么在其他文件中就可以先import test,然后通过test.add(a,b)来调用了,当然也可以通过from test import add来引入
main.py
import test
result = test.add(11,22)
print(result)
<3>测试模块
在实际开中,有时一个模块,是一个开发人员进行编写,为了让整个模块中的功能都达到想要的效果,有时编程人员会自行在py文件中添加一些测试信息,例如:
test.py
def add(a,b):
return a+b
# 用来进行测试
ret = add(12,22)
print('int test.py file,,,,12+22=%d'%ret)
如果此时,在其他py文件中引入了此文件的话,想想看,测试的那段代码是否也会执行呢!
main.py
import test
result = test.add(11,22)
print(result)
运行现象:
至此,可发现test.py中的测试代码,应该是单独执行test.py文件时,才应该执行的,不应该是其他的文件中引用而执行
为了解决这个问题,python在执行一个文件时有个变量__name__
总结:
可以根据__name__变量的结果能够判断出,是直接执行的python脚本还是被引入执行的,从而能够有选择性的执行测试代码
- Python中的包
python中的包
1.python中的包
包将有联系的模块组织在一起,有效避免模块名称冲突问题,让应用组织结构更加清晰
假定我们的包的例子有如下的目录结构:
Phone/
__init__.py
common_util.py
Voicedta/
__init__.py
Pots.py
Isdn.py
Fax/
__init__.py
G3.py
Mobile/
__init__.py
Analog.py
igital.py
Pager/
__init__.py
Numeric.py
Phone 是最顶层的包,Voicedta 等是它的子包。 我们可以这样导入子包:
import Phone.Mobile.Analog
Phone.Mobile.Analog.dial()
你也可使用 from-import 实现不同需求的导入
第一种方法是只导入顶层的子包,然后使用属性/点操作符向下引用子包树:
from Phone import Mobile
Mobile.Analog.dial('555-1212')
此外,我们可以还引用更多的子包:
from Phone.Mobile import Analog
Analog.dial('555-1212')
事实上,你可以一直沿子包的树状结构导入:
from Phone.Mobile.Analog import dial
dial('555-1212')
在我们上边的目录结构中,我们可以发现很多的 __init__.py 文件。这些是初始化模块,from-import 语句导入子包时需要用到它。 如果没有用到,他们可以是空文件。
包同样支持 from-import all 语句:
from package.module import *
然而,这样的语句会导入哪些文件取决于操作系统的文件系统。所以我们在__init__.py 中加入 __all__ 变量。该变量包含执行这样的语句时应该导入的模块的名字。它由一个模块名字符串列表组成.。
2. __all__
Python的moudle是很重要的一个概念,moudle里一般都会有一个__init__.py文件。有的__init__.py中是空白,有的却会有__all__参数。
如果其他页面import 的时候,如果__init__.py是空白的,可以直接import到moudle的所有函数。而如果__init__.py中定义了__all__,则import 的时候只会导入__all__部分定义的内容。
例如,我们可以这样组织一个package:
package1/
__init__.py
subPack1/
__init__.py
module_11.py
module_12.py
module_13.py
subPack2/
__init__.py
module_21.py
module_22.py
__init__.py可以为空,只要它存在,就表明此目录应被作为一个package处理。当然,__init__.py中也可以设置相应的内容
现在我们在module_11.py中定义一个函数:
def funA():
print "funcA in module_11"
在顶层目录(也就是package1所在的目录,当然也参考上面的介绍,将package1放在解释器能够搜索到的地方)运行python:
>>>from package1.subPack1.module_11 import funcA
>>>funcA()
funcA in module_11
这样,我们就按照package的层次关系,正确调用了module_11中的函数。
细心的同学会发现,有时在import语句中会出现通配符*,导入某个module中的所有元素,这是怎么实现的呢?
答案就在__init__.py中。我们在subPack1的__init__.py文件中写
__all__ = ['module_13', 'module_12']
然后进入python
>>>from package1.subPack1 import *
>>>module_11.funcA()
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named module_11
也就是说,以*导入时,package内的module是受__init__.py限制的。
- 模块发布
模块发布
1.mymodule目录结构体如下:
.
├── setup.py
├── suba
│ ├── aa.py
│ ├── bb.py
│ └── __init__.py
└── subb
├── cc.py
├── dd.py
└── __init__.py
2.编写setup.py,py_modules需指明所需包含的py文件
from distutils.core import setup
setup(name="xwp", version="1.0", description="xwp's module", author="xingwenpeng", py_modules=['suba.aa', 'suba.bb', 'subb.cc', 'subb.dd'])
3.构建模块
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
4.生成发布压缩包
python setup.py sdist
打包后,生成最终发布压缩包xwp-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
│ └── xwp-1.0.tar.gz
├── MANIFEST
├── setup.py
├── suba
│ ├── aa.py
│ ├── bb.py
│ └── __init__.py
└── subb
├── cc.py
├── dd.py
└── __init__.py
- 作业
必做题
1. 编写程序,完成‘文件加密解密器’
思路提示(只有想不出来的时候,才可以看哦)
打开一个已经存在的文件(最好以二进制的方式打开)
创建一个文件(比如叫 xxx加密后.txt),用来写入要加密后的数据
使用循环 每次读取一行的方式,获取到数据
对第3步获取到的数据,每个字符的方式进行加密,并且写入到第2步创建好的文件中
关闭所有打开的文件
阅读全文
1 0
- 5-Python-文件操作、异常、模块
- 【python】os文件操作模块
- python文件操作模块glob
- python os模块 文件操作
- Python 12:Python 文件io操作模块
- Python模块学习 ---- zipfile zip文件操作
- Python模块学习 ---- zipfile zip文件操作
- python模块介绍- shutil 高级文件操作
- Python OS 文件操作模块常用函数
- python 目录文件操作 os模块
- python 文件操作 os模块使用
- Python OS 文件操作模块常用函数
- Python--文件操作之os模块
- Python文件操作之OS模块
- Python文件操作-shutil 模块(参考)
- python os模块 操作文件和目录
- Python 学习File、os模块操作文件
- Python文件操作os,shutil模块
- Android编程之SparseArray<E>详解
- ajax请求(一)
- Redux框架简介
- Python 格式化字符串
- 基于Python语言使用RabbitMQ消息队列(一)
- 5-Python-文件操作、异常、模块
- 整理Windows下用vs2010写的简单看门狗
- oracle各种基本函数查询
- margin在文档流和浮动中的区别
- JavaWeb三大组件之一Servlet【Servlet细节】
- 网络获取图片高度和宽度
- iOS Base64编码
- 网上资源交易系统(ssm)
- LeetCode 38 Count and Say