skip to content
Logo Lostman_Wang的小站

Python面向对象-面向对象基础

一、什么是对象和类

  • 类(class): 一种“蓝图”或“模具”,描述一类事物的共有属性(数据)与行为(函数)。
  • 对象(object): 根据类“生产”出来的具体实例(instance),拥有独立的属性值,但共享类中定义的方法。
  • Python 面向对象编程(OOP)是一种把“数据(属性)”和“操作数据的代码(方法)”封装在一起,进而组织程序的范式。核心概念是“对象”:对象由类(class)生成,类相当于模板,对象相当于实例。

二、Python 类

1、类定义语法

1.1、最小可运行语法:

class 类名:
pass # 占位语句,类体不能为空
  • 关键字 class,后跟类名(PascalCase 约定)。
  • 冒号 + 缩进块(通常 4 空格)。
  • 即使什么都不放,也要写 pass,否则 SyntaxError

1.2、包含属性、方法:

# 1. 定义类
class Dog:
species = "Canis familiaris" # ① 类属性(所有实例共享)
def __init__(self, name, age): # ② 构造器:创建对象时自动调用
self.name = name # ③ 实例属性(每个对象独立)
self.age = age
def bark(self, sound="Woof!"): # ④ 实例方法
print(f"{self.name}: {sound}")
# 2. 由类创建对象(实例化)
d1 = Dog("旺财", 3)
d2 = Dog("Lucky", 2)
# 3. 访问属性 / 调用方法
print(d1.name, d1.species) # 旺财 Canis familiaris
d2.bark("汪汪") # Lucky: 汪汪

三、类对象

1、相关概念

  • 类对象(class object):由 class 语句执行后,Python 在内存中创建的对象,类型是 type(元类)。
  • 实例对象(instance object):由“类对象”调用得到的具体个体,类型就是该“类对象”。

2、属性引用

2.1、属性引用语法

  • Python 中使用点号 . 运算符进行属性引用:
# 基本语法
obj.attribute # 访问对象的属性
Class.attribute # 访问类的属性

2.2、属性查找顺序

当通过实例访问属性时,Python 按照以下顺序查找:

  1. 实例命名空间 - 首先检查实例自身的 __dict__
  2. 类命名空间 - 然后在实例的类中查找
  3. 基类命名空间 - 最后按照方法解析顺序(MRO)在基类中查找
class Parent:
parent_attr = "Parent attribute"
class Child(Parent):
class_attr = "Child class attribute"
def __init__(self):
self.instance_attr = "Instance attribute"
obj = Child()
# 查找顺序示例
print(obj.instance_attr) # 1. 实例命名空间 → 找到
print(obj.class_attr) # 1. 实例命名空间 → 未找到 → 2. 类命名空间 → 找到
print(obj.parent_attr) # 1. 实例 → 未找到 → 2. 类 → 未找到 → 3. 基类 → 找到
print(obj.nonexistent) # 所有位置都未找到 → 抛出 AttributeError

当通过类访问属性时,查找顺序更简单:

  • 类命名空间 - 在当前类中查找
  • 基类命名空间 - 按照 MRO 在基类中查找
# 类属性查找
print(Child.class_attr) # 1. 类命名空间 → 找到
print(Child.parent_attr) # 1. 类命名空间 → 未找到 → 2. 基类 → 找到

3、实例化

实例化其实就是调用类对象,从而创建一个实例对象

class Dog:
def __init__(self, name):
self.name = name
buddy = Dog("旺财") # 实例化

四、实例对象

1、相关概念

  • 通过类实例化操作生成对象就是实例对象
  • 一个类可以多次实例化,生成多个实例对象
# 实例对象
class person:
pass
# 实例化:类名()
p1 = person()
p2 = person()
p3 = person()
print(p1, id(p1))
print(p2, id(p2))
print(p3, id(p3))
# 输出结果
<__main__.person object at 0x10e42b8b0> 4534220976
<__main__.person object at 0x10e42b880> 4534220928
<__main__.person object at 0x10e42b850> 4534220880

2、常说的面向对象编程是什么

  1. 设计类
  2. 创建类实例对象
  3. 实例对象调用方法

3、创建实例对象详解

  1. 在内存中为对象分配空间
  2. 调用初始化方法 __init__ 为对象初始化
  3. 对象创建后,内存中就有一个类的实例对象了
类名() → 创建对象
├── __init__() → 初始化方法
│ ├── 定义实例属性
│ └── 设置初始值
├── 实例方法(self) → 对象行为
│ ├── 操作实例属性
│ └── 定义对象功能
└── 对象名.方法名() → 调用方法
├── 对象1
│ ├── 属性1
│ └── 属性2
├── 对象2
│ ├── 属性1
│ └── 属性2
└── 对象n
├── 属性1
└── 属性2

