回顾
绑定方法
1.绑定给对象
# 特点:对象调用
class Student():
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def choose_course(self):
pass
sut = Student('ly',20,'male')
# 使用类里面的方法,默认绑定给对象
stu.choose_corse() # stu.choose_corse(stu)
2.绑定给类
# 类调用
class Student():
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
@classmethod # 只要加上该装饰器,该方法绑定给类,由类调用,把类名当成第一个参数传入
def choose_course(cls):
# cls就是类名
pass
# 如果方法里面即需要类,也需要对象,最好绑定给对象
def func(self):
print(self) # 对象
print(self.__class__) # 类
# 使用类里面的方法,使用@classmethod装饰的函数都是绑定给类
Student.choose_course()
非绑定方法
# 既不绑定给类,也不绑定给对象。静态方法
class Student():
@staticmethod # 静态方法,不管是谁来调用,都不会自动传递参数
方法名字
隐藏属性
1.如何隐藏属性 __隐藏的名
'''
1.给属性或方法名前加__
2.隐藏对外不对内,外部想要使用,在类内部开放可访问的接口,可以设置限定,对外部做严格的控制,防止外部随意更改内部属性
3.在类的定义阶段发生了语法上的变形,之后的__也不会发生变形
'''
property 装饰器
@proerty
把方法伪装成相对性的属性。
@属性名.setter # 名字要与相对性的属性名一至
方法
# 了解即可
name = property(方法名1,方法2,方法3) # 顺序不可乱
面向对象的三大特征
封装
封装
类似函数,类,将面条版代码封装起来
继承(重要)
1.什么是继承?
# 继承就是新建类的一种方式,新建的类我们成称为子类或者派生类,被继承的类称之为父类或者基类
# 子类可以使用父类中的属性或者方法
2.为什么要用继承
# 类,解决了对象与对象之间的代码冗余问题
# 继承解决的是类与类之间的代码冗余问题
3.如何使用继承
新式类:继承了object类的子子孙孙类都是新式类
经典类:没有继承了object类都是经典类
# 新式类和经典类之后在python2中区分,Python3中默认都是新式类
怎么使用继承
class Parent1 # 默认继承内置类(object)
pass
class Parent2 # 所有类都默认
pass
class Sub1(Parent1):
pass
class Sub2(Parent1,Parent2)
pass
__bases__ # 查看子类继承了哪些父类
print(Sub1.__bases__) # 查看有哪些父类
print(Parent1.__bases__) # object
学生选课为例
# 父类(公共类)
class People():
shool = 'SH'
def __int__(self, name, age, gender)
self.name = name
self.age = age
self.gender = gender
# 学生类
class Student(People):
def __init__(self, course=None):
if course is None:
course = []
# 学生类与老师类里面相同的属性就可以放在父类中
People.__init__(self, name, age, gender) # 就是调用父类的类,不继承也可以正常调用
self.courses = course
def choose_course(self,course):
self.course.append(course)
print('%s 选课成功 %s' % (self.name, self.courses))
# 老师类
class Teacher(People):
def __init__(self, level):
self.level = level
People.__init__(self, name, age, gender)
def score(self, stu_obj, score): # 自动传入老师对象,在传入学生对象,然后传入学生分数
syu_obj.score = score # 给学生对象添加分数的属性
print('%s给%s打了%s分' % (self.name, stu_obj.name, score))
stu = Student() # 产生一个学生对象
tea = Teacher() # 产生一个老师对象
继承的属性查找顺序
1.单继承下的属性查找
对象自身>>产生对象的类>>继承的父类 # 注意隐藏属性的实际是类名加属性名
# 练习1
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
#
print('Foo.f2')
self.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj = Bar() # {}
obj.f2()
# 练习2
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
#
print('Foo.f2')
self.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj = Bar() # {}
obj.f2()
2.多继承下的属性查找
# 可恶的菱形查找
# 了解
经典类的查找顺序:多继承情况下,在要查找属性不存在自身的时候,会按照'深度优先'的方式查找下去(最终汇聚的类不能是obj的类)'在继承的父类中左到右依次查找'先最深查询即优先找到最后一个父类
非菱形查找:没有汇聚的顶端
# 重要
新式类查找顺序:多继承,要查找属性不存在时,会按照'广度优先'的方式查找下去,'留一个最深的先不找,到最后一个父类之火在找最深的'
# 练习
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()列表
mro() 了解 # 帮助继承属性查找
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的在子类中使用
# mro列表练习1
class A:
def test(self):
print('from A.test')
super().test() # 运行,找到.test()功能
class B:
def test(self):
print('from B')
class C(A, B):
pass
c = C()
c.test() # 查找顺序按照mro列表寻找。
# mro列表练习2
class B:
def test(self):
print('B---->test')
def aaa(self): # super().aaa()找到这里
print('B---->aaa') # 打印
class A:
def test(self): # c.tset()找到这里
print('A---->test') # 打印
super().aaa() # 然后找.aaa()这个功能,不会回头,会继续在C的另一个父类中寻找
class C(A, B):
def aaa(self):
print('C----->aaa')
c = C()
c.test() # 寻找方法,自身没有,到父类中寻找,找到之后运行
print(A.mro())
多态与多态性(了解)
抽象类只能被继承,不能被实例化
import abc # 调用模块。
class 类名(metaclass = abc.ABCMeta) # 强制限制
# 抽象方法
@abc.abstractmethod # 加上这个语法糖代表已经是抽象方法了
def 函数名(self):pass
# 子类必须要有父类中的抽象方法函数名
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
def login(self):
pass
class Pig(Animal):
def speak(self):
print('哼哼哼')
class Dog(Animal):
def speak(self):
print('汪汪汪')
obj = People()
obj.speak()
'Python不推荐这么使用'
多态带来的特性:在不用考虑对象数据类型的情况下,直接调用对象的函数
# 掌握
父类限制子类行为。主动抛异常
raise 异常名称:
异常处理
1.什么是多态:
多种形态:同一类的多种形态
# 多态练习
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 animmal.speak()
animal(obj) # 调用这个函数,然后一个对象,对象使用speak()方法。不会存在方法不存在报错的情况
# 父类限制子类的行为
class Animal():
def speak(self):
raise Excepyion('!!!') # 如果对应的子类没有speak()方法。就会抛出异常