为什么Python对象中的`self`是不可变的?

28 投票
6 回答
6841 浏览
提问于 2025-04-15 12:21

为什么我不能执行像下面这样的操作:

class Test(object):
    def __init__(self):
        self = 5

t = Test()
print t

我本以为它会打印出 5,因为我们在用这个值覆盖实例,但实际上它什么都没做。甚至没有抛出错误,完全忽略了这个赋值。

我明白这种情况几乎不会发生,但还是觉得不能这样做有点奇怪。

更新:我现在明白了 为什么 它不工作,但我还是想知道有没有办法在实例内部替换一个实例。

6 个回答

3

我刚做了个简单的测试,你可以给 self 赋值。在你的 __init__() 方法里,打印出 self 的值。你会看到它是 5。

你这里缺少的一个点是,在 Python 中,参数是按值传递的。所以,在一个函数或方法里改变一个变量的值,并不会影响外面的值。

不过,我还是强烈建议你不要去改变 self 的值。

10

它并不是“忽略”这个赋值。这个赋值是正常工作的,你创建了一个本地的名字,它指向了数据5。

如果你真的想要做到你正在做的事情……

class Test(object):
    def __new__(*args):
        return 5
64

任何简单的赋值操作在Python中对任何函数的任何参数都表现得完全一样:它只是把这个名字绑定到一个不同的值上,除此之外什么也不做。正如Python的哲学所说:“没有哪个特殊情况足够特殊到可以打破规则!”

所以,简单地说,给特定函数的特定参数赋值没有任何外部可见的效果,这并不奇怪。如果这个特定情况以其他方式工作,那才真是令人惊讶,仅仅因为函数和参数的名字。

如果你想创建一个类,这个类构造的对象类型与它自己不同,这种行为当然是可能的——但你需要重写特殊方法__new__,而不是 __init__

class Test(object):
    def __new__(cls):
        return 5

t = Test()
print t

这确实会输出5。在Python中,__new____init__的行为是一个“二步构造”设计模式的例子:真正的“构造器”是__new__(它构建并返回一个(通常是未初始化的)对象(通常是所涉及类型/类的新实例);__init__是“初始化器”,它负责正确初始化这个新对象。

这允许构造一旦创建就不可变的对象:在这种情况下,所有操作必须在__new__中完成,因为一旦对象被构造出来是不可变的,__init__就不能再改变它来进行初始化。

撰写回答