monkey-patched-python类中的自引用

2024-04-19 14:22:07 发布

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

我试图用一种修补的方法来理解self引用。代码如下:

class foo():
    def __init__(self):
        self.child = lambda: none
        self.child.string = "child's string value"
        self.string = "string value 1"
        print "initialized"
    def func1(self):
        print self.string

if __name__=="__main__":
    foo0=foo()
    foo0.newMethod = lambda: "test"
    print foo0.newMethod()

    foo0.func1()    
    foo0.child.secondMethod = foo0.func1
    foo0.child.secondMethod()

为什么孩子的方法把自己的引向foo0?这和javascript有什么不同吗?你知道吗


Tags: 方法lambda代码selfchildstringfoovalue
1条回答
网友
1楼 · 发布于 2024-04-19 14:22:07

这个问题的答案在于Python对未绑定方法和绑定方法的区分。当你定义一个方法时,它是未绑定的:它可以对类的任何实例进行操作,事实上,它只不过是一个函数,它的第一个参数名为self(即使这样,它也是一个约定)和一点检查,这样你就不会对它们做真正可怕的事情。你知道吗

class Foo(object):
    def my_method(self, arg):
        print "self:", self
        print "arg:", arg

a = Foo()
print Foo.my_method(a, 2)
# self: self: <__main__.Foo object at 0x000000000219DE10>
# arg: 2

# You could, in theory, do that, but Python complains because it values the sanity
# of the people who will have to maintain your code :p
print Foo.my_method(1, 2)
# TypeError: unbound method my_method() must be called with Foo instance as first argument (got int instance instead)

到目前为止,没有什么特别的。然而,当我们调用一个方法时,Python有一点魔力,它不是在类本身上(如上所述),而是在该类的一个实例上(即在一个对象上)。你知道吗

a.my_method(2)
# self: <__main__.Foo object at 0x000000000219DE10>
# arg: 2

请注意,尽管方法是用两个参数定义的,但突然之间您只需要向该方法提供arg?这是因为a.my_method是一个绑定方法:它是a对象my_method方法,而不是Foo的方法。它绑定到那个特定的实例,并且在其中有一个对那个特定对象的引用(如果您查看dir(a.my_method),您会注意到它有一个im_self属性)。你知道吗

但是,在您的示例中,如果要在func1中添加print self语句,它将打印foo0,而不是foo0.child。这是因为“绑定”不是在调用方法(foo0.child.secondMethod())时发生的,而是在引用它(foo0.func1)时发生的。你知道吗

更重要的是,只有在引用在类上定义的方法时才会发生这种情况。你知道吗

因此,在您的示例中,foo0.child.secondMethod = foo0.func1引用了foo0func1方法(它为您提供了一个foo0的绑定方法),但是赋值本身没有执行任何魔法。它只是设置一个foo0.child属性。你知道吗

这有道理吗?你知道吗

相关问题 更多 >