将参数传递给类的实例以隐含地调用方法

时间:2017-10-28 07:12:32

标签: python class apply

我最近在python库(PyTorch)中看到过类似的内容:

class A(BaseClass):
      def __init__(self,b,c):
           self.b =b 
           self.c = c
      def forward(self,d,e):
         return self.b + self.c + d + e

a_instance = A(1,2)
assert a_instance(d=4,e=5) == a_instance.forward(4,5) 

除了在A类中直接调用方法“forward”之外,您可以将参数传递给类的实例,然后将它们传递给“forward”函数并调用它。

我非常想知道如何实现这样的东西。  任何有关这方面的解释都非常感激。

PS:这是我的例子不是真实的。

2 个答案:

答案 0 :(得分:3)

您可以使用__call__方法。

class A():
    def __init__(self,b,c):
        self.b =b 
        self.c = c
    def forward(self,d,e):
        return self.b + self.c + d + e

    def __call__(self,d,e):
        return self.forward(d,e)
a_instance = A(1,2)
assert a_instance(d=4,e=5) == a_instance.forward(4,5) 

答案 1 :(得分:1)

这取决于BaseClass的定义方式。例如,在常规情况下,您将拥有如下内容:

>>> class B(object):
    def __init__(self):
        pass
>>> B("sa")

Traceback (most recent call last):
  File "<pyshell#85>", line 1, in <module>
    B("sa")
TypeError: __init__() takes exactly 1 argument (2 given)

如果有人将BaseClass定义为元类,但您会遇到与此类似的情况: ```

>>> class CallableClass(type):
    def __new__(self, a):
        print "Look at me, making life harder for everyone: "+str(a)


>>> class B(CallableClass):
    def __init__(self):
        pass


>>> B("Do I really need to?")
Look at me, making life harder for everyone: Do I really need to?

```

为了得到你想要的东西,你会做类似

的事情
>>> class CallableClass(type):
    def __new__(self, a):
        print "Look at me, making life harder for everyone: "+str(a)
        self.a = a
        return self


>>> class B(CallableClass):
    def __init__(self):
        pass


>>> a = B("Do I really need to?")
Look at me, making life harder for everyone: Do I really need to?
>>> a.a
'Do I really need to?'

但正如我的例子所示:为什么? 9/10次你真的不需要metaclasses,你真的,really,不希望它们与你的工作混淆 - 很难调试,写起来很难,很难想。也许这是一个xyz问题?

编辑:

>>> class IsCallable(object):
    def __init__(self):
        print("this is init")
    def __call__(self):
        print("this is call")

>>> class C(IsCallable):
    def __init__(self):
        IsCallable.__init__(self)
        pass
>>> C()
this is init
<__main__.C object at 0x7f32b98ebdd0>
>>> C()()
this is init
this is call