鱼C论坛

 找回密码
 立即注册
查看: 33|回复: 2

关于类和对象课后习题的困惑

[复制链接]
发表于 昨天 16:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我在学习类和对象的课程,其中课后作业分别有两道题如下:

1.
>>> class C:
...     x = []
...     def add_x(self, x):
...         self.x.append(x)
...
>>> c = C()
>>> d = C()
>>> c.add_x(250)
>>> d.add_x(520)
>>> c.x

[250, 520]

2、
>>> class C:
...     def __init__(self):
...         self.x = []
...     def add_x(self, x):
...         self.x.append(x)
...
>>> c = C()
>>> d = C()
>>> c.add_x(250)
>>> d.add_x(520)
>>> c.x
[250]

我的困惑是第一题中当x为空列表时,c.x的值为何包含250和520两个值,而第二题通过构造函数创建self.x为空列表时,c.x的值为何只包含250一个值?

为何都是空列表,结果却不同?

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 16:15 | 显示全部楼层
你好!这是一个非常棒的观察,这正好触及了 Python 中 类属性(class attribute)实例属性(instance attribute) 的核心区别。

让我们来逐题分析:

第一题:x 是类属性(共享的)

  1. class C:
  2.     x = []  # 这是一个类属性,属于类C本身。所有实例共享这一个列表!
  3.     def add_x(self, x):
  4.         self.x.append(x)  # 这里操作的是共享的类属性列表
复制代码


过程解析:
1.  `x = []` 定义在类内部,但在所有方法之外。它是一个 类属性,只会在类 C 被定义时创建 一次
2.  当你创建 c = C()d = C() 时,它们两个实例并没有自己独立的 x 属性。
3.  执行 c.add_x(250) 时,Python 会先在实例 c 中找 x,没找到,于是向上找到类的 x(那个空列表),并向其中添加了 250。
4.  执行 d.add_x(520) 时,同样的过程发生。实例 d 也没有自己的 x,于是它操作的也是同一个 类属性 x 列表。所以这个列表现在包含了 [250, 520]。
5.  最后访问 c.x,实例 c 还是没有自己的 x,所以它返回的是类属性 x,也就是被两个实例修改过的那个共享列表。

第二题:x 是实例属性(独立的)

  1. class C:
  2.     def __init__(self):
  3.         self.x = []  # 这是一个实例属性。每个实例在创建时都会得到一个全新的、属于自己的空列表。
  4.     def add_x(self, x):
  5.         self.x.append(x)  # 这里操作的是每个实例自己的列表
复制代码


过程解析:
1.  `self.x = []` 定义在 __init__ 方法里。这是一个 实例属性
2.  每次你创建实例,比如 c = C()__init__ 方法都会执行,为这个 特定的实例 c 创建一个全新的、只属于它的空列表,并赋值给 c.x
3.  同样地,d = C() 也会为实例 d 创建一个全新的、只属于它的空列表,赋值给 d.x。这两个列表互不相干。
4.  执行 c.add_x(250),它操作的是 c 自己的列表,变成 [250]。
5.  执行 d.add_x(520),它操作的是 d 自己的列表,变成 [520]。这个操作完全不影响 c 的列表。
6.  最后访问 c.x,返回的就是实例 c 自己的那个列表,所以只有 [250]。

总结一下关键区别:
  • 第一题 (类属性): 像一个[教室里的公共储物柜]。所有同学(实例)都在往里放东西,大家看到和操作的是同一个柜子里的内容。
  • 第二题 (实例属性): 像每个同学[自己的书包]。每个同学都有一个,里面放自己的东西,互不干扰。


所以,虽然看起来“都是空列表”,但它们的归属和创建时机完全不同,导致了最终结果的差异。理解这一点对掌握面向对象编程至关重要!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 16:27 | 显示全部楼层
第一个的 x 是 C 的,c 和 d 使用一个列表

第二个的 x 在 init 里,所以每次创建一个实例就会有一个列表,c 和 d 有自己的列表

求最佳
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-3-23 03:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表