why is "self" used in OO-Python?

S

ssecorp

I first learned about OO from Java.

I much prefer to program in Python though.

However I am consufed about 2 things.

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.

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?
I see how the getters and setters could be just visual clutter and you
have to add them to every class so it is annoying a bit in the same
way as self described above.
However I feel like I want getters and setters when I write classes,
not sure of the advantages/disadvantages though.
Only looking at the documentation of a Python-class, will internal
representations be provided?

If I have a class:

class Stack(object):
def __init__(self, *items):
self.stack = list(items)

def append(self, item):
self.stack.append(item)

def pop(self):
return self.stack.pop()

I can get to see the stack with var.stack but then why even implement
append when I could do self.stack.append(x) etc.
That way you could do away with OO completely. So why let people
access the main attribute but not let them manipulate it?
Makes more sense to draw the line to not access any attributes at all
no?
 
C

Carl Banks

I first learned about OO from Java.

I much prefer to program in Python though.

However I am consufed about 2 things.

Short answer is, "Java isn't the only way OOP."

Longer answers follow.

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.

This is pretty simple: it was judged to be significantly more readable
if you mark class variables explicitly. That is, when you see
something like "self.var" you instantly know it's an attribute of the
object and not a local or global variable.

That you sometimes see Java and (more often) C++ guidelines that
recommend always using "this" for accessing class members shows that
it's somewhat helpful to keep them visually distinct from other
variables.

I think it's a minor point, really, that people make a pretty big deal
over.

2. self.item instead of getters and setters. I thought one of the main
purposes of OO was encapsulation.

Just as an aside: the usage of getters and setters probably does more
to thwart encapsulation than to protect it, in practice.

You see, it doesn't matter whether you access a member directly, or
through getters and setters: you're still accessing the member.
Getters and setters don't encapsulate your data one bit. All they do
is to add a bunch of mostly unnecessary boilerplate.

OTOH, many people add getters and setters recklessly, based on the
above misconception. Not only are they exposing internal details by
doing this, they're also giving the user a blessing to use them.

The practical advantage getters and setters have in Java is that, if
your class implementation changes and you no longer wish for something
that was once a single variable to be that way anymore, you can change
your underlying implementation without changing the interface. That
advantage does not exist in Python, however, since in Python one can
do the same thing with properties.

Doesn't messing with internal object-
representations break this?
I see how the getters and setters could be just visual clutter and you
have to add them to every class so it is annoying a bit in the same
way as self described above.
However I feel like I want getters and setters when I write classes,
not sure of the advantages/disadvantages though.
Only looking at the documentation of a Python-class, will internal
representations be provided?

If I have a class:

class Stack(object):
def __init__(self, *items):
self.stack = list(items)

def append(self, item):
self.stack.append(item)

def pop(self):
return self.stack.pop()

I can get to see the stack with var.stack but then why even implement
append when I could do self.stack.append(x) etc.
That way you could do away with OO completely. So why let people
access the main attribute but not let them manipulate it?
Makes more sense to draw the line to not access any attributes at all
no?

Much of what you're arguing is only true if you accept it as a given
that data hiding is important. The designers of Python don't really
think it is, and that's why they don't have it.


Carl Banks
 
B

bruno.desthuilliers

I first learned about OO from Java.

I much prefer to program in Python though.

However I am consufed about 2 things.

1. Why do I have to pass self into every method in a class?

You mean "declare self as the first argument", I assume ?

This has been explained many times here. Anyway: the point is that
what you define is not a method, but a function. This function needs
to have a way to get at the instance on which it's called, and the
simplest way to do so is to use the common way: passing it as an
argument. This avoids having to have two different constructs -
functions and methods - when one is enough.
Since I am
always doing why cant this be automated or abstracted away?

This could, probably, but you'd had complexity, break uniformity and
loose some interesting features of the language.
2. self.item instead of getters and setters. I thought one of the main
purposes of OO was encapsulation.

I don't know if it's "one of the main purposes", but you're missing
the point: you have to use explicit getters and setters in Java
because Java doesn't have any support for computed attributes. In
Python, the object.attribute syntax doesn't mean you are directly
accessing an instance attribute. First because lookup rules are more
complex than that (not only the instance, but also it's class and it's
class parents are looked up), then because there are several ways to
hook into these lookup rules. Given that you can decouple the
interface (looks like an access attribute) from the implementation
(anything from an instance attribute to a method call in a distantly
related class, possibly including a network connection and database
access), you just don't need explicit getters and setters when
directly accessing an instance attribute is enough (and that's more
than often the case).
Doesn't messing with internal object-
representations break this?

