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中都是新式类

 

super和mro列表

super 返回的是一个 特殊 的对象(重点是对象)

super是再子类中可以使用,调用的是父类的名称空间中的方法 但是在类中调用

 

mro,用法是 类名.mro  返回的是属性是子类 依次 查找的基类 的 顺序

复制代码
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'>]
复制代码

 

多态与多态性

多态指的是一类事物有多种形态

动物有多种形态:人,狗,猪

需要导入abc模块

@abc.abstractmethod装饰器限制,并且父类中不写具体的功能,

下面的子类必须拥有父类中的方法,并且要实现这个功能(或者pass)

复制代码
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
    elseprint('当没有发生异常的时候执行')
    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('出问题啦')
复制代码

 

posted @   Damon1899  阅读(78)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
点击右上角即可分享
微信分享提示