Python

Python 面向对象编程详解

·11 分钟阅读·4059 字

Python 面向对象编程详解 的详细笔记

📋 目录

Python 面向对象编程详解

核心概念 Python 面向对象编程涵盖类与对象、继承、多态、封装、魔术方法等。

1. 什么是面向对象

面向对象是一种编程思想,把程序看作「对象的集合」,和面向过程(按步骤写函数)对立:

  • 面向过程:关注怎么做,拆分步骤、函数;
  • 面向对象:关注谁来做,拆分事物(类),封装属性和行为。 两个核心基础概念:
  1. 类 Class:模板、图纸,定义一类事物共有属性、方法;
  2. 实例 Instance:根据类创建出来的真实对象,每个实例独立拥有自己的数据。 示例:
    Person 是类(模板);p1 = Person() 是实例(具体的人)

# 定义类

class Person:

    pass

# 创建实例

p1 = Person()

p2 = Person()

2. 类的核心组成:属性 + 方法

2.1. 属性(变量)

分为两类:

1)实例属性:每个实例独有,写在 __init__ 构造函数里

2)类属性:属于类本身,所有实例共享,写在类内部最上方


class Person:

    # 类属性(全局共享)

    species = "人类"

    # 构造方法:创建实例自动执行

    def __init__(self, name, age):

        # 实例属性(每个对象独立)

        self.name = name

        self.age = age

p1 = Person("张三", 20)

p2 = Person("李四", 22)

print(p1.name)    # 张三(实例属性)

print(Person.species) # 人类(类属性)

print(p1.species) # 人类,实例可以读取类属性

# 修改类属性,全部实例同步变化

Person.species = "智人"

print(p2.species) # 智人

2.2. 方法(函数)

方法第一个参数必须是 self,代表当前实例本身。

2.2.1. (1)实例方法(最常用)

只能由实例调用,可读写实例属性、类属性


class Person:

    def __init__(self, name):

        self.name = name

    # 实例方法

    def say_hello(self):

        print(f"我是{self.name}")

p = Person("小明")

p.say_hello()

2.2.2. (2)类方法 @classmethod

@classmethod 装饰,第一个参数 cls 代表类本身,不能访问实例属性,只能操作类属性


class Person:

    count = 0

    def __init__(self):

        Person.count += 1

    @classmethod

    def get_count(cls):

        return cls.count

print(Person.get_count())

2.2.3. (3)静态方法 @staticmethod

@staticmethod,无默认参数,既不能访问实例,也不能访问类,单纯挂靠在类里的普通函数


class Math:

    @staticmethod

    def add(a, b):

        return a + b

print(Math.add(1,2))

2.3. 三种方法面试区分总结

| | | | | | |

|---|---|---|---|---|---|

|类型|装饰器|首参数|访问实例属性|访问类属性|调用方式|

|实例方法|无|self|✅ 可以|✅ 可以|实例.方法()|

|类方法|@classmethod|cls|❌ 不行|✅ 可以|类/实例均可调用|

|静态方法|@staticmethod|无|❌ 不行|❌ 不行|类/实例均可调用|


3. 四大特性(面试必考核心)

3.1. 封装 Encapsulation

把数据和操作数据的方法打包到类内部,隐藏内部细节,对外暴露简单接口

Python 没有严格私有,靠命名规范区分:

  1. name:公有,外部随便读写
  2. _name:单下划线,约定私有,不建议外部直接访问
  3. __name:双下划线,名称改写(name mangling),外部无法直接访问

class Person:

    def __init__(self, age):

        self.__age = age  # 私有属性

    # 对外提供读取接口

    def get_age(self):

        return self.__age

    # 对外提供修改接口,可增加校验逻辑

    def set_age(self, new_age):

        if 0 < new_age < 150:

            self.__age = new_age

        else:

            print("年龄非法")

p = Person(20)

print(p.get_age())

p.set_age(200) # 提示非法

好处:控制数据修改逻辑,防止脏数据。

3.2. 继承 Inheritance

子类复用父类代码,还能扩展新功能;语法 class 子类(父类):


# 父类

