使用 class 对象作为方法来模拟 Python 中的可调用对象

Use class object as method to emulate a callable object in Python

如何在 Python3 中定义一个 class MyClass 以便像这样实例化它 obj = MyClass(param1, param2) 然后用它来计算像 res = obj(in1, in2, in3) ?

这样的操作

例如,使用 PyTorch,您可以将模型声明为 mod = MyResNet50(),然后将其预测计算为 pred = mod(input)

下面是我试过的代码。我声明一个方法并将其称为 obj.method().

import numpy as np


class MLP:

    def __init__(self, hidden_units: int, input_size: int):
        self.hidden_units = hidden_units
        self.input_size = input_size
        self.layer1 = np.random.normal(0, 0.01, size=(hidden_units, input_size))
        self.layer2 = np.random.normal(0, 0.01, size=(1, hidden_units))

    def sigmoid(self, z):
        return 1/(1 + np.exp(-z))

    def predict(self, input):
        pred = self.layer1.dot(input)
        pred = self.layer2.dot(pred)
        return self.sigmoid(pred)

my_MLP = MLP(5, 10)
pred = my_MLP.predict(np.random.normal(0, 0.01, 10))

实施 __call__ 以对使用 () 调用的 class 实例作出反应:

class MyClass:
    def __init__(self, p1, p2):
        # here you would initiate with p1, p2
        pass 
        
    def __call__(self, in1, in2, in3):
        return f'You rang? {in1} {in2} {in3}'

示例:

>>> obj=MyClass(1,2)    
>>> res=obj(1,2,3)
>>> res
You rang? 1 2 3

如果您的 class 实例没有 __call__ 定义(无论是它本身还是它的后代),它会让您知道:

class MyClass:
    def __init__(self, p1, p2):
        # here you would initiate with p1, p2
        pass 
    # no other methods and descendant of Object...

>>> MyClass(1,2)()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'MyClass' object is not callable

回调使用__call__,mod使用__mod__函数。

class MyClass:
    def __init__(self, param1, param2):
        self.param1, self.param2 = param1, param2
        print(self.param1, self.param2)

    def __call__(self, in1, in2, in3):
        self.result = '%s, %s, %s' % (in1, in2, in3)
        print(in1, in2, in3)
        return self

    def __mod__(self, other):
        return other


obj = MyClass('param1', 'param2')
res = obj('in1', 'in2', 'in3')
print(res % 5)