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

时间:2009-06-18 22:51:22

标签: python object

为什么我不能执行以下操作:

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

t = Test()
print t

我希望它打印5,因为我们用它覆盖了实例,但它完全没有做任何事情。甚至不会抛出错误。只是忽略了作业。

据我所知,几乎没有人愿意这样做,但你不能这样做似乎很奇怪。

更新:我现在明白了为什么它不起作用,但我仍然想知道是否有任何方法可以在实例中替换实例

6 个答案:

答案 0 :(得分:61)

任何函数的任何参数的任何简单赋值在Python中的行为方式完全相同:将该名称绑定到不同的值,并且什么都不做。 “没有特殊情况足以破坏规则”,正如Python的禅宗所说的那样! - )

所以,远非它奇怪(简单地说=分配给特定函数中的特定参数没有任何外部可见效果),如果这个特定情况适用于任何情况,它将完全令人惊讶另一方面,仅仅是因为有问题的函数和参数的名称。

如果你想创建一个构造一个不同于自身类型的对象的类,这种行为当然是很有可能的 - 但它是通过重写特殊方法__new__而不是<来获得的。 / strong> __init__

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

t = Test()
print t

发出5。 Python中的__new__ / __init__行为是“两步构造”设计模式的一个示例:“构造函数”本身是__new__(它构建并返回一个(通常未初始化) object(通常是有问题的类型/类中的新对象); __init__是正确初始化新对象的“初始化器”。

例如,这允许构造一旦构造为不可变的对象:在这种情况下,在构造不可变对象之前,一切都必须在__new__中完成,因为,假定对象是不可变的,{ {1}}无法改变它以便初始化它。

答案 1 :(得分:10)

它不会“忽略”作业。赋值工作正常,您创建了一个指向数据的本地名称。

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

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

答案 2 :(得分:3)

我刚刚进行了快速测试,你可以分配给自己。在 init ()方法中,打印出self的值。你会看到它是5。

这里缺少的是参数在Python中按值传递。因此,在函数或方法中更改变量的值不会改变外部世界。

所有这一切,我强烈建议不要改变自己。

答案 3 :(得分:1)

博士。 Egon Spengler:这很糟糕。
Peter Venkman博士:我对整个好/坏事情都很模糊。你是什​​么意思,“坏”? Egon Spengler博士:试着想象你所知道的所有生命瞬间停止,你体内的每一个分子都以光速爆炸。

答案 4 :(得分:1)

有时你想要这样做,但不是像int这样的不可变类型:

>>> class Test(list):
    ... def __init__(self):
    ...    list.__init__(self, [1,2,3])   # self = [1,2,3] seems right, but isn't

>> t = Test()
>> print t
[1, 2, 3]

答案 5 :(得分:-3)

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

t = Test()
print t

就像拥有这个PHP(只知道其他语言,对不起)

class Test {
    function __construct() {
            $this = 5;
        }
}

我看不出它有多大意义。用值替换实例?