目录
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 = 0
try:
res = num_1 / num_2
print(res) # 不会执行
except:
print('除数不能为0') # 执行
finally:
print('finally') # 放到 finally中的内容最后无论如何都会执行
print(1 + 3) # 会继续往下执行,程序不会中断
try:
res = num_1 / num_2
print(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_2
print(res) # 不会执行
except Exception as e:
print(e) # division by zero
raise Exception('除数不能为0') # 抛出异常,并提示 除数不能为0
finally:
print('finally')
print(1 + 2) # 不会执行,程序会中断
try:
res = num_1 / num_2
print(res) # 不会执行
except ZeroDivisionError as e1: # 逐层捕获错误
print(e1) # division by zero
raise 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 = name
self.age = age
self.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}')
# 定义类的静态方法,直接使用类名调用
@classmethod
def 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 * y
y = 20
def inner(a = 0):
return a + x + y + z
return 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 = 99999
for i in range(100000):
result = result - i ** 2
print("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']) # Tom
print(type(res)) # <class 'list'>