在python中,self并不意味着instance?

2024-04-23 07:14:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我只是做了一个foo类来解释我的意思:

class Foo:
    def __init__(self, fakevalue):
        self.fv = fakevalue

    @staticmethod
    def make_a_foo():
        return Foo(2)

    def try_change_foo_value(self):
        self = Foo.make_a_foo()
        print "in change function, self.fv:", self.fv

if(__name__ =='__main__'):
    foo_instance = Foo(1)
    print "foo_instance.fv:", foo_instance.fv
    foo_instance.try_change_foo_value()
    print "foo_instance.fv:", foo_instance.fv

我希望:

foo_instance.fv: 1
in change function, self.fv: 2
foo_instance.fv: 2

但结果是:

foo_instance.fv: 1
in change function, self.fv: 2
foo_instance.fv: 1

我们可以看到self值已经更改,但是instance值没有更改。 为什么?如何解决这个问题?你知道吗


Tags: instanceinselfmakefoovaluedeffunction
3条回答

在本例中,self是指向调用方实例的指针。尽管您在try_change_foo_value中更改指针,但它就像更改函数中的参数一样:在方法之外没有任何效果。你知道吗

为了澄清这一点,你可以考虑

a.try_change_foo_value()作为Foo.try_change_foo_value(a)的简写。很明显,当您更改self时,您正在更改一个局部变量,而调用方a保持不变。你知道吗

为了解决这个问题,你应该

def try_change_foo_value(self):
    self.fv = 2

但正如mgilson所指出的,仅仅说foo_instance.fv = 2更像是Python。你知道吗

如果您想实际更改foo_instance(而不仅仅是fv)的值,您应该在其他地方这样做,而不是在方法中这样做(这在概念上没有什么意义)。你知道吗

您正在更改方法try\u change\u foo\u值中的容器“self”。记住self是作为参数传入的,这意味着您可以更改变量self内部的引用;但是您不能更改调用者传递给您的引用。想想Java。你知道吗

public void changeIt(Foo foo) {
    foo = new Foo(2);
}

如果我打电话

Foo bar = new Foo(1);
.changeIt(bar);

我可以期待酒吧仍然是“新富(1)”

self只是一个变量。对于常规方法(例如,没有用@staticmethod或@classmethod修饰…),传入的对象是实例。但是,在函数中,您可以将self重新绑定到您想要的任何对象,但是这些更改不会保留在函数之外,因为赋值只是对右侧的对象进行一个新引用——除非您返回该引用或将其存储在某个范围更广的对象上,当函数结束时,它将超出范围,再也听不到消息(因为您不再有对它的引用/句柄)。你知道吗

考虑常规函数:

def foo(x):
    x = 2

a = 1
foo(a)
print a #prints 1, not 2

这真的没什么不同。你知道吗

相关问题 更多 >