在使用文件对象时,首先需要通过内置的open()方法创建一个文件对象,然后 通过该对象提供的方法进行一些基本文件操作。
1.创建和打开文件
open()
file = open(filename, mode, buffering)
file: 被创建的文件对象
filename: 要创建或者打开文件的文件名,需要使用单引号或者双引号括起来。待打开的文件在当前位置,不用使用绝对路径,否则使用。
mode: 可选参数,用于指定文件的打开模式。具体P203页
buffering: 可选参数,用于指定读写文件的缓冲模式。0,不缓存;1,缓存;大于1,则表示缓冲区大小。默认为缓存模式。
1.file = open(“status.txt”)
打开一个不存在的文件时先创建该文件,否则会抛出异常
解决方案
在当前目录下创建一个名为“status.txt”文件。
在调用open()函数时,指定mode的参数为w、w+、 a、a+。这样,当要打开的文件不存在时,就可以创建新的文件了。
2.以二进制的形式打开文件
使用open()函数不仅可以以文本的形式打开文本文件,而且可以以二进制形式打开非文本文件,如图片、音频、视频等。
3.打开文件时指定编码方式
open()函数打开文件时,默认采用GBK编码,当打开的不是GBK编码时将抛出异常。
2.close()
打开文件后,需要及时关闭,以免对文件造成不必要的破坏。
file.close()
close()方法先刷新缓冲区中没有写入的信息,然后在关闭文件,这样可以将没有写入到文件的内容写入到文件中。在关闭文件后,便不能再进行写入操作了。
3.打开文件时使用with语句,保证文件执行完操作后正常关闭。
打开文件后,要及时将其关闭。从而实现在处理文件时,无论是否抛出异常,都能保证with语句执行完毕后关闭已经打开的文件。
基本语法格式:
with 表达式 as target:
with语句体
例子:
with open(“message.txt”, ‘w’) as file:
pass # 可以改成其他操作语句
4.写入文件内容
file.write(string)
file为打开的文件对象;string为要写入的字符串。
调用write()方法向文件中写入内容的前提是, 打开文件时,指定的打开模式为w(可写)或者a(追加),否则抛出异常。
5.读取文件
1.读取指定字符
file.read([size])
file为打开的文件对象;size为可选参数,用于指定要读取的字符个数,如果省略则一次性读取所有内容。
在调用read()方法读取文件内容的前提是,打开文件时,指定的打开模式为r(只读)或者r+(读写),否则将抛出异常。
例子:
with open(“message.txt”, ‘r’) as file:
string = file.read(9)
print(string)
注:使用read(size)方法读取文件时,是从文件的开头读取文件。
指定位置读取文件,file.seek(offset[,whence])
file: 表示已经打开的文件对象。
offset: 用于指定移动的字符个数,其具体位置与whence有关。
whence: 用于指定从什么位置开始计算。值为0表示从文件头开始计算,值为1表示从当前位置开始计算,值为2表示从文件尾开始计算,默认值为0。
例子:
with open(“message.txt”, ‘r’) as file:
file.seek(14) # 移动文件指针到新的位置
string = file.read(8) # 读取8个字符
print(string)
具体见 P208页
2.读取一行
file.readline()
with open(”message,txt“, ‘r’) as file:
number = 0 # 记录行号
while True:
number +=1
line = file.readline()
if line == ’ ':
break
print(number, line, end = ‘\n’) # 输出一行内容
3.读取全部行
file.readlines()
读取全部行的作用同调用read()方法时不指定size类似,只不过读取全部行时,返回的是一个字符串列表,列表每个元素为文件的一行内容。
例子:
with open(”message,txt“, ‘r’) as file:
message = file.readlines()
print(message)
如果文件比较大时,采用该方法输出读取的文件内容会很慢,这时可以将列表的内容逐行输出。
例子:
with open(”message,txt“, ‘r’) as file:
messageall = file.readlines()
for message in messageall:
print(message)
在python中,内置了os模块以及其子模块os.path,用于对目录或者文件进行操作。
1.os和os.path模块
2.路径
1.相对路径
import os
print(os.getcwd()) # 输出当前目录
其依赖于当前工作目录
2.绝对路径
import os
print(os.path.abspath(r’demo\message.txt’)) # 获取绝对路径
不依赖于当前工作目录
3.拼接路径
如果想将两个或者多个路径拼接到一起组成一个新的路径,可以使用os.path模块提供的join()函数实现。
语法格式:
os.path.join(‘path1,[,path2[,…]]’)
路径之间用‘ ,’隔开。
如果路径中没有一个绝对路径,那么最后拼接出来的将是一个相对路径。
注:使用os.path.join()函数拼接路径时,并不会检测路径是否真实存在。
例子:
import os
print(os.path.join(“E:\program\Python\Code”, “demo\message.txt”))
如果存在多个绝对路径,那么以从左到右的顺序最后一次出现为准,并且该路径之前的参数都将被忽略。
3.判断目录是否存在
os.path.exists(path)
其中的path可以采用绝对路径,也可以使用相对路径
返回值:如果给定的路径存在,返回Ture,否则返回False
4.创建目录
1.创建一级目录
注:该函数只能创建指定路径中的最后一级路径,如果该路径的上一级不存在,则抛出异常FileNotFoundError。
os.mkdir(path, mode = 0o777)
path: 可以是绝对路径,也可以是相对路径。
mode: 用于指定数值模式,默认值为0777。该参数在非UNIX系统上无效或者被忽略。
例子:
import os
os.mkdir(“C:\demo”)
如果路径已经存在,将会抛出FileExistsError异常。
解决办法:
import os
path = ‘C:\demo’
if not os.path.exists(path):
os.makedir(path)
print(“目录创建成功!”)
else:
print(“该目录已经存在!”)
2.创建多级目录
os.mkdirs(name, mode=0o777)
import os
os.makedirs(“C:\demo\test\dir\mr”)
创建C:\demo\test\dir\mr
5.删除目录
使用rmdir()函数只能删除空的目录
os.rmdir(path)
其中,path为要删除的目录,可以是相对路径,也可以是绝对路径。
例子:
import os
os.rmdir(”C:\demo\test\dir\mr“)
删除C:\demo\test\dir目录下的mr目录,如果删除的目录不存在将会抛出FileNotFoundError异常。
删除非空目录
shutil.rmtree(“C:\demo\test”)
import shutil
shutil.rmtree(“C:\demo\test”)
要删除不为空的”C:\demo\test“目录。
6.遍历目录
指对 指定目录下 的全部目录(包含子目录)及文件浏览一遍。
os.walk(top[, topdown][, onerror][, followlinks])
参数说明:
top: 用于指定要遍历内容的根目录
topdown: 可选参数,用于指定遍历的顺序,Ture,表示自上而下遍历(即先遍历根目录);False,表示自下而上遍历(即先遍历最后一级子目录),默认为Ture。
onerror: 可选参数,用于指定错误处理方式,默认为忽略。
followlinks: 可选参数,详见P218页
返回值:返回一个包含三个元素的(dirpath, dirnames, filenames)的元组生成器对象。
dirpath: 当前遍历的路径,是一个字符串
dirnames: 当前路径下包含的子目录,是一个列表
filenames: 当前路径下包含的文件,也是一个列表
例子:
import os
tuples = os.walk(“E:\program\Python\Code\01”)
for tuple1 in tuples:
print(tuple,’\n’)
1.删除文件
os.remove(path)
import os
path = “mrsoft.txt”
if os.path.exists(path):
os.remove(path)
print(“文件删除完毕!”)
else:
print(“文件不存在!”)
2.重命名文件和目录
os.rename(src, dst)
src: 用于指定重命名的目录和文件
dst: 用于指定重命名后的目录或者文件
例子:
import os
src = “C:\demo\test\dir\mr\mrsoft.txt” 换为目录“demo”
dst = “C:\demo\test\dir\mr\mr.txt” 换为目录“test”
if os.path.exists(src):
os.rename(src, dst)
print(“文件重命名完毕!”)
else:
print(“文件不存在!”)
3.获取文件基本信息
在计算机上创建文件后,该文件本身就会包含一些信息。
stat()函数可以获取最后一次访问时间、最后一次修改时间、文件大小等基本信息。
object = os.stat(path),该函数的返回值是一个对象,该对象包含以下属性,
st_mode:保护模式
st_dev:设备名
st_ino:索引号
st_uid:用户名
st_nlink:硬链接号
st_gid:组ID
st_size:文件大小,单位为字节
st_atime:最后一次访问时间
st_mtime:最后一次修改时间
st_ctime:最后一次状态变化时间
函数的定义:
def functionname([parameterlist1,parameterlist2]):
[’’’ 注释’’’]
[函数体]
函数体:不知道填写什么,可以用pass替代或者“ … ”替代
functionname([参数])
形参和实参:
(1)形参:
在函数定义 / 创建时,函数名后面括号中的参数为“形式参数”
(2)实参
在调用函数时,函数名后面括号中的参数为"实际参数"
注:
(1)当实参为不可变对象时,进行的是值得传递==>值传递后,改变形参的值,实参的值不变
(2)当实参为可变对象时,进行的是引用传递==>引用传递时,改变形参的值,实参的值也一同变化
P162页
1.位置参数
2.关键字参数
使用形参的名字来确定输入的参数值
注:通过该方式指定实参时,不再需要与形参的位置完全一致,只要将参数名写正确即可。
3.为参数设置默认值
调用函数时,如果没有指定某个参数将抛出异常,即在定义函数时,直接指定形式参数的默认值。
定义函数时,指定默认的形参必须在所有参数的最后,否则将产生语法错误。
def functionname(…, [parameter1 = defualtvalue1]):
[函数体]
注意:定义函数时,为形式参数设置默认值要牢记一点==>默认参数必须指向不可变对象。
查看当前函数的默认参数值,函数名._defaults_,其结果是一个元组
可变对象最好使用None作为默认值,否则会出现意料之外的值,P166,这时还需要进行代码的检查
def demo(obj=None):
if obj == None:
obj = [ ]
print(“obj的值:”,obj)
obj.append(1)
4.可变参数
可变参数也称为不定长参数,即传入函数的实际参数可以是0个、1个、两个到任意个。
表示接受任意多个实际参数,并将其放到一个元组中
def functionname(*name):
print("\n我们喜欢的球员有:")
for item in name:
print(item)
functionname(‘邓肯’, ‘乔丹’)
扩展:使用一个已存在的列表作为函数的可变参数,可以在列表的名称前加“ * ”.
param = [‘邓肯’, ‘帕克’, ‘詹姆斯’]
functionname(*param)
表示任意多个显式赋值的实际参数,并将其放到一个字典中
def functionname(**sign):
print( ) # 输出一个空行
for key, value in sign.items():
print("[" + key +"] 的绰号是:" + value)
functionname(邓肯=‘石佛’, 罗冰逊 =‘海上将军’)
扩展:使用一个已经存在的字典作为函数的可变参数,可以在字典的名字前面加“ ** ”
dict1 = {‘邓肯’: ‘石佛’, ‘罗宾逊’: ‘海上将军’, ‘吉诺比利’: ‘妖刀’}
functionname(** dict1)
1.局部变量
2.全局变量
能够作用于函数内外的变量
两种形式
1.在函数外定义
2.在函数内定义
使用global关键字修饰
利用关键字lambda
result = lambda[arg1, [,arg2, …,argn]]:expression
例子:
import math
r = 10
result = lambda r: math.pi *r*r
print('半径为', r, '的面积为:',result(r))
python中的一个".py"文件就是一个模块。
import modelname [as 别名]
import test1, test2, ... # 导入多个模型,使用","分隔,不推荐该方法
from 模块名 import member/* # 利用dir()查看具体导入了哪些定义(变量、函数或者类等)
- 模块搜索目录
1、在当前目录(即执行的python脚本文件所在目录)下查找
2、到PYTHONPATH(环境变量)下的每一个目录中查找
2、到Python的默认安装目录下查找
以上各个目录的具体位置保存在标准模块sys的sys.path变量中
import sys
print(sys.path) # 输出具体目录
我们可以通过以下3种方式添加指定的目录带sys.path中。P193
1.临时添加
2.增加.pth文件(推荐)
3.在PYTHONPATH环境变量中添加
1.创建包
(1) 创建一个文件夹(setting)
(2) 在文件夹中创建一个__init__.py的文件,可以不写任何内容,再导入包是会自动执行。
2.使用包
(1) import+完整包名+模块名
import setting.size
通过这种方式导入的模块后,在使用时需要使用完整的名称。
例子:
import seeting.size
if __name__ =='__main__': #__name__,程序可以检查该变量,以确定它在哪个模块中执行
print(‘高度:’,setting.size.width)
print('宽度:',setting.size.height)
(2) from+完整包名+import+模块名
from seeting import size
if __name__ =='__main__':
print(‘高度:’,size.width)
print('宽度:',size.height)
#无需加包名setting
(3) from+完整包名+模块名+import+定义名:加载指定模块
# 导入setting包下size模块中的width和height变量
from seeting.size import width, height (*代替全部定义被加载)
if __name__ =='__main__':
print(‘高度:’,width)
print('宽度:',height)
1.类的定义
class ClassName:
‘’‘类的帮助信息’’’
statement
设计图也就绪,
2.创建类的实例
class Geese:
'''大雁类'''
pass
wildGoose=Geese()
print(wildGoose)
3.魔术方法
init()
P178页
class Geese:
‘’‘大雁类’‘’
def __init__(self):
# 其中除了self参数外,还可以自定义一些其他参数,例如:def __init__(self, beak, wing, claw):
print(“大雁类”)
wildGoose = Geese()
在创建类后,类通常会自动创建一个__init__()方法。
每当创建一个类的新实列时,Python都会自动执行它。
__init__()方法必须包含一个self参数,并且必须是第一个参数。
self参数是一个指向实列本身的引用,用于访问类中的属性和方法。在方法调用时会自动传递实际参数self。
- Python中默认的方法
类的成员主要由实例方法和数据成员组成,可以通过类的实例进行访问。
(1)创建实例方法并访问
所谓的实例方法(行为)是指在类中定义的函数。同_init_()方法一样,实例方法的第一个参数为self,并且必须包含一个参数self。
def functionname(self, parameterList):
block # 方法体
实例名.functionname(parameterValue)
# 其中的参数个数和类中的实例方法个数一致
(2)创建数据成员并访问
数据成员是指在类中定义的变量,即属性。
根据定义的位置又可以分为类属性和实例属性。
- 类属性
类属性是指定义在类中,并且在函数体外的属性。
类属性可以在类的所有实例之间共享值,也就是在所有实例化的对象中公用。
class Geese:
'''大雁类'''
neck = "脖子较长" # 定义类属性
wing = “振翅频率高” # 定义类属性
leg = “腿位于身份的中心支点,行走自如” # 定义类属性
def __init__(self): # 定义类方法(相当于构造方法)
print("我是大雁类,我具有以下特征")
print("Geese.neck")
print("Geese.wing")
print("Geese.leg")
geese = Geese() # 实例化过程中运行
- 实例属性
是指定义在类的方法中的属性,只作用与当前实例中。
class Geese:
'''大雁类'''
def __init__(self): # 定义类方法(相当于构造方法)
neck = "脖子较长" # 定义实例属性
wing = “振翅频率高” # 定义实例属性
leg = “腿位于身份的中心支点,行走自如” # 定义实例属性
print("我是大雁类,我具有以下特征")
print("self.neck")
print("self.wing")
print("self.leg")
geese = Geese() # 实例化过程中运行
Python中并没有对属性和方法的访问权限进行限制.
- (1)尾都有双下划线,__foo__
- 表示定义特殊方法,一般是系统定义名字,如__init__()
- (2)头一个下划线,_foo
- 表示protected(保护)类型的成员,只允许类本身和子类进行访问,但是不能使用"from module import *"语句导入
class Swan:
‘’‘天鹅类’‘’
_neck_swam='天鹅的脖子很长' # 定义私有属性
def __init__(self):
print('__init__():' Swan.__neck_swan) # 在实例方法中访问私有属性
swan = Swam() # 创建Swam类的实例
print("直接访问:", swam._neck_swan) #保护属性可以通过实例名访问
- 可以通过类名和实例名进行访问
- (3)头两个下划线,__foo
- 表示private(私有)类型的成员,只允许定义该方法的类本身进行访问,而且不能通过类的实例进行访问,但是可以通过"类的实列名.类名__xxx"方式访问
class Swan:
’‘天鹅类’‘’
__neck_swam='天鹅的脖子很长' # 定义私有属性
def __init__(self):
print('__init__():' Swan.__neck_swan) # 在实例方法中访问私有属性
swan = Swam() # 创建Swam类的实例
print("加入类名:", swam._Swan__neck_swan) # 私有属性,可以通过"实例名.类名__xxx"方式访问
print("直接访问:", swam.__neck_swan) # 私有属性不能通过实例名访问,错误❌
- 可以 通过类名访问,或者“实例名.类名__xxx”访问,但是不能直接通过“实例名.属性名”方式访问
(1)创建用于计算的属性
通过@property(装饰器)将一个方法转化为属性,从而实现用于计算机的属性。
将方法转换为属性后,可以直接通过方法名来访问,不需要在添加“()”。
语法格式:
@property
def methodname(self):
block
例子:
class Rect:
def __init__(self, width, height):
self.width = wifth
self.height = height
@property # 将方法转化为属性
def area(self):
return self.width*self.height
rect = Rect(800,600)
print(“面积:”,rect.area) # 访问的时候没有添加"()"
class TVshow:
def __init__(self, show):
self.__show = show
@property # 将方法转化为属性
def show(self):
return self.__show # 返回私有属性的值
tvshow=TVshow("正在播放《战狼2》")
print("默认:" tvshow.show)
tvshow.show="正在播放《红海行动》" #修改属性的值
print("默认:" tvshow.show) # ❌无法修改
- 实现只读属性
被继承的类称为父类或者基类,新的类称为子类或者派生类。
语法格式:
class ClassName(基类1,基类2,...) # 如果不指定,将适用所有python对象的根类object
''类的信息'''
类体
方法重写P186
子类中调用父类的__init__()方法
super().__init__() # 调用基类的__init__()方法