It does, indeed, but it's sometimes necessary (as a matter of fact,
there are ways to get at private attributes even in Java). Anyway,
this is unrelated to your above question about getters and setters.
I see how the getters and setters could be just visual clutter and you
have to add them to every class so it is annoying a bit in the same
way as self described above.
However I feel like I want getters and setters when I write classes,
not sure of the advantages/disadvantages though.

Unless you need to do something else than accessing an instance
attribute, explicit getters and setters in Python are a pure waste of
time for you, anyone using your code, and even the computer.
Only looking at the documentation of a Python-class, will internal
representations be provided?

For which definition of "internal representation" ?
If I have a class:

class Stack(object):
def __init__(self, *items):
self.stack = list(items)

def append(self, item):
self.stack.append(item)

# OT : canonically, it's stac.push(item), not stack.append(item)
def pop(self):
return self.stack.pop()

I can get to see the stack with var.stack but then why even implement
append when I could do self.stack.append(x) etc.

Because you may want to change the implementation, as usual. But you
shouldn't expose stack as part of your API. The convention in Python
is to name implementation stuff with a leading underscore. This a
*very* strong convention saying "don't mess with this unless you know
exactly what you're doing and are willing and able to take full
responsability if you break anything or if your code breaks when I'll
change my class implementation". So just rename 'stack' to '_stack',
and anyone using your class will ignore it unless they have a pretty
good reason to mess with it and are ok to suffer the potential
consequences.
That way you could do away with OO completely.

You could, but what would be the point ? Why would I mess with
implementation when I get what I need using the API ?
So why let people
access the main attribute but not let them manipulate it?

You just can't stop them from manipulating it if they really want, you
know. Don't worry, whatever the language, if someone want to mess with
implementation, he will find a way.
Makes more sense to draw the line to not access any attributes at all
no?

No. Most programmers are of at least median intelligence, and won't
even have a look at your implementation as long as they can - because
they don't want to have to worry about implementation. As long as you
clearly marked something as being "implementation, don't touch", and
provided a sound API, then you've done your job.

I know this can sound disturbing when coming from the ultra-dogmatic
chains-and-bondage world of Java, but from experience (from dozens of
years of thousands of programmers), Python's pragmatic approach
JustWorks(tm).
 
C

castironpi

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:

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.


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.

Part of the value of accessor methods appears when you're changing
class definitions, or changing classes, after you've already started
to use them-- the same interface with a different implementation.

In the AddressBookEntry example, if you changed a pickled dictionary
to a shelf, you could reimplement the class and reprocess stored data
files, all without changing the code that uses the class-- especially
if there's a lot of it, or you don't know where it all is.

Nothing stops you from using accessor methods to offer encapsulation,
and permit back-end changes later. But, nothing in Java stops you
from declaring class members public.

Depending on your development process, data hiding may enforce
distribution of labor a little better, resulting in errors in Java
where Python relies only on discipline. If you're checking for value
validation, you can write a custom setter, regardless of language.

Python doesn't break encapsulation; you do.

In the Stack example, you have more options than you've mentioned.
Can you inherit from list directly? Can you delegate using
reflection? Are you studying this example specifically, or the class
model generally? If you're choosing a language, be careful that
stricter enforcement doesn't cause harder-to-find bugs.

Useful link: Section 9.4 in the docs: http://docs.python.org/tut/node11.html
 
R

Roy Smith

Duncan Booth said:
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.

You can generalize that to, "a lot of programmers assume that OO is defined
by whatever happens to be the first OO language they learn".

In fact, it generalizes even further to the Law of Primacy
(http://en.wikipedia.org/wiki/Principles_of_learning#Primacy). I recognize
this drivel from the crud the FAA publishes:
Primacy, the state of being first, often creates a strong, almost unshakable,
impression. Things learned first create a strong impression in the mind that
is difficult to erase. For the instructor, this means that what is taught
must be right the first time. For the student, it means that learning must be
right. ³Unteaching² wrong first impressions is harder than teaching them
right the first time. If, for example, a student learns a faulty technique,
the instructor will have a difficult task correcting bad habits and
³reteaching² correct ones.

but fundamentally, it's true. If the first programming language (or the
first OOPL) a person learns is Java, it should come as no surprise when
they think they way Java does things is the only way to do things. Having
seen no other ways yet, what else *could* they think?

