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 familiarisd2.bark("汪汪") # Lucky: 汪汪三、类对象
1、相关概念
- 类对象(class object):由
class语句执行后,Python 在内存中创建的对象,类型是type(元类)。 - 实例对象(instance object):由“类对象”调用得到的具体个体,类型就是该“类对象”。
2、属性引用
2.1、属性引用语法
- Python 中使用点号 . 运算符进行属性引用:
# 基本语法obj.attribute # 访问对象的属性Class.attribute # 访问类的属性2.2、属性查找顺序
当通过实例访问属性时,Python 按照以下顺序查找:
- 实例命名空间 - 首先检查实例自身的
__dict__ - 类命名空间 - 然后在实例的类中查找
- 基类命名空间 - 最后按照方法解析顺序(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> 45342208802、常说的面向对象编程是什么
- 设计类
- 创建类实例对象
- 实例对象调用方法
3、创建实例对象详解
- 在内存中为对象分配空间
- 调用初始化方法
__init__为对象初始化 - 对象创建后,内存中就有一个类的实例对象了
类名() → 创建对象│├── __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 步)
-
遇到 obj = 类名(args)
-
解释器内部:
- 先执行 类名.new(类名, *args) → 得到裸实例。
- 若裸实例是该类实例 → 自动调用 裸实例.init(*args)。
-
返回已初始化好的对象。
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 45、常见用法扩展
-
带验证
class Celsius:def __init__(self, value):if value < -273.15:raise ValueError("温度低于绝对零度")self.value = value -
调用父类
class Animal:def __init__(self, name):self.name = nameclass Dog(Animal):def __init__(self, name, breed):super().__init__(name) # 先初始化父类self.breed = breed -
dataclass 场景
from dataclasses import dataclass@dataclassclass User:id: intname: 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 = valueacc = BankAccount("Alice", 1000)print(acc.balance) # 1000 (读)acc.balance = 1500 # 写# acc.balance = -100 # ValueError3、继承 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: passclass B: passclass C(A, B): passprint(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 = level4、多态 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