为什么Python对象中的`self`是不可变的?
为什么我不能执行像下面这样的操作:
class Test(object):
def __init__(self):
self = 5
t = Test()
print t
我本以为它会打印出 5
,因为我们在用这个值覆盖实例,但实际上它什么都没做。甚至没有抛出错误,完全忽略了这个赋值。
我明白这种情况几乎不会发生,但还是觉得不能这样做有点奇怪。
更新:我现在明白了 为什么 它不工作,但我还是想知道有没有办法在实例内部替换一个实例。
6 个回答
我刚做了个简单的测试,你可以给 self
赋值。在你的 __init__()
方法里,打印出 self
的值。你会看到它是 5。
你这里缺少的一个点是,在 Python 中,参数是按值传递的。所以,在一个函数或方法里改变一个变量的值,并不会影响外面的值。
不过,我还是强烈建议你不要去改变 self
的值。
它并不是“忽略”这个赋值。这个赋值是正常工作的,你创建了一个本地的名字,它指向了数据5。
如果你真的想要做到你正在做的事情……
class Test(object):
def __new__(*args):
return 5
任何简单的赋值操作在Python中对任何函数的任何参数都表现得完全一样:它只是把这个名字绑定到一个不同的值上,除此之外什么也不做。正如Python的哲学所说:“没有哪个特殊情况足够特殊到可以打破规则!”
所以,简单地说,给特定函数的特定参数赋值没有任何外部可见的效果,这并不奇怪。如果这个特定情况以其他方式工作,那才真是令人惊讶,仅仅因为函数和参数的名字。
如果你想创建一个类,这个类构造的对象类型与它自己不同,这种行为当然是可能的——但你需要重写特殊方法__new__
,而不是 __init__
:
class Test(object):
def __new__(cls):
return 5
t = Test()
print t
这确实会输出5
。在Python中,__new__
和__init__
的行为是一个“二步构造”设计模式的例子:真正的“构造器”是__new__
(它构建并返回一个(通常是未初始化的)对象(通常是所涉及类型/类的新实例);__init__
是“初始化器”,它负责正确初始化这个新对象。
这允许构造一旦创建就不可变的对象:在这种情况下,所有操作必须在__new__
中完成,因为一旦对象被构造出来是不可变的,__init__
就不能再改变它来进行初始化。