目录
1、文件操作
1-1)打开文件的两种方式:
1-2)文件操作的简单示例:
write方法:
read方法:
readline方法:
readlines方法:
2、异常处理
2-1)不会中断程序的异常捕获和处理
2-2)中断程序的异常捕获和处理 raise
2-3)对操作文件的异常处理:
3、面向对象
4、闭包
5、装饰器(函数装饰器)
6、关于JSON的数据操作
6-1)dumps 方法
6-2)loads方法
6-3)dump方法
6-4)load 方法
1、文件操作
打开模式(mode) | 描述 |
---|---|
b | 二进制模式。 |
+ | 打开一个文件进行更新(可读可写)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
参考自:https://www.runoob.com/python3/python3-file-methods.html
1-1)打开文件的两种方式:
# 打开指定的文件,默认以读的方式打开,并指定编码的格式为utf-8
f = open('./test.txt','r', encoding = 'utf-8')# 读取所有的内容
content = f.read()# 输出内容
print(content)# 使用完时手动关闭文件
f.close()
# 使用 with 自动处理资源关闭
with open('test.txt', 'r', encoding='utf-8') as f:content = f.read()# 到 with 缩进内容的最后,文件会被关闭
print(content) # 执行这句前,文件已被关闭
1-2)文件操作的简单示例:
test.txt 昨天是星期一,天气晴朗,我很开心; 今天是星期二,下了大雨,我很难过; 明天是星期三,听说还是要下大雨,我觉得我不会开心; 后天是星期四,不知道会怎么样呢; 永远相信美好的事情即将发生!
write方法:
# 'a' 用于追加,文件指针放到文件内容的结尾
f = open('test.txt', 'a', encoding = 'utf-8')# 换行追加指定的内容
f.write("\n Hello. goodbye!")f.close()
昨天是星期一,天气晴朗,我很开心; 今天是星期二,下了大雨,我很难过; 明天是星期三,听说还是要下大雨,我觉得我不会开心; 后天是星期四,不知道会怎么样呢; 永远相信美好的事情即将发生!Hello. goodbye!
read方法:
# 读取 指定读取的长度
f = open('test.txt', 'r', encoding='utf-8')
content = f.read(10) # 读取前10个字符,如果没有指定,则是读入全部内容
print(list)
f.close()
with open('test.txt', 'r', encoding='utf8') as f:res = f.read(3) # 默认读取第一行的内容,读取前3个字符print(res)res = f.read(3) # 接着读入后面3个字符print(res)
readline方法:
with open('test.txt', 'r', encoding='utf8') as f:res = f.readline() # 默认读取第一行的内容,包括最后的换行符print(res)res = f.readline() # 读取第二行的内容,包括最后的换行符print(res)
readlines方法:
with open('test.txt', 'r', encoding='utf-8') as f:line = f.readlines() # 返回一个列表,其中的每一个元素是每一行的内容,包括最后的换行符print(line)
2、异常处理
2-1)不会中断程序的异常捕获和处理
num_1 = 10
num_2 = 0try:res = num_1 / num_2print(res) # 不会执行
except:print('除数不能为0') # 执行
finally:print('finally') # 放到 finally中的内容最后无论如何都会执行print(1 + 3) # 会继续往下执行,程序不会中断
try:res = num_1 / num_2print(res) # 不会执行
except Exception as e: # 捕获所有 Exception 类中已定义的错误print(e) # division by zero
finally:print('finally') # 执行print(1 + 2) # 会继续执行
2-2)中断程序的异常捕获和处理 raise
try:res = num_1 / num_2print(res) # 不会执行
except Exception as e:print(e) # division by zeroraise Exception('除数不能为0') # 抛出异常,并提示 除数不能为0
finally:print('finally')print(1 + 2) # 不会执行,程序会中断
try:res = num_1 / num_2print(res) # 不会执行
except ZeroDivisionError as e1: # 逐层捕获错误print(e1) # division by zeroraise ZeroDivisionError('除数不能为0') # 抛出错误并自定义提示内容
except Exception as e2: # Exception 是所有异常类的父类,应该放在最后print(e2)raise # 抛出错误并给出对应的默认提示
finally:print('finally')print(1 + 2) # 不会执行
2-3)对操作文件的异常处理:
try:with open('../Normal/test.txt', 'r', encoding='utf-8') as f:res = f.read()
except FileNotFoundError as e: # 文件不存在时的错误raise FileNotFoundError('文件不存在')
except Exception as e: # 其他错误raise Exception('发生错误')
else: # 没有异常时执行print(res)
3、面向对象
class People:# 定义类属性type = '哺乳动物'# 定义私有属性 双下划线开头__private = ''# 定义构造方法 实例化时会自动调用,并且可以将实例变量或实例属性在此定义# self 形参属于类实例的引用,与其他语言中的 this 中的关键字类似# 类方法的第一个形参一定是 self (可以用其他的名称),代表实例本身def __init__(self, name = '', age = '', gender = ''):# 定义实例属性self.name = nameself.age = ageself.gender = gender# 用于释放实例空间,释放内存空间 程序结束后会自动调用,可以处理收尾工作def __del__(self):print('正在释放实例空间')# 打印类的实例使会触发的方法, 相当于 java 中的 toString;下面的操作是重写def __str__(self):return f'当前类的实例正在被打印'# 受保护的方法 子类可以继承def _protectFunc(self):print('这是一个受保护的方法')# 私有的方法 子类不能继承def __privateFunc(self):print('这是一个私有的方法')# 定义三个方法def talk(self, str):print(f'{self.name}: {str}.')def doing(self, str):print(f'{self.name}正在{str}.')def info(self):print(f'name: {self.name},age: {self.age}, gender: {self.gender}')# 定义类的静态方法,直接使用类名调用@classmethoddef people_type(cls): # cls 代表类本身print(cls.type)
# 新建一个Man类,继承于 People 类
class Man(People):# 重写父类的方法def talk(self, str):print('子类重写了父类的talk方法')# 拓展自己的新方法def eat(self):print('子类自己的方法 eat')
# 如果执行者是当前文件自身,则会执行以下的内容;被其他的模块导入时,不会执行下面的内容
if __name__ == '__main__':# p1 = People() # 类的实例化,会自动调用构造方法# p1.name = '张三' # 先找实例变量,在找类变量# p1.age = 14## p2 = People()## print(id(p1), id(p2)) # 两个不同的虚拟地址# p3 = People('张三', 23, '男')# # print(p3)# print(p3.name)## People.people_type() # 使用 类名.静态方法 调用类的静态方法(推荐)man = Man()man._protectFunc() # 子类可以调用父类受保护的方法,不能调用父类私有的方法
4、闭包
在一个函数中定义了一个内部函数,并且该内部函数使用了外部函数的参数或变量,则称为闭包。
def outer(x, y):z = x * yy = 20def inner(a = 0):return a + x + y + zreturn inner# 由外部函数到内部函数依次传参
res = outer(2, 3)(4) # 4 + 2 + 20 + 6
print(res)res = outer(2, 3)() # 0 + 2 + 20 + 6
print(res)
5、装饰器(函数装饰器)
上面面向对象中,People类定义静态方法 people_type 的上一行:@classmethod 就是一个装饰器。
装饰器本身也是一个函数,装饰器给其他的函数使用,可以改变程序执行的顺序。
'''
定义装饰器,用于统计函数的运行时间
函数里面定义了一个函数,称之为内部函数(闭包)
装饰器自带一个参数 —— func,用于获取被装饰函数的地址
内部函数运行结束后,必须要返回其函数名(地址)
'''
def stat(func): # 装饰器,接收到的第一个参数是要使用该装饰器的函数的地址(函数名)def inner():start = time.time()print('当前时间为:', start)func() # 执行该函数end = time.time()print('结束时间为:', end)print('总用时:', end - start)return inner@stat # 表示 test2 函数使用 stat 装饰器
def test2():result = 99999for i in range(100000):result = result - i ** 2print("result = ",result)test2() # 如果该函数有装饰器,则会直接去执行装饰器
def decorate(func):def inner(*args, **kwargs):print('###',args, kwargs)func(*args, **kwargs)print('finally')return inner@decorate
def test(name, age):print(f'Hello,{name}.your age is {age}.')test('张三', age=18)
在这里, test('张三',age=18) 相当于调用了 装饰器里的 inner('张三',age=18)
装饰器的内部函数接收到的参数就是传递给test的参数,第四行时,执行了 test 函数。
6、关于JSON的数据操作
sourceObj = [{'name': 'Tom', 'age': 15, 'gender': 'man', 'num': 1001},{'name': 'ben', 'age': 14, 'gender': 'woman', 'num': 1002},{'name': 'jam', 'age': 15, 'gender': 'woman', 'num': 1003},{'name': 'jack', 'age': 16, 'gender': 'man', 'num': 1004},
]
sourceStr = ('[{"name": "Tom", "age": 15, "gender": "man", "num": 1001}, ''{"name": "ben", "age": 14, "gender": "woman", "num": 1002}, ''{"name": "jam", "age": 15, "gender": "woman", "num": 1003}, ''{"name": "jack", "age": 16, "gender": "man", "num": 1004}]')
import json
6-1)dumps 方法
将 json 对象(python字典)转换成 json 字符串。单引号会转换成双引号。
import json
jsonstr = json.dumps(sourceObj) # 使用 dumps 方法将其转换成 json 字符串
print(type(jsonstr))
print(jsonstr) # 单引号会变成双引号
6-2)loads方法
将 json 字符串转成 json 对象(Python字典)
jsonObj = json.loads(sourceStr) # 将 json 格式的字符串转成对象列表的形式
print(jsonObj[0]['name']) # Tom
6-3)dump方法
将 json 对象格式的内容以 json 对象写出到指定文件
with open('./jsonString.json','w', encoding='utf-8') as f:json.dump(json.loads(sourceStr), f) # 将json对象格式的内容写出
6-4)load 方法
将json对象文件中的内容以字典列表的形式读入
with open('./jsonString.json', 'r') as f:res = json.load(f)print(res[0]['name']) # Tomprint(type(res)) # <class 'list'>