There are several reasons, though the main one is from the Zen of Python: "Explicit is better than implicit." In a language like C++, a method on the class always has an implicit argument this
which is pushed onto the stack every time the method is called. In this case, when an instance variable b
exists as well as a global variable b
, then the user may just refer to b
referring to one without realizing that the other will be used. So Python forces you to be explicit about your scope to avoid confusion.
With that being said, there are other reasons as well. For example, I may define a function outside of a class and then attach it to a class at runtime. For example:
def log(self):
print "some library function requires all objects to have a log method"
print "unfortunately we're using the Student class, which doesn't have one"
print "this class is defined in a separate library, so we can't add the method"
print "fortunately, we can just add the method dynamically at runtime"
Student.log = log
Here the fact that self
is explicit makes it trivial for us to define a function outside of a class and then attach it to that class. I don't do this sort of thing incredibly often, but it's EXTREMELY useful when I do.
Here's an even more complex example; suppose we want to define a class inside another class, such as for the purposes of unit testing:
class SomeUnitTests(TestCase):
def test_something(self):
class SomeMockObject(SomeActualObject):
def foo(self2):
self.assertEqual(self2.x, SOME_CONSTANT)
some_lib.do_something_with(SomeMockObject)
Here the presence of an explicit self (which we can call whatever we want, it doesn't have to be self) allows to to distinguish between the self
of the inner and outer classes. Again, this isn't something I do frequently, but when I do then it's incredibly useful.