内容概要
面向对象的三大特征
继承的属性查找顺序
super()和mro()列表
多态与多态性(了解)
组合
面向对象的内置函数(魔术方法,魔法,开头的方法)
反射
异常
内容详细
继承(重要)
1.什么是继承?
# 继承就是新建类的一种方法,新建的类我们成为子类或者派生类,被继承的类我们称为父类或者基类
# 子类可以使用父类中的属性或者方法
2.为什么要用继承?
类解决了对象与对象之间的代码冗余问题
继承解决了类与类之间的代码冗余问题
3.如何使用继承?
新式类:继承了object类的子子孙孙类都是新式类
经典类:没有继承object类的子子孙孙类都是经典类
# 新式类和经典类只有在python2中区分
类的继承
# 以学生选课系统为例
# 父类,公共类
# class People():
# school = 'sh'
#
# def __init__(self,name,age,gender):
# self.name = name
# self.age = age
# self.gender = gender
#
# # 学生类
# class Stndent(People):
# def __init__(self,name,age,gender,course=None):
# if course is None:
# course = []
# People.__init__(self,name,age,gender)
# self.course = course
#
# def chose_course(self,course):
# self.course.append(course)
# print('%s选课成功%s'%(self.name,self.course))
#
# stu = Stndent('jason',18,'male')
#
#
# # 教师类
# class Teacher(People):
# def __init__(self,name,age,gender,level):
# self.level = level
# People.__init__(self,name,age,gender)
#
# def score(self,stu_obj,score):
# stu_obj.score = score
# print('%s给%s打了%s分'%(self.name,stu_obj.name,score))
#
# tea = Teacher('ly',18,'mail',10)
# print(tea.name)
# print(tea.age)
# print(tea.gender)
# print(tea.level)
# tea.score(stu,80)
单继承下属性查找
# class Foo:
# def f1(self):
# print('Foo.f1')
#
# def f2(self):
# print('Foo.f2') # 打印
# self.f1() # self = Bar
#
#
# class Bar(Foo):
# def f1(self):
# print('Bar.f1')
#
#
# obj = Bar() # {}
# obj.f2() # Foo.f2 Bar.f1
# 练习
# class Foo:
# def __f1(self): # _Foo__f1()
# print('Foo.f1')
#
# def f2(self):
# #
# print('Foo.f2')
# self.__f1() # _Foo__f1()
#
#
# class Bar(Foo):
# def __f1(self): # # _Bar__f1()
# print('Bar.f1')
#
#
# obj = Bar() # {}
# obj.f2() # Foo.f2 Foo.f1
多继承下的属性查找
# 新式类:按照广度优先查询
# 经典类:按照深度优先查询
# class A(object):
# def test(self):
# print('from A')
#
#
# class B(A):
# # def test(self):
# # print('from B')
# pass
#
#
# class C(A):
# # def test(self):
# # print('from C')
# pass
#
#
# class D(B):
# # def test(self):
# # print('from D')
# pass
#
#
# class E(C):
# # def test(self):
# # print('from E')
# pass
#
#
# class F(D, E):
# # def test(self):
# # print('from F')
# pass
#
#
# f1 = F()
# f1.test()
super()和mro列表
# class People():
# school = 'SH'
#
# def __init__(self,name,age,gender):
# self.name = name
# self.age = age
# self.gender = gender
#
# class Teacher(People):
# def __init__(self,name,age,gender,level):
# self.level = level
# super().__init__(name,age,gender) # super的使用
#
#
# tea = Teacher('tom', 18, 'male', 2)
# print(tea.name)
# tea1 = Teacher('iii',19,'female',3)
# print(tea1.gender)
# print(tea1.level)
# mro列表练习1
# class A:
# def test(self):
# print('from A.test')
# super().test()
#
#
# class B:
# def test(self):
# print('from B')
#
#
# class C(A, B):
# pass
#
#
# c = C()
# print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
#
# c.test() # from A.test # from B
# mro列表练习2
# class B:
# def test(self):
# print('from B')
#
# def aaa(self):
# print('from aaa')
#
# class A:
# def test(self):
# print('from A')
# # super().aaa()
#
# class C(A,B):
# def aaa(self):
# print('from C')
#
# c = A()
# c.test() # from A
#
# print(A.__mro__)
# print(A.mro())
多态与多态性(了解)
1.什么是多态
水:固态水,液态水,气态水
动物:人,猪,狗,猫 ...
# 抽象类:抽象类只能被继承,不能被实例化
# import abc
#
# class Animal(metaclass=abc.ABCMeta):
# @abc.abstractmethod # 该方法已经是抽象方法了
# def speak(self):pass
#
# @abc.abstractmethod
# def login(self):pass
#
# class People(Animal):
# def speak(self):
# print('嗷嗷叫')
# pass
#
# class Pig(Animal):
# def speak(self):
# print('哼哼哼')
#
# class Dog(Animal):
# def speak(self):
# print('汪汪汪')
#
# obj = People()
# obj.speak()
# 多态练习
class Pig():
def speak(self):
print('哼哼哼')
class Dog():
def speak(self):
print('汪汪汪')
class Txt():
def speak(self):
print('Txt')
obj = People()
obj1 = Pig()
obj2 = Dog()
obj3 = Txt()
# 多态带来的特性:在不用考虑对象数据类型的情况下,直接调用对应的函数
def animal(animal):
return animal.speak()
animal(obj)
animal(obj1)
animal(obj2)
animal(obj3)
# 父类限制子类的行为
class Animal():
def speak(self):
raise Exception("必须实现speak方法")
组合
组合:就是一个对象拥有一个属性 该属性的值是另外一个对象
继承:解决了类与类之间的代码冗余问题
1.继承:满足什么是什么的关系,is a 的关系
2.组合:有的关系,eg:教师有生日,教师教python和linux课程,教师有学生s1、s2...
# class People():
# school = 'sh'
#
# def __init__(self,name,age,gender):
# self.name = name
# self.age = age
# self.gender = gender
#
# class Course():
# def __init__(self,name,period,price):
# self.name = name
# self.period = period
# self.price = price
#
# python = Course('python','6mon',10000)
# linux = Course('linux','5mon',20000)
#
# class Student(People):
# def __init__(self,name,age,gender,course = None):
# if course is None:
# course = []
# self.courses = course
# super().__init__(name,age,gender)
#
# def choose_course(self,stu_obj,course):
# stu_obj.courses.append(course)
#
# stu = Student('ly',20,'male')
# stu.courses.append(python)
# stu.courses.append(linux)
#
# for course in stu.courses:
# print(course)
# 得到两个内存地址
# <__main__.Course object at 0x0000026C91FAB080>
# <__main__.Course object at 0x0000026C91FAB0B8>
# for course in stu.courses:
# print(course.price)
# 10000
# 20000
面向对象的内置函数
1. __init__()
2. __str__()
3. __del__()
4. __enter__()
5. __exit__()
6. __call__()
class Student():
school = 'SH'
# 调用类的时候触发
def __init__(self, name, age):
self.name = name
self.age = age
def tell(self):
print('name: %s, age: %s' % (self.name, self.age))
# 打印对象的时候,自动触发的函数
# 返回值只能是字符串
def __str__(self):
return 'name:%s' % self.name
# return 123
# 1. 手动执行del
# 2. 程序执行完毕触发
def __del__(self):
print('__del__')
self.f.close()
# 对象加括号自动触发
def __call__(self, *args, **kwargs):
print('__call__')
stu = Student('ly', 20)
反射
# 对象通过字符串来操作属性
1. getattr
print(getattr(stu, 'name1', None)) # stu.name
stu.func()
print(getattr(stu, 'func'))
getattr(stu, 'func')() # 必须掌握
2. setattr
setattr(stu, 'x', 123)
print(stu.__dict__)
3. hasattr
print(hasattr(stu, 'name'))
4. delattr
delattr(stu, 'name')
print(stu.__dict__)
异常
1.什么是异常?
异常就是错误发生的信号,如果不对该信号做处理,那么异常之后的代码都不会执行
2.异常的种类
1)语法错误
print(123
2)逻辑错误
a = [1, 2, 3]
a[4]
3. 异常的作用
增强代码的健壮性
4. 异常的使用
try:
被监测代码
except 异常的类型:
pass
except 异常的类型:
pass
except 异常的类型:
pass
except Exception as e:
pass
else:
当被监测代码没有发生异常的时候,触发的
pass
finally:
不管被监测的代码有没有出错,都执行