在Python中使用self时,为什么要将类传递给在类函数内调用的函数?

2024-07-02 11:08:06 发布

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

所以,我有这个代码片段。你知道吗

class LogObserver(object): 
    def write_log(...):
        self.logger.log(self, level, message, *args, **kwargs)
...

查看调试器和错误消息,我注意到变量level包含LogObserver,而不是整数。我在等一个整数。你知道吗

但是,当我从self.logger.log()中移除self时,就像:

self.logger.log(level, message, *args, **kwargs)

level包含整数而不是LogObserver对象。错误信息也会消失。你知道吗

这种行为背后的解释是什么?你知道吗


Tags: 代码selflogmessageobjectdefargs整数
1条回答
网友
1楼 · 发布于 2024-07-02 11:08:06

如果调用实例方法(notstaticmethod或classmethod),实例将作为第一个参数隐式传递。这就是为什么方法定义将self作为第一个参数;顺便说一下,名称self只是一个约定。例如,foo.bar()将被翻译成type(foo).bar(foo)。你知道吗

如果显式地将实例作为参数传递,那么它将像任何其他参数一样传递—在已经隐式传递实例之后。例如,foo.bar(foo)将被翻译成type(foo).bar(foo, foo)。你知道吗

现在,在一个方法中,self通常是第一个参数。假设你已经定义了

class Foo(object):
  def bar(self, other=None):
    pass
foo = Foo()

调用foo.bar()被转换为type(foo).bar(self=foo, other=None)。 同样地,foo.bar(foo)被翻译成type(foo).bar(self=foo, other=foo)。你知道吗

所以,当你调用self.logger.log(self, level, message, *args, **kwargs)时,它实际上转化为type(self).logger.log(self=self, level=self, message=level, args=(message,), kwargs={})。因此,level获取对象的实例,即self。你知道吗


请注意,foo.bar()并不总是解析为type(foo).bar(foo)——只有在类/类型上定义了bar时才会出现这种情况。然而,self的传递并没有因此而改变。你知道吗

相关问题 更多 >