Sean Francis N. Ballais
Sean Francis N. Ballais

Reputation: 2488

Why is the class passed to a function being called inside a class function when using self in Python?

So, I have this code snippet.

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

Looking into the debugger and the error messages as well, I noticed that the variable level contains LogObserver instead of an integer. I was expecting an integer.

However, when I remove self from self.logger.log() like:

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

level contains an integer instead of a LogObserver object. The error messages disappear as well.

What is the explanation behind this behavior?

Upvotes: 0

Views: 60

Answers (1)

MisterMiyagi
MisterMiyagi

Reputation: 52139

If you call an instance method (not staticmethod or classmethod), the instance is implicitly passed as the first parameter. That is why method definitions take self as the first parameter; the name self is just a convention, by the way. For example, foo.bar() will be translated to type(foo).bar(foo).

If you explicitly pass on the instance as an argument, it will be passed along like any other argument - after the instance is passed in implicitly already. For example, foo.bar(foo) will be translated to type(foo).bar(foo, foo).

Now, inside a method, self is usually the first parameter. Let's say you have defined

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

Calling foo.bar() is translated to type(foo).bar(self=foo, other=None). Likewise, foo.bar(foo) is translated to type(foo).bar(self=foo, other=foo).

So, when you call self.logger.log(self, level, message, *args, **kwargs), that actually translates to type(self).logger.log(self=self, level=self, message=level, args=(message,), kwargs={}). Thus, level gets an instance of your object, namely self.


Note that foo.bar() is not always resolved as type(foo).bar(foo) - this is only the case if bar is only defined on the class/type. The passing of self is not changed by this, however.

Upvotes: 3

Related Questions