面向对象编程
类和对象
类(Class):用来描述具有相同属性和方法的对象的集合
class Student:
name='stu'#属性
def say(self):#方法
print("hello")
对象:一个类的实例。
对象名=类名()
s1=Student()
print(s1.name)#对象名.属性
s1.say()#对象名.方法
**类和对象详细知识点:
1.pass语句——类似于空语句
class A:
pass
def demo():
pass
if 5>3:
pass
2.属性
1)实例属性
init(self):
只有实例(对象)才能调用
2)类属性
是 在 类中方法之外定义的属性,多个实例共享
可以通过类名或者实例名访问
方法可以调用类中的其它方法,可以访问类属性、对象属 性。
类和对象都可以动态地增加成员
定义:
class Student:
name="stu" #类属性
def __init__(self):
self.name="default" #实例属性
self.age=0 #实例属性
def study(self):
print("study")
def say(self):
self.attr="attr" #额外增加的实例属性
print("hello")
self.study() #调用其他方法
调用:
s1=Student()
Student.sex="man" 增加的类属性
s1.height=1.75 #增加的实例属性
print(s1.height)
print(s1.sex)
print(s1.name)
#print(s1.attr) 没有初始化,无法访问
s1.say() print(Student.name)
print(s1.age)
print(s1.attr)
s2=Student() #创建新的实例
print(s2.sex)
print(s2.height) #没有该实例属性
3.属性访问权限
1)私有属性是以__开头。只能在来的内部使用,通过self或类名访问,但可以使用:实例名._类名__私有属性 来访问
2)受保护属性以_开头。只能让类和子类进行访问,但不能使用“from module import”引入
3)其他为共有属性。可以公开使用的,既可以在内部使用,也可以在外部使用(即通过对象访问)使用
定义:
class Student:
__money=10000
def showmoney(self):
print(self.__money)
访问:
s1=Student()
#print(s1.__money) #无法访问 私有属性
s1.showmoney()
**print(s1._Student__money) #又可以访问了,没有纯粹的私 有属性**
4.特殊属性
@property可将一个方法转换成属性,不可修改
class Rect:
def __init__(self,width,height):
self.width=width
self.height=height
@property def area(self):
return self.width*self.height
rect=Rect(20,30)
print(rect.area)
rect.area=500 # AttributeError: can't set attribute
5.类的特殊方法
以 __ 开头
构造方法:python中类的构造方法是__init__
如果用户没定义,会自动提供一个默认的构造方法
析构方法:python中类的析构方法是__init__
用来释放对象占用的资源,在python收回对象空间之前自动执行。如果没设计,系统将提供一个默认的析构方法
类有4种方法:公有方法,私有方法(__开头),静态方法和类方法
公有方法、私有方法都属于对象,每个对象都有自己的公有方法和私有方法,并且可以访问属于类和对象的成员
公有方法通过对象名调用,私有方法不能通过对象名调用,只能在属于对象的方法中通过self调用
静态方法和类方法都通过类名和对象名调用,但不能访问属于对象的成员,只能访问属于类的成员。类方法定义时,
需要一个类型参数
#类名调用方法时需要实例参数
例题:
通过特殊方法重写,完成新功能
len(self)
str(self)
eq(self, other)
1.实现len(s1),输出名字的长度
2.实现print(s1),输出该学生名字
3.实现当两个学生名字相同时,认为相同
class Student:
def __init__(self,name):#特殊方法——构造方法
self.name=name#实例属性
def __len__(self):#特殊方法
print(len(self.name))#输出名字的长度
def __str__(self):#特殊方法
print(self.name)#输出名字
def __eq__(self, other):#特殊方法
if self.name==other.name:#当两个学生姓名相同的时,认为相同
return True
else:
return False
s1=Student('zhangsan')#定义实例——对象
s2=Student('zhangsan')
s1.__len__()#调用方法
s1.__str__()
print(s1.__eq__(s2))
D:\Anaconda3\python.exe D:/PycharmProjects/Python_code/demo6-7.py
8
zhangsan
True
Process finished with exit code 0
6.动态添加方法type.MethodType()
import types
class Car:
price = 100000#定义类属性
def __init__(self,c):
self.color = c#定义实力属性
car1 = Car("red")
def setSpeed(self,s):
self.speed=s
car1.setSpeed = types.MethodType(setSpeed(,Car))
#动态为对象增加成员方法
car1.setSpeed(50)#调用对象的成员方法
print(car.speed)
7.在python中,函数和方法是有区别的。方法一般指与特定实例绑定的函数,通过对象调用方法时,对象本身将作为第一个参数传递过去,普通函数不具备这个特点
import types
class Demo:
pass
t = Demo()
def test(self, v):
self.value = v
t.test = test
print(t.test)
t.test(t, 3)
print(t.value)
t.test = types.MethodType(test, t)
print(t.test)
t.test(5)
print(t.value)
结果:
<function test at 0x000001CCE6B34378>
3
<bound method test of <__main__.Demo object at 0x000001CCE69080B8>>
5
8.继承
继承是为代码重写而设计的,当我们设计一个新的类时,为了代码重用可以继承一个以设计好的类。在继承关系中 ,原来设计好的类称为父类或基类,新设计的类称为子类或派生类
派生类可以继承父类所有的成员,但不能访问其私有成员
python支持多继承,如果父类中有相同的方法名,而子类中没有时没有指定父类名,则python解释器将会从左向右进行搜索
**#基类必须继承于object**
class Person(object):#基类必须继承于 object
def __init__(self, name = '', age = 20, sex = 'man'):
self.setName(name)
self.setAge(age)
self.setSex(sex)
def setName(self, name):
self.__name = name #私有实例 属性
def setAge(self, age):
self.__age = age #私有实例属性
def setSex(self, sex):
self.__sex = sex
def show(self):
print(self.__name)
print(self.__age)
print(self.__sex)
class Teacher(Person):
def __init__(self, name='', age = 30, sex = 'man', department = 'Computer'):
super(Teacher, self).__init__(name, age, sex) #Person.__init__(self, name, age, sex)#等同
self.setDepartment(department)
def setDepartment(self, department):
self.__department = department
def show(self):
super(Teacher, self).show()
print(self.__department)
p= Person('Zhang San', 19, 'man')
p.show()
s = Teacher('Li Si',32, 'man', 'Math')
s.show()
9.方法的重写
当子类中定义和父类中完全一样的方法时,称为子类对父类方法的重写,子类对象调用时,优先用子类中的方法,如果要用父类方法时,使用super()
class Fruit:
def showColor(self):
print("green")
class Apple(Fruit):
def showColor(self):
super().showColor()#调用父类的方法
print("red")
a=Apple()
10.异常处理
**python中有两种很容易辨认:语法错误和异常
语法错误:语法规则不满足
异常:程序运行时出现错误(不符合逻辑)**
try:
#可能出现异常的语句
except 异常类型1:
#处理异常类型1的语句
except:
#处理异常1除外的语句
else:
#没有异常时执行的语句
finally:
#总会执行的语句
try:
num1 = eval(input("num1:"))
num2 = eval(input("num2:"))
result = num1 / num2
except NameError:
print("NameError")
except ZeroDivisionError:
print("ZeroDivisionError")
except Exception:
print("Exception")
else:
print("result:" + str(result))
finally:
print("finally")
常见系统预定义异常
BaseException 所有异常的基类
Exception 常规错误基类
ZeroDivisionError 除(或取模)零
IOError 输入/输出操作失败
IndexError 序列中没有此索引
NameError 未声明/初始化对象
TypeError 对类型无效的操作
ValueError 传入无效的参数
注意:意义通过raise主动引发异常,也可以被动感受到系统预定义异常
需要注意的是:
1.在上面所示的完整语句中try/except/else/finally所出现的顺序必须是try-->except 异常类型1-->except-->else-->finally,即所有的except必须在else和finally之前,else(如果有的话)必须在finally之前,而except 异常类型1 必须在except之前。否则会出现语法错误。
2.对于上面所展示的try/except完整格式而言,else和finally都是可选的,而不是必须的,但是如果存在的话else必须在finally之前,finally(如果存在的话)必须在整个语句的最后位置。
3.在上面的完整语句中,else语句的存在必须以except 异常类型1 或者except语句为前提,如果在没有except语句的try 中使用else语句会引发语法错误。也就是说else不能与try/finally配合使用。
这部分的详细内容可以看python基础知识三——try与except处理异常语句
该文章作者是:站着刷论文
11.用户自定义异常:
异常应该继承自Exception类,作为系统预定义异常的补充
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return str(self.value)
try:
raise MyError(2*2)#raise不能与else并用,因为raise一定引起错误
except MyError as e:
print('My exception occurred, value:',e.value)
图书信息管理系统:
class Book:
def __init__(self,name,author,comment,state=0):
self.name=name
self.author=author
self.comment=comment
self.state=state
def __str__(self):
status='未借出'
if self.state==1:
status='已借出'
return '书名:《%s》作者:%s 评语:%s \n状态:%s'%(self.name,self.author,self.comment,status)
class Manager:
books=[]
def __init__(self):
book1=Book('惶然录', '费尔南多·佩索阿', '一个迷失方向且濒于崩溃的灵魂的自我启示,一首对默默无闻、失败、智慧、困难和沉默的赞美诗。')
book2=Book('以箭为翅', '简媜', '调和空灵文风与禅宗境界,刻画人间之缘起缘灭。像一条柔韧的绳子,情这个字,不知勒痛多少人的心肉。')
book3=Book('心是孤独的猎手', '卡森·麦卡勒斯', '我们渴望倾诉,却从未倾听。女孩、黑人、哑巴、醉鬼、鳏夫的孤独形态各异,却从未退场。', 1)
self.books.append(book1)
self.books.append(book2)
self.books.append(book3)
def manu(self):
print("欢迎来到图书管理系统!")
while True:
print('1.查询所有书籍\n2.添加书籍\n3.借阅书籍\n4.归还书籍\n5.退出系统\n')
choice=int(input("请输入数字来选择相应的功能;"))
if choice==1:
self.show_all_book()
elif choice==2:
self.add_book()
elif choice==3:
self.lend_book()
elif choice==4:
self.return_book()
elif choice==5:
print("感谢使用图书管理系统,相约江湖,有缘再见!")
break
else:
print("没有该数字对应的功能,请检查后重新输入!")
def show_all_book(self):
print("书籍信息如下:")
for book in self.books:
print(book)
print('')#分隔信息
def add_book(self):
print("请输入要添加的书籍的信息:")
new_name=input("书名:")
result=self.check_book(new_name)
if result == None:
new_author = input("作者:")
new_comment = input("推荐语:")
new_book = Book(new_name, new_author, new_comment)
self.books.append(new_book)
print("添加成功!\n")
else:
print("该书已存在!")
def check_book(self, name):
for book in self.books:
if book.name == name:
return book
else:
return None
def lend_book(self):
name = input("请输入你想借的书的名称:")
result = self.check_book(name)
if result == None:
print("不好意思,目前还没有这本书!")
else:
if result.state==1:
print("这本书已被借出!")
else:
result.state=1
print("借阅成功!")
def return_book(self):
book=input("请输入要归还的书名:")
result=self.check_book(book)
if result == None:
print("目前没有这本书!")
else:
if result.state==0:
print("这本书未被借出,请再次检查是否输入错误!")
else:
result.state=0
print("归还成功!")
manager=Manager()
manager.manu()