问题: 类(class)和对象(object)的区别是什么,举例说明?

👇 点击展开/折叠 面试背诵模板(建议先背这个) 类是抽象模板,用于定义具有相同属性和行为的一类事物的结构,在内存中仅存储一份(方法区)。对象是根据类模板创建的具体实体,在堆内存中独立分配空间,拥有独立的实例属性值。类属性(如物种)被所有实例共享,修改类属性会影响所有对象;实例属性(如姓名)各自独立,修改一个对象不影响其他对象。类是图纸,对象是根据图纸造出的实物。
---

内存分配与存储位置差异

类本身也是对象(元类的实例),但主要存储静态信息(类属性、方法定义)和方法表。对象的实例属性存储在各自独立的堆内存空间,通过指针(__dict__)维护。实例方法虽由对象调用,但实际存储在类中,调用时自动传入 self 绑定到当前实例。

代码示例与属性查找机制

1
2
3
4
5
6
7
8
9
10
11
12
13
class Dog:
species = "犬科" # 类属性(所有实例共享)

def __init__(self, name, age):
self.name = name # 实例属性(独立)
self.age = age

d1 = Dog("旺财", 3)
d2 = Dog("小黑", 2)

print(d1.species) # 犬科(访问类属性)
print(d1.name) # 旺财(实例独立)
print(d2.name) # 小黑

高频追问(面试必考)

Q1:修改对象属性会影响类属性吗?
不会。d1.species = "新物种" 是在实例上新建同名属性,访问时优先查找实例 __dict__,从而遮蔽(屏蔽)类属性。类属性本身并未改变,Dog.species 仍为 "犬科"。

Q2:修改可变类属性(如列表)会发生什么?
若类属性是可变对象(如列表),通过对象调用 d1.tricks.append('sit') 会直接修改共享列表,影响所有实例;若通过赋值 d1.tricks = [] 则是新建实例属性,不影响类属性。

1
2
3
4
5
6
class Dog:
tricks = [] # 共享列表

d1 = Dog(); d2 = Dog()
d1.tricks.append('roll') # 修改共享列表
print(d2.tricks) # ['roll'](影响所有实例)

Q3:d1.__dict__ 和 Dog.__dict__ 的区别?
d1.__dict__ 存储实例属性(如 {'name': '旺财'});Dog.__dict__ 存储类属性、方法等。查找属性时按实例 __dict__ → 类 __dict__ → 父类 __dict__ 顺序。