从其可调用属性中引用所有者类

时间:2012-05-02 20:26:45

标签: python descriptor callable

我想将一个可调用的类作为一个函数分配给另一个类,然后从拥有的函数中引用所有者类:

class DoIt(object):

    def __call__(self):
        print "%s did it" % self.name

class Doer(object):

    def __init__(self, name):
        self.name = name

    doSomething = DoIt()


doer = Doer("Bob")
doer.doSomething()

在上面的代码中,我希望doSomething()函数打印“Bob做到了”,但是使用此代码我将得到一个

  

AttributeError:'DoIt'对象没有属性'name'

因为self引用了DoIt实例,而不是Doer实例。是否可以引用Doer实例?

3 个答案:

答案 0 :(得分:4)

class DoIt(object):

    def __get__(self, instance, owner):
        def done():
            print "%s did it" % instance.name
        return done

class Doer(object):

    def __init__(self, name):
        self.name = name

    doSomething = DoIt()


doer = Doer("Bob")
doer.doSomething()

说明: (这是请求者尽可能地解释这个答案)

Python为您提供了描述符类,它们是充当属性的类(与属性作为实例变量或属性相反)。描述符类的__get__方法指示在分配该类并将其作为另一个类的属性进行访问时返回的内容。 __get__允许您访问拥有实例和拥有类(请参阅方法签名)。

通过让__get__返回一个函数,您实际上创建了一个可以访问其所有者的可调用对象。

有关描述符的更多信息,请参阅Attributes, Properties and Descriptors- Building Skills in Python

答案 1 :(得分:2)

以下是实现此目的的一种方法:

class DoIt(object):
    def __init__(self, obj):
        self.obj = obj

    def __call__(self):
        print "%s did it" % self.obj.name

class Doer(object):
    def __init__(self, name):
        self.name = name
        self.doSomething = DoIt(self)

doer = Doer("Bob")
doer.doSomething()    # prints 'Bob did it'

答案 2 :(得分:0)

这只是Ignacio回答的另一个例子 - 当“可调用”需要参数时,我希望显示相同的概念。

class DoIt(object):

    def __get__(self, instance, owner):

        def done(what):
            print "%s did something %s" % (instance.name, what)
        return done

class Doer(object):

    def __init__(self, name):
        self.name = name
    doSomething = DoIt()

doer = Doer("Bob")
doer.doSomething("cool")

打印:

  鲍勃做了一件很酷的事情