Есть несколько причин, хотя главная из них от Zen of Python: «Явное лучше, чем неявное». В языке, подобном C ++, метод класса всегда имеет неявный аргумент this
, который помещается в стек каждый раз, когда вызывается метод. В этом случае, когда существует переменная экземпляра b
, а также глобальная переменная b
, пользователь может просто ссылаться на b
, ссылаясь на одну, не осознавая, что будет использоваться другая. Таким образом, Python заставляет вас четко указывать область действия, чтобы избежать путаницы.
С учетом вышесказанного есть и другие причины. Например, я могу определить функцию вне класса, а затем присоединить ее к классу во время выполнения. Например:
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
Здесь тот факт, что self
явный, делает для нас тривиальным определение функции вне класса и затем присоединение ее к этому классу. Я не делаю такие вещи невероятно часто, но это чрезвычайно полезно, когда я делаю.
Вот еще более сложный пример; Предположим, мы хотим определить класс внутри другого класса, например, для целей модульного тестирования:
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)
Здесь наличие явного «я» (которое мы можем называть как угодно, оно не обязательно должно быть «я») позволяет различать self
внутреннего и внешнего классов. Опять же, это не то, что я делаю часто, но когда я делаю это, это невероятно полезно.