Why self?

Rich Harkins rich at worldsinfinite.com
Tue Jul 9 15:56:01 EDT 2002


> [snip]
> If you are subclassing a class that someone else has written, you don't
> want to accidentally redefine an internal name.  Sorry.  I can accept
> that you should be able to explicitly access it, but to be able to
> change it by accident is (would be?) a misfeature.
>
> I didn't believe that this happened in Python.  It does, and it seems a
> significant flaw.  My understanding is that if you define a variable in
> a class that subclasses another class, then unless you take definite
> steps to cause things to happen otherwise, you are defining a new
> variable that is local to the scope of the class that you are currently
> defining, and will not impact routines that you call from parental
> classes.  Experiment shows that this isn't what happens.
> from __future__ import nested_scopes
> does not fix this problem, as I assumed that it would.
>
> Let's be explict:
> from __future__ import nested_scopes
> class A:
>     def ma(self):
>         print  "ma, ma"
>     def pa(self):
>         self.ma()
> class B(A):
>     def ma():
>         print "hello, world"
> tst = B()
> tst.pa()
>
> Testing this produces the message, "hello, world"
> This seems to be the wrong message.  The version of pa that was called
> was the version defined in class A, so the routine called should have
> been the routine defined in class A.
>
> Or, to me more accurate, for libraries to have maximal portability, I
> would want the message to have generated "ma, ma", and I had been
> assuming that nested_scopes would result in that being the message that
> was produced.

This would happen in Java/C++ too:

public class X
{
	public String ma()
	{
		return "ma, ma";
`	}
	public String pa()
	{
		return ma();
	}
};

public class Y extends X
{
	public String ma()
	{
		return "hello, world";
	}
};

Calling Y().pa() would return "hello, world", just like Python.  So this seems 
to me a problem of general polymorphism rather than Python.  In Python you 
could at least force it by being explicit and utilizing the fact that classes 
are first-class objects too (C++ works similarly, but Java doesn't let me 
call arbitrary superclass methods for some reason):

class A:
	def ma(self):
		print "ma, ma"
	def pa(self):
		A.ma(self)
class B(A):
	def ma(self):
		print "hello, world"

Java/C++ have the same problem with instance variables too that aren't 
declared private (private is spelled __ in Python) as much as Python does, 
other than in Java/C++ I can't change the type of the inherited instance 
variable.  I am aware that Java/C++ deter using member variables of inherited 
classes directly, but this is one of the things I *like* about Python, and 
why I don't spend so much wasted time defining get/set methods when I can 
just *use* the variable in question.

Anyway, that's my .02.
Rich






More information about the Python-list mailing list