有时候需要把一些复杂的信息存储在文件中
比如一个list,或者一个文件夹的目录
举个例子
我们需要把['a','b','c']存储在一个文件中
那么我们可以用pickle
看看代码
import pickle
chars = ['a', 'b', 'c', 'd', 'e']
numbers = [1, 2, 3, 4, 5]
f = open('text.txt', 'wb')
pickle.dump(chars, f)
pickle.dump(numbers, f)
f.close()
f = open('text.txt', 'rb')
chs = pickle.load(f)
f.close()
print(chs)
f = open('text.txt', 'rb')
chs = pickle.load(f)
f.close()
print(chs)
f = open('text.txt', 'rb')
chs = pickle.load(f)
nums = pickle.load(f)
f.close()
print(chs)
print(nums)
然后看下结果
代码分成几个部分
显示导入pickle
import pickle
然后来了两个列表
一个是chars,一个是numbers
chars = ['a', 'b', 'c', 'd', 'e']
numbers = [1, 2, 3, 4, 5]
然后使用open方法,打开一个文件
我们这里用了一个text.txt文件
open('text.txt','wb')
第一个参数是文件的名字, text.txt
第二个参数是选择模式,'wb'就是 write binary,也就是写入
f=open('text.txt','wb')
然后用pickle的dump方法,也就是把对象写入文件
pickle.dump(chars,f)
pickle.dump(numbers,f)
操作完这个文件之后,我们需要关闭这个文件
f.close()
然后是读取文件
同样需要先打开文件
f=open('text.txt','rb')
第一个参数是文件名,text.txt
第二个参数是rb,,,,也就是reading binary
然后pickle.load(f),加载这个文件中的内容
然后同样的f要关闭,
f.close()
f = open('text.txt', 'rb')
chs = pickle.load(f)
nums = pickle.load(f)
f.close()
print(chs)
print(nums)
这是加载两次
第一次加载的就是存入的第一个列表
第二次加载的就是存入的第二个列表
shelve
import shelve
shelf = shelve.open('text03')
shelf['a']=['a','b','b','c','c']
shelf['b']=[1,2,3,4]
shelf['c']='abcdef'
shelf.sync()
shelf.close()
shelf = shelve.open('text03')
print(shelf['a'])
print(shelf['b'])
print(shelf['c'])
shelf.close()
shelve相当于是快速存入
很像用directory的方式直接快速存入
先是open('test'), 打开文件
然后,存入'a'对应列表['a','b'...]
存入'b'对应列表[1,2,3,4]
'c'对应列表'abcdef'
然后shelf调用sync()方法, 保存更改
然后shelf调用close()方法,关闭shelf
查看或者取出也是一样的道理
先是shelve.open()打开文件
然后直接通过key键查看或者取出
然后关闭
Exception Handling
程序运行的时候,可能会出现一些错误
我们也可以根据自己的需要来定制一些自己的Exception
打个比方
a = 1 / 0
print(a)
出现的错误是这样的
Traceback (most recent call last):
File "C:/D/Project/PythonTest1005/test01", line 1, in <module>
a = 1 / 0
ZeroDivisionError: division by zero
那么我们可以捕捉这个错误,然后进行相关的操作
比如这样
try:
a = 1 / 0
except ZeroDivisionError:
print('0 could not be divisor.')
这段代码的意思是,如果在try里面的代码中
捕捉到了 ZeroDivisionError
那么就输出
'0 could not be divisor.'
再打个比方
try:
print('a')
print('b')
print('c')
a = 1 / 0
print('d')
print('e')
except ZeroDivisionError:
print('0 could not be divisor.')
先执行 输出a
然后 输出b
然后 输出c
然后 1/0发生了错误, 那么就捕捉到了ZeroDivisionError
然后就执行了
print('0 could not be divisor.')
所以,就没有输出d和e
现在我们来写一个例子
输出一个文件中指定的行
我们先来写一个输出文件中所有内容的例子
file = open('test.txt')
for line in file:
print(line)
然后我们再写一个输入正整数的例子
while True:
content = input()
try:
num = int(content)
if num >= 0:
print(num)
else:
print('Please input a positive number or 0.')
except ValueError:
print('Please input a number.')
然后我们把这两个例子整合一下
就得到了一个输出一个文件指定行数的一个例子
def output(num):
file = open('test.txt')
count=0
out=False
for line in file:
if count==num:
print('The number of line is : {}'.format(count))
print('The content of line is : {}'.format(line))
out=True
break
count+=1
if out==False:
print('No such line.')
while True:
content = input()
try:
num = int(content)
if num >= 0:
output(num)
else:
print('Please input a positive number or 0.')
except ValueError:
print('Please input a number.')
面向对象OOP
面向对象就是把一些属性和方法封装成一个对象
在Python中就是class的形式
我们举个例子
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person('Tom', 20)
p2 = Person('Jerry', 10)
print(p1.name)
print(p1.age)
print(p2.name)
print(p2.age)
我们来看一下一个对象实例是如何被创建的
当我们执行
a=Person('Sara', 20) 的时候
Python创建了一个Person对象实例
并且在内存中为这个对象分配地址
callable attribute可调用属性
class中的方法,叫做可调用属性callable attribute
其实也就是类中的方法,专属于这个class的方法
有3个特性:
1.类中的方法属于这个类
2.第一个参数必须是self,也就是这个类的对象
3.方法可以通过self对象来访问这个类中的属性
举个例子
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def sayHello(self):
print('Hello. My name is {}. I am {} years old.'.format(self.name, self.age))
p1 = Person('Tom', 20)
p2 = Person('Jerry', 10)
print(p1.name)
print(p1.age)
print(p2.name)
print(p2.age)
p1.sayHello()
p2.sayHello()
打印实例print an instance
我们试一下打印一个实例
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def sayHello(self):
print('Hello. My name is {}. I am {} years old.'.format(self.name, self.age))
p1 = Person('Tom', 20)
p2 = Person('Jerry', 10)
print(p1)
结果是
这实际上是打印出了这个对象的地址
但是如果我们需要打印出这个对象的信息
那么我们需要一个方法
__str__()方法
举个例子
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def sayHello(self):
print('Hello. My name is {}. I am {} years old.'.format(self.name, self.age))
def __str__(self):
return "(Name:{}, Age:{})".format(self.name, self.age)
p1 = Person('Tom', 20)
p2 = Person('Jerry', 10)
print(p1.__str__())
继承
继承就是
一个类继承一个类,那么这个子类就继承了父类的属性和方法
举个例子
刚刚我们的类是Person,也就是人
那么我们来一个子类,比如Student继承Person
再来一个Teacher继承Person
学生和老师都是属于人,所以都是Person的子类
我们来看下代码
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def sayHello(self):
print('Hello. My name is {}. I am {} years old.'.format(self.name, self.age))
def __str__(self):
return "(Name:{}, Age:{})".format(self.name, self.age)
class Student(Person):
pass
class Teacher(Person):
pass
stu01 = Student('Tom', 20)
print(stu01)
tea01= Teacher('Jerry',30)
print(tea01)
现在我们把Student和Teacher这两个类弄得复杂一点
他们都属于Person,都是Person的子类
但是Student和Teacher肯定是有一些不同的
我们来举个例子
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def sayHello(self):
print('Hello. My name is {}. I am {} years old.'.format(self.name, self.age))
def __str__(self):
return "(Name:{}, Age:{})".format(self.name, self.age)
class Student(Person):
def sayHello(self):
super(Student, self).sayHello()
print('I am a student.')
class Teacher(Person):
def sayHello(self):
super(Teacher, self).sayHello()
print('I am a teacher.')
stu01 = Student('Tom', 20)
stu01.sayHello()
tea01 = Teacher('Jerry', 30)
tea01.sayHello()
Student和Teacher都继承了Person
都调用了Person的sayHello方法
同时又加入了自己的语句
最终两个类都输出了Person的sayHello方法
然后又各自输出了sayHello的语句
然后再增加一下Student的属性和方法
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def sayHello(self):
print('Hello. My name is {}. I am {} years old.'.format(self.name, self.age))
def __str__(self):
return "(Name:{}, Age:{})".format(self.name, self.age)
class Student(Person):
def __init__(self, name, age):
super(Student, self).__init__(name, age)
self.modules = []
def enroll(self, module):
self.modules.append(module)
def sayHello(self):
super(Student, self).sayHello()
print('I am a student.')
class Teacher(Person):
def sayHello(self):
super(Teacher, self).sayHello()
print('I am a teacher.')
stu01 = Student('Tom', 20)
stu01.sayHello()
stu01.enroll('Math')
stu01.enroll('English')
print(stu01.modules)
tea01 = Teacher('Jerry', 30)
tea01.sayHello()
public,protected,private attribute属性
1.public 可以在外部访问
2.protected 只有自身和子类可以访问
3.private 只有自己可以访问
默认情况下,所有属性都是public的,也就是公开的
如果要让一个属性或者一个方法变成protected
比如刚刚的sayHello方法,是可以在外部访问的
那么我们如果修改这个方法为private
就变成了 __sayHello()
那么就不能在外部访问了
看下代码
class Person():
def sayGoodbye(self):
print('bye')
def __sayHello(self):
print('hello')
p = Person()
p.sayGoodbye()
p.__sayHello()
两个方法
一个是sayGoodbye,是public
一个是__sayHello,是private
调用这两个方法,结果是
注意
_function_(),,,,,,这种命名方式,,,在方法名的两边加上下划线
是python预留的特殊方法名字
有时候,调用某些方法的时候,会唤醒__function__()这样的方法
旁边是2个下划线
比如
我们调用str(x)
实际上调用了__str__(x)
special methods特殊方法
multiple classes多个类
刚刚我们创建了Student类,用来表示学生
那么如果我们想创建一个班级的类,比如module,那么这个module班级里面应该是有多个学生的
所以module里面有student
我们来试试看