I have no objection to teaching Java in a CS curriculum. Or even making it
the first language you teach. What I do object to is making it the ONLY
language you teach.

My next door neighbor's kid just finished a MSCS program. The curriculum
did a pretty good job of covering most of the important topics, but they
did it all in Java. Web development in Java, graphics programming in Java,
algorithms in Java, etc. He's well prepared to get a job as a Java
programmer (and, in fact, he did), but I don't think he's really trained to
be a computer scientist.

A good CS program should include a survey of different programming
languages. Today, I would certainly want to give students exposure to C++,
at least one of {Python,Ruby}, and a random sampling of some less main-line
languages like Erlang, Lisp, PHP, Groovy, Smalltalk, or PostScript.
Exactly which ones is not so important as getting to see a wide variety of
different approaches. Only after you've seen a bunch of different ways of
doing something can you start to appreciate the choices different language
designers made.

BTW, there's an interesting article in the July 2008 Computer Magazine: "In
Priase of Scripting: Real Programming Pragmatism". Ronald Loui argues
(amongst other things) that Python would make a good first language to
teach in a CS curriculum.
 
S

ssecorp

Part of the value of accessor methods appears when you're changing
class definitions, or changing classes, after you've already started
to use them-- the same interface with a different implementation.

In the AddressBookEntry example, if you changed a pickled dictionary
to a shelf, you could reimplement the class and reprocess stored data
files, all without changing the code that uses the class-- especially
if there's a lot of it, or you don't know where it all is.

Nothing stops you from using accessor methods to offer encapsulation,
and permit back-end changes later.  But, nothing in Java stops you
from declaring class members public.

Depending on your development process, data hiding may enforce
distribution of labor a little better, resulting in errors in Java
where Python relies only on discipline.  If you're checking for value
validation, you can write a custom setter, regardless of language.

Python doesn't break encapsulation; you do.

In the Stack example, you have more options than you've mentioned.
Can you inherit from list directly?  Can you delegate using
reflection?  Are you studying this example specifically, or the class
model generally?  If you're choosing a language, be careful that
stricter enforcement doesn't cause harder-to-find bugs.

Useful link: Section 9.4 in the docs:http://docs.python.org/tut/node11.html




ty for all the answers. Im not saying either is better Im just trying
to fiugre out the philosophies behind each language and their
respective pros and cons.


and self is apparently not a reserved word so I could replace it with
"blahaba".
But basically Python trusts the programmer and relies on conventions
rather than enforcements like Java does.
 
S

satoru

I first learned about OO from Java.

I much prefer to program in Python though.

However I am consufed about 2 things.

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.

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?
I see how the getters and setters could be just visual clutter and you
have to add them to every class so it is annoying a bit in the same
way as self described above.
However I feel like I want getters and setters when I write classes,
not sure of the advantages/disadvantages though.
Only looking at the documentation of a Python-class, will internal
representations be provided?

If I have a class:

class Stack(object):
    def __init__(self, *items):
        self.stack = list(items)

    def append(self, item):
        self.stack.append(item)

    def pop(self):
        return self.stack.pop()

I can get to see the stack with var.stack but then why even implement
append when I could do self.stack.append(x) etc.
That way you could do away with OO completely. So why let people
access the main attribute but not let them manipulate it?
Makes more sense to draw the line to not access any attributes at all
no?
i think the following article may be helpful to you.
"Introduction to OOP with Python"
http://www.voidspace.org.uk/python/articles/OOP.shtml#id34
 
F

Fredrik Lundh

ssecorp said:
def append(self, item):
self.stack.append(item)

I can get to see the stack with var.stack but then why even implement
append when I could do self.stack.append(x) etc.
That way you could do away with OO completely.

Umm. Even if you were to write that, self and stack would still be
objects, and the "append" would still be a method defined by the stack
object, right?

What you seem to be referring to is the Law of Demeter, which is a
design guideline for avoiding unnecessary coupling, not an absolute
requirement for object-orientation:

http://en.wikipedia.org/wiki/Law_of_Demeter

As for the rest, I suspect you will have more success in using Python if
you use it to write Python programs, not Java programs:

http://dirtsimple.org/2004/12/python-is-not-java.html

</F>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,001
Messages
2,570,251
Members
46,850
Latest member
Brightrs

Latest Threads

Top