class Animal:

    def eat(self):

        print("动物吃东西")

# 子类 Dog 继承 Animal

class Dog(Animal):

    def bark(self):

        print("汪汪叫")

d = Dog()

d.eat()  # 继承父类方法

d.bark() # 自己独有方法

3.2.1. 重写 override

子类和父类同名方法,优先执行子类自己的逻辑:


class Dog(Animal):

    def eat(self):

        # 先调用父类原有逻辑

        super().eat()

        print("狗啃骨头")

super() 代表父类对象,用于调用父类构造/方法。

3.2.2. 多重继承

Python 支持一个类同时继承多个父类:class A(B,C)

MRO 查找顺序(面试高频):方法解析顺序,用 类名.__mro__ 查看,从左到右深度优先查找。

3.3. 多态 Polymorphism

同一个方法,不同子类实现不同逻辑,调用时自动匹配对应实现。

核心:只要拥有同名方法,就能统一调用


class Cat(Animal):

    def eat(self):

        print("猫吃鱼")

def feed(animal):

    animal.eat() # 统一接口,自动适配不同子类

feed(Dog())

feed(Cat())

3.4. 抽象(拓展,中级面试)

abc 模块定义抽象基类,强制子类必须实现指定方法,否则无法实例化。


from abc import ABC, abstractmethod

class Animal(ABC):

    @abstractmethod

    def eat(self):

        pass

# 子类必须重写eat,否则报错

4. 常用魔术方法(Magic Method,面试高频)

__xx__ 命名,实例触发对应行为自动执行

  1. __init__(self):构造方法,创建实例时执行,初始化属性
  2. __new__(cls):创建实例对象(在__init__之前,单例模式常用)
  3. __del__(self):析构方法,对象被销毁时执行
  4. __str__(self)print(对象) 输出人类可读字符串
  5. __repr__(self):开发调试用,精准还原对象
  6. __enter__ / __exit__:实现 with 上下文管理器(文件操作原理)
  7. __getitem__:支持 obj[0] 下标取值
  8. __call__:对象可以像函数一样 obj() 调用 示例:

class Person:

    def __init__(self, name):

        self.name = name

    def __str__(self):

        return f"Person(name={self.name})"

p = Person("张三")

print(p) # 自动调用 __str__

5. 属性装饰器 @property

把方法伪装成属性,不用加括号调用,兼顾封装与简洁读写


class Person:

    def __init__(self, age):

        self.__age = age

    # 读

    @property

    def age(self):

        return self.__age

    # 写

    @age.setter

    def age(self, val):

        if 0 < val < 150:

            self.__age = val

p = Person(10)

print(p.age)   # 不用括号

p.age = 20

6. 面试高频问答(必背)

  1. self 是什么?
    代表当前实例对象,调用实例方法时自动传入,用来访问实例属性。
  2. 类属性和实例属性区别?
    类属性所有实例共享;实例属性每个对象独立,互不干扰。
  3. super() 作用?
    调用父类的构造函数或方法,解决多重继承代码复用。
  4. 单下划线 _x、双下划线 __x 区别?_x 约定私有,仅提示;__x 触发名称改写,外部无法直接访问。
  5. 实例方法/类方法/静态方法使用场景?
  • 实例方法:需要操作对象自身数据;
  • 类方法:只操作类全局数据,不需要实例;
  • 静态方法:和类、实例都无关,仅逻辑归类。
  1. MRO 多重继承查找规则?
    __mro__ 顺序,从左到右深度优先,保证父类只执行一次。
  2. __str____repr__ 区别?str 给用户看;repr 给开发者调试,还原对象代码。
  3. 面向对象三大/四大特性?
    封装、继承、多态;抽象是扩展特性。
  4. 什么是多态?好处是什么?
    统一调用接口,不同子类不同实现,代码易扩展、解耦。
  5. 装饰器 @property 作用?
    将方法转为属性,简洁读写,同时在赋值时增加数据校验逻辑。

关联文档

Yanche Blog

记录云原生、Linux、数据库等技术领域的学习心得,以及日常生活的思考与感悟。

© 2026 Yanche Blog. All rights reserved.

Powered by Astro