why is "self" used in OO-Python?

Duncan Booth duncan.booth at invalid.invalid
Sat Jul 12 20:01:31 CEST 2008


ssecorp <circularfunc at gmail.com> wrote:

> 1. Why do I have to pass self into every method in a class? Since I am
> always doing why cant this be automated or abstracted away?
> Are the instances where I won't pass self?
> I imagine there is some tradeoff involved otherwise it would have been
> done away with.

When you define a method in Java there is an implicit 'this' passed to the 
method. Python cannot tell when you define a function whether the function 
is going to be used as a function, an instance method, a class method, a 
static method or something else (or all of the above). Consider this:

>>> class C: pass

>>> def showme(*args, **kw):
	print args, kw

	
>>> C.method = showme
>>> C.staticmethod = staticmethod(showme)
>>> C.classmethod = classmethod(showme)
>>> showme(1,2,3)
(1, 2, 3) {}
>>> C().method(1,2,3)
(<__main__.C instance at 0x00C4B580>, 1, 2, 3) {}
>>> C().staticmethod(1,2,3)
(1, 2, 3) {}
>>> C().classmethod(1,2,3)
(<class __main__.C at 0x01162C60>, 1, 2, 3) {}
>>> 

The dynamic nature of Python means you can lift a method out of a class and 
re-use it in a different context or inject a function into a class as a 
method. There are two ways to handle this sort of code: javascript has an 
implied 'this' for everything whether a function or what passes for a 
method, Python makes it explicit.

> 2. self.item instead of getters and setters. I thought one of the main
> purposes of OO was encapsulation. Doesn't messing with internal object-
> representations break this?

That is correct. Some languages (e.g. Java) don't allow you to encapsulate 
attributes so you have to write getter and setter methods. If you expose an 
attribute in Java then you cannot later insert some code into the lookup or 
override the set without getting all users of your code to change the way 
they access the value. This is bad.

Other languages (e.g. Python, C#) allow you to intercept the attribute 
lookup so you can change a plain attribute into a property without 
requiring the users of your class alter their source code. With C# I 
think they would still need to recompile their code so it may be more 
appropriate to avoid using public attributes if you are producing a class 
library for widespread reuse, but with Python there is no difference to the 
user of your class whether they are accessing an attribute or a property.

Sadly a lot of Java programmers mistake the limitations of their language 
for rules of OO programming, and worse this has spread from Java into other 
languages where these restrictions no longer need apply.

Your Stack class is a bad example: the stack attribute is purely internal 
so you wouldn't want to expose it as part of the public interface. Consider 
instead something like:

class AddressBookEntry(object):
    def __init__(self, name, phone):
        self.name = name
        self.phone = phone

    @property
    def phone(self):
        return self._phone

    @property.setter
    def phone(self, number)
        validatephonenumber(number) # may throw an exception
    	  self._phone = number

If later you want to add some processing to the name attribute it is easy, 
but putting in dummy property getter/setter methods before you need them 
would be pointless.



More information about the Python-list mailing list