我知道在python中,可以通过在类定义中定义__call__()方法来调用用户定义的对象.例如

class MyClass:
  def __init__(self):
    pass

  def __call__(self, input1):
    self.my_function(input1)

  def my_function(self, input1):
    print(f"MyClass - print {input1}")

my_obj = MyClass()
# same as calling my_obj.my_function("haha")
my_obj("haha") # prints "MyClass - print haha"

我在看pytorch如何使nn.Module对象的forward()方法在被调用时被隐式调用,看到了一些我不理解的语法.

the line中,假设定义了__call__方法,使用的语法是,

__call__ : Callable[..., Any] = _call_impl

这似乎是一个注释(python忽略:之后的关键字Callable[)和一个_call_impl值的组合,我们希望在调用__call__时调用它,我猜这是,

def __call__(self, *args, **kwargs):
    return self._call_impl(*args, **kwargs)

但我想清楚地了解这种定义函数的方法是如何工作的.

我的问题是:我们什么时候想要使用类的可调用属性的这种定义,而不是通常的def myfunc(self, *args, **kwargs)

推荐答案

函数是python中常见的一级对象.定义函数对象时使用的名称(例如,使用def语句)并不是一成不变的,就像intlist一样.正如你所能做的

a = [1, 2, 3]
b = a

要通过名称b访问a的元素,可以对函数执行相同的操作.在第一个示例中,可以替换

def __call__(self, input1):
    self.my_function(input1)

用更简单的

__call__ = my_function

你需要把这一行放在my_function的定义之后.

这两种实现之间的关键区别在于def __call__(...创建了一个新函数.__call__ = ...简单地将名称__call__绑定到与my_function相同的对象.值得注意的区别是,如果执行__call__.__name__,第一个版本将显示__call__,而第二个版本将显示my_function,因为这是def语句分配的内容.

Python相关问答推荐

如何终止带有队列的Python进程?+ 队列大小的错误?

Python -根据另一个数据框中的列编辑和替换数据框中的列值

Odoo -无法比较使用@api.depends设置计算字段的日期

如何从FDaGrid实例中删除某些函数?

如何根据日期和时间将状态更新为已过期或活动?

三个给定的坐标可以是矩形的点吗

max_of_three使用First_select、second_select、

Pandas 滚动最接近的价值

使可滚动框架在tkinter环境中看起来自然

根据二元组列表在pandas中创建新列

如何使用根据其他值相似的列从列表中获取的中间值填充空NaN数据

Odoo 16使用NTFS使字段只读

如何在UserSerializer中添加显式字段?

无法连接到Keycloat服务器

合并帧,但不按合并键排序

Matplotlib中的字体权重

Python 3试图访问在线程调用中实例化的类的对象

mdates定位器在图表中显示不存在的时间间隔

如何训练每一个pandaprame行的线性回归并生成斜率

如何在Python中自动创建数字文件夹和正在进行的文件夹?