python 面向对象编程 知识点汇总
面向对象编程
什么是面向对象编程?
面向对象编程,英文Object Oriented Programming,OOP,是一种计算机编程架构,核心是 对象 两个字,重要的是思想
面向对象的特点:
优点:扩展性强
缺点:把简单的问题复杂化
应用场景: 对扩展性要求高的地方
举个栗子:
微信。很对人要求增加各种各样的功能,面向对象编程 能 更好的增加各种单独的功能
面向对象的三大特征:(重要)
封装,继承,多态,
类和对象:类是一系列具有相同特征 或 技能 的对象及集合体
在python中,先定义类,后通过类来新建对象
定义类的固定语法- class 类名():
注意:类名 的 第一个英文字母需要大写(约定俗称)并且符合命名规范
封装
定义 类 之后 发生了什么
1.定义类之后,会立马执行类体中的代码
2.执行类体代码,把类中的 属性 和 方法 都加到类的名称空间里面去
3 把类的名称空间绑定给__dict__, 即 类名.__dict__ (os:其实类的底层是一个字典,所以用dict关键词吧。。。。)
在类体中,变量被称为 类属性,而 函数 被称为 方法
ex:
class Student(): # 定义类属性 school = 'SH' # 在类中,函数被称为是方法 def choose_course(): pass
# 如何查看类的名称空间 class Student(): school = 'SH' def __init__(self, name, age): self.name = name self.age = age # 查看类的名称空间 print(Student.__dict__)
# 输出结果 {'__module__': '__main__', 'school': 'SH', '__init__': <function Student.__init__ at 0x000001B4772591F8>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None} # 是一个字典
# 产生对象, 调用类,类名() stu1 = Student('ly', 18) # 产生了stu1 这个对象,就是吧Student 这个类 实例化 # 查看对象的名称空间 print(stu1.__dict__)
输出结果:{'name': 'ly', 'age': 18}
# 从名称空间可以看到,实例化对象之后,也是是一个字典。
类 属性(即类体中的 变量) 的 增删改查
# 类属性的增删改查 # 增加 Student.xxx = 111 print(Student.xxx) # 即 在类中增加了一个 xxx = 111 的属性(就是类中的变量) # 删除 del Student.xxx # 删除类中 刚才增加的 xxx = 111 这个属性 # 修改 # 修改类中的属性,直接对他重新赋值就可以了 Student.school = 'USA' print(Student.school) # 查看 print(Student.__dict__) # 输出结果是一个字典,可以通过key 来取值 v 值
对象 属性 的增删改查
# 对象属性的增删改查 # 增加 同样直接赋值就可以 stu1.xx = 11 print(stu1.__dict__) # {'name': 'ly', 'age': 18, 'xx': 11} # 删除 del关键字 del stu1.xx print(stu1.__dict__) # {'name': 'ly', 'age': 18} # 修改 同样直接重新赋值就可以 stu1.name = 'gdw' print(stu1.__dict__) # {'name': 'gdw', 'age': 18} # 查询 就是 对象名.__dict__ print(stu1.__dict__) # {'name': 'gdw', 'age': 18}
绑定方法
分为绑定给类 和 绑定给对象 的方法
1.绑定给 对象 的方法
在类里面正常写的 函数 ,都是绑定给对象的。(貌似没啥实际意义)
# 绑定给 对象 的方法 # 在类里面正常写的 函数 ,都是绑定给对象的 class Animal(): def __init__(self, name, age): self.name = name self.age = age def info(self): print('名字:%s' % self.name) print('年龄:%s' % self.age) people = Animal('ly', 18) people.info() # 输出结果 名字:ly # 年龄:18
2 绑定给类的函数
# 绑定给 类 的方法,使用 关键字@classmethod class Animal(): def __init__(self, name, age): self.name = name self.age = age @classmethod def info(cls): # 约定促成填写的参数 是 cls(就是类名) return cls('ly', 18) # return之后的内容相 类似与调用类类名.方法名() # 调用的话,直接用类名 来 调用,而不是对象来调用 print(Animal.info()) # <__main__.Animal object at 0x0000020608EE1D48>
非绑定方法
就是 既不绑定给类,也不绑定给对象
# 非绑定方法 用关键字 @staticmethod 关键字 应用场景,比如 验证码 随机数 import random class People(): def __init__(self, name, age): self.name = name self.age = age self.id = self.create_num() @staticmethod def create_num(): return random.randint(1, 10)
隐藏属性(重要)
怎么隐藏属性: 在类定义阶段, 属性名 和 方法名 前面加 __(两个下划线)外部就无法调用,并且 隐藏 的属性对外不对内
为什么要隐藏:不让外部随意修改,或者需要按照 要求 来修改,可以对外部来严格限制
可以在类的内部 开放一个接口 返回类内部的隐藏的属性值
class Student(): __country = 'CHINA' # 相当于在底层中,字典中的key变成 _Student__country def __init__(self, name, age): self.__name = name # _Student__name self.age = age def __func(self): # _Student__func # print('from func') pass def country(self): return self.__country # self._Student__country def set_country(self, v): if not type(v) is str: # 可以限制外部如何修改,修改的话必须是字符串 print('不是str') return self.__country = v stu = Student('ly', 18) print(stu.country()) # CHINA stu.set_country('US') print(stu.country()) # US
property装饰器
作用 就是把函数伪装成属性,结合上面的隐藏属性,就可以在外部像修改属性一样,修改隐藏属性,并且可以有严格限制
ex:
class Student(): __country = 'CHINA' # 相当于在底层中,字典中的key变成 _Student__country def __init__(self, name, age): self.__name = name # _Student__name self.age = age def __func(self): # _Student__func # print('from func') pass @property # @property 让外部可以正常调用隐藏的country属性 def country(self): return self.__country # self._Student__country @country.setter # @属性名.setter 装饰器 修改 def country(self, v): if not type(v) is str: # 可以限制外部如何修改 print('不是str') return self.__country = v @country.deleter # 属性名.deleter 让外部不能删 def country(self): print('不能删除') stu = Student('ly', 18) print(stu.country) # CHINA stu.country = 'us' print(stu.country) # US
继承
. 什么是继承?
继承就是新建类的一种方式,新建出来的类称为子类或者叫派生类,被继承的类称为父类或者基类
子类可以遗传父类的属性
2. 为什么要用继承?
类解决了对象与对象之间的代码冗余问题
继承解决类与类之间的代码冗余问题
3. 怎么用继承?
经典类:没有继承object类的子子孙孙类都是经典类
新式类:继承了object类的子子孙孙类都是新式类
注意: '''只有在python2中才区分经典类和新式类,在python3中都是新式类'''
链接:http://www.cnblogs.com/linhaifeng/articles/7340153.html
单继承下的属性查找
一级一级往上,从最下的类中找,如果没有,往上一级的父类中找,如果没有 那就再往上一级的类中找
多继承下的属性查找
经典类: 深度优先 。# 但是只有python2 中才区分 经典类 和 新式类
新式类: 广度优先 # py3中都是新式类
class People(): school = 'SH' def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender class Student(People): def __init__(self, name, age, gender, course): self.course = course # 1. People.__init__(self, name, age, gender) # 2. super(Student, self).__init__(name, age, gender) # 在python2 # 3. super().__init__(name, age, gender) # 在python3中的写法 print(Student.mro()) # [<class '__main__.Student'>, <class '__main__.People'>, <class 'object'>]
import abc class Animal(metaclass=abc.ABCMeta): #括号中是固定写法 @abc.abstractmethod #加装饰器,把talk 改成抽象方法。就是Animal改成抽象类,抽象类的特点,只能被继承,不能被实例化 def talk(self): pass class People(Animal): #动物的形态之一:人 def talk(self): print('say hello') class Dog(Animal): #动物的形态之二:狗 def talk(self): print('say wangwang') class Pig(Animal): #动物的形态之三:猪 def talk(self): print('say aoao')
2.鸭子类型
认为拥有同一种方法的类,是同一类
ex:不强制限制,下面都有speak功能
class People(): def speak(self): pass class Dog(): def speak(self): pass class Cat(): def speak(self): pass
组合:
一个对象拥有一个属性,该属性的值是另外一个对象
# 组合:满足什么有什么的关系
# 继承:满足什么是什么的关系
class People(): 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', 20000) linux=Course('linux', '6mon', 20000) print(python.name) print(python.period) print(python.price) class Student(People): def __init__(self, name, age, gedner, course_name, course=None): if course is None: course = [] super().__init__(name, age, gender) self.course = course stu = Student('tom', 19, 'male') stu.course.append(python.name) stu.course.append(linux.name) for course in stu.course: print(course.name) class Teacher(People): def __init__(self, name, age, gedner, level): super().__init__(name, age, gender) self.level = level tea = Teacher() tea.course = python print(tea.course.name)
内置方法
只需要搞清楚,什么内置方法,在什么条件下会触发,就可以
1. __init__ # 在实例化的时候自动调用该方法 # __str__ class Student(): def __init__(self, name, age): self.name = name self.age = age # 打印或者输出对象的时候,自动调用的方法 def __str__(self): return 'name:%s' % self.name # return 123 # 返回结果是字符串,不能是整型 stu = Student('tom', 19) # print(stu) __del__ class Student(): def __init__(self, name, age): self.name = name self.age = age # self.f = open('a.txt') # 1. del 删除对象的时候自动触发 # 2. 当整个程序执行完毕在调用方法 def __del__(self): print('触发了') # self.f.close() stu = Student('tom', 19) del stu print(123) # __enter__ __exit__ class Open: def __init__(self,name): self.name=name def __enter__(self): print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量') # return self def __exit__(self, exc_type, exc_val, exc_tb): print('with中代码块执行完毕时执行我啊') with Open('a.txt') as f: print('=====>执行代码块') with open('a.txt', 'r', encoding='utf-8') as f: f.read() class Foo: x = 1 def __init__(self, y): self.y = y # pass def __getattr__(self, item): print('----> from getattr:你找的属性不存在') # 当设置的属性不存在的时候触发 def __setattr__(self, key, value): print('----> from setattr') print(key, value) # self.a = 200 # self.key=value #这就无限递归了,你好好想想 self.__dict__[key]=value #应该使用它 def __delattr__(self, item): print('----> from delattr') # del self.item #无限递归了 # self.__dict__.pop(item) # __setattr__添加/修改属性会触发它的执行 f1 = Foo(10) # print(f1.y) # f1.a = 200 del f1.a class Foo: def __init__(self): pass # 对象加括号 def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 执行 __init__ obj()
反射
通过字符串,来操作属性
暂时只需要掌握4个,都是内置的
其实就是增删改查
1. getattr() 查询,调用,可以调用 属性 和 方法 2. setattr() 修改 3. hasattr() 判断是否有 4. delattr() 删除
class Student(): school = 'SH' def func(self): print('from func') stu = Student() print(stu.school) print(getattr(stu, 'school')) # 上面2个等价,输出的结果 均是SH print(getattr(stu, 'school111', 111)) # 如果没有school111这个属性,那就输出后面的111 getattr(stu, 'func')() # 返回的是类中 方法 的内存地址,可以加()调用,输出结果from func # 2. setattr() setattr(stu, 'xxx', 1000) # 在对象的名称空间中,加上字典{’xxx‘ : 1000} print(stu.xxx) # 3. hasattr print(hasattr(stu, 'school')) # 判断后边的变量,是否在stu中,返回的是布尔值 # delattr delattr(stu, 'xxx') # 删除对象中的属性,删除类的属性,那就报错
异常
什么是异常?
异常就是错误发生的信号,如果不对该信号做处理,程序就会终止运行
为什么要用异常?
增加代码的健壮性
如何使用异常?
try: pass except 异常的类型: pass except 异常的类型: pass except 异常的类型: pass else: print('当没有发生异常的时候执行') finally: print('不管有没有异常都会执行')
# 主动抛出异常 class Animal(): def speak(self): raise Exception('必须实现speak方法') class Student(Animal): def speak(self): pass stu = Student() stu.speak() # 自定义异常 class MyException(BaseException): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg raise MyException('出问题啦')
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能