由此可见,一个类可以有很多个对象,每个对象都有属于自己的属性、方法;

  • 创建出来的 对象 叫做 类的 实例对象
  • 创建对象的 行为 叫做 实例化
  • 对象的属性 叫做 实例属性
  • 对象调用的方法 叫做 实例方法

五、__init__ 构造方法

1、相关概念

身份:实例的“初始化器”(initializer)。

作用:在对象已创建但尚未可用时,给对象填充属性、完成额外设置。

__new__ 的关系:

  • __new__ 负责“生壳”→ 返回实例;
  • __init__ 负责“装修”→ 给实例贴标签、装属性。

2、语法格式

class 类名:
def __init__(self, 形参1, 形参2, *, 关键字=默认值):
"""可选文档字符串"""
self.属性1 = 形参1
self.属性2 = 形参2
# 任意逻辑
  • 方法名固定为 __init__
  • 第一参数必须是 self(名字可改但别改)。
  • 不能有返回值,或必须返回 None
  • 支持所有普通函数能用的形参形式:位置、默认、可变、关键字、类型注解。

3、调用流程(用户只写 1 行,Python 做 3 步)

  1. 遇到 obj = 类名(args)

  2. 解释器内部:

    • 先执行 类名.new(类名, *args) → 得到裸实例。
    • 若裸实例是该类实例 → 自动调用 裸实例.init(*args)。
  3. 返回已初始化好的对象。

4、最小可运行示例

class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
p = Point(3, 4) # 自动触发 __init__
print(p.x, p.y) # 3 4

5、常见用法扩展

  • 带验证

    class Celsius:
    def __init__(self, value):
    if value < -273.15:
    raise ValueError("温度低于绝对零度")
    self.value = value
  • 调用父类

    class Animal:
    def __init__(self, name):
    self.name = name
    class Dog(Animal):
    def __init__(self, name, breed):
    super().__init__(name) # 先初始化父类
    self.breed = breed
  • dataclass 场景

    from dataclasses import dataclass
    @dataclass
    class User:
    id: int
    name: str = "guest"
    # 自动生成 __init__,等价于:
    # def __init__(self, id: int, name: str = "guest"): ...

六、三大特性:封装、继承、多态

1、总览

特性关键词一句话Python 典型语法/机制
封装Encapsulation把数据和操作打包,对外只暴露必要接口私有属性 __x、属性装饰器 @property
继承Inheritance子类复用、扩展父类代码class Child(Parent):
多态Polymorphism同一接口,不同对象表现出不同行为鸭子类型 + 重写方法

2、封装 Encapsulation

2.1、概念

  • 隐藏内部细节,对外提供清晰、可控的接口,防止外部直接篡改数据。

2.2、Python 实现手段

  • 命名约定:

    • _var 保护变量(提示别乱动)
    • __var 私有变量(触发名称重整 ClassName__
  • 属性装饰器:将方法伪装成属性,实现读写校验

  • 只读/只写控制

2.3、代码示例

class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.__balance = balance # 私有属性
@property # getter
def balance(self):
return self.__balance
@balance.setter # setter 带校验
def balance(self, value):
if value < 0:
raise ValueError("余额不能为负")
self.__balance = value
acc = BankAccount("Alice", 1000)
print(acc.balance) # 1000 (读)
acc.balance = 1500 # 写
# acc.balance = -100 # ValueError

3、继承 Inheritance

3.1、概念

子类自动获得父类的属性和方法,并可:

  • 扩展新增功能
  • 重写(override)旧功能
  • 调用 super() 复用父类实现

3.2、语法

class Animal: # 父类
def speak(self):
print("Animal speaks")
class Dog(Animal): # 子类
def speak(self):
print("Dog barks")
class Cat(Animal):
def speak(self):
print("Cat meows")

3.3、多重继承 & MRO

class A: pass
class B: pass
class C(A, B): pass
print(C.__mro__) # 查看方法解析顺序

3.4、使用 super() 调用父类

class Employee:
def __init__(self, name):
self.name = name
class Manager(Employee):
def __init__(self, name, level):
super().__init__(name) # 复用父类
self.level = level

4、多态 Polymorphism

4.1、概念

  • “同一接口,多种形态”。调用方只管“会做什么”,不管“具体是谁”。

4.2、Python 鸭子类型

  • Python 是动态语言,不强制继承体系,只要对象实现了所需方法即可。

4.3、代码示例

class Duck:
def quack(self):
print("Quack!")
class Person:
def quack(self): # 同样的方法名
print("Person imitates quack!")
def make_quack(obj): # 统一接口
obj.quack()
make_quack(Duck()) # Quack!
make_quack(Person()) # Person imitates quack!

4.4、基于继承的多态也可

for animal in [Dog(), Cat()]:
animal.speak()
# 输出:
# Dog barks
# Cat meows