inner classes in python as inner classes in Java

Alex Martelli aleax at aleax.it
Thu Oct 16 07:54:23 EDT 2003


Carlo v. Dango wrote:

> On Wed, 15 Oct 2003 21:52:32 GMT, Alex Martelli <aleaxit at yahoo.com> wrote:
> 
>> You'll have to decide what semantics you want to obtain when an
>> attribute is set on an instance of the "inner class" -- I sure can't do
>> it on your behalf.
> 
> I want the semantics of java's inner classes and the semantics of inner
> methods... that the inner class shares the fields and methods of its outer
> class instance.. But I've come to realize I can't do this in python, as

I don't understand what you mean.  "inner methods" (? presumably you
mean nested functions ?) cannot re-bind names in outer scope -- you say
you want these semantics, and you also seem to say you DO want assignments
on the innerobject's attribute to re-bind attributes on the outer.  There
is a contradiction here in what you say.  Neither in Python nor with any
other tools whatsoever can you implement contradictory requirements.

Give non-contradictory requirements about what you want to happen
upon "inner.i = 23" and you will be able to implement them (whether
they will be at all useful or sensible is quite another issue, of
course).

> the statement in some method in the inner class "self.i = 42" can be
> interpreted as "create i in the inner class instance" or "lookup i in the
> 'outer scope' and set it"

It can be interpreted to mean any non-contradictory set of requirements
you want to be interpreted as.  Having as yet no idea of what you may
hope to accomplish, that is useful at all, I can't guess what those
hypothetical requirements could possibly be.


>> There's a reason the official Python style guidelines have been
>> amended to prefer spaces instead of tabs, you know.  Sure, there
>> will be some programs who display tabs in a way compatible with
>> your preferences, but others won't; be conservative in what you
>> generate -- spaces are ensured to be displayed as you intend, tabs
>> are NOT, so don't use the latter in any code you send to others.
> 
> hmm depends on which font people are using.. if it's not monospace, the
> layout will also change.. 

This assertion is false.  Since the _significant_ whitespace is only
that which occurs at the start of a line, as long as each occurrence
of a space character is displayed with the same width X, it cannot 
possibly matter in terms of code meaning what witdths x1, x2, ... xN
are used to display other, non-whitespace characters.  In particular
it cannot matter whether x1==x2==...==xN or not, nor whether any one,
several or all xi's happen to equal X.

If you want your code's meaning to be unaltered, always indent it
with spaces, NOT tabs.  It does NOT matter which fonts people are
using.  If you indent with spaces, they'll see your code meaning
the same thing.  If you indent with tabs, there's no guarantee.  This
is part of the reason PEP 8, "Style Guide for Python Code", was
updated by Guido van Rossum to read "For new projects, spaces-only
are strongly recommended over tabs" and similar phrasings.

> I doubt that there are many news readers where
> you cannot set TAB == 4 spaces

Two might suffice, when they're among the most widely used: Microsoft
Outlook Express, and KDE's KNode.  And no, of course I'm not going to
change my favourite newsreader to accomodate people who choose to
violate the official Python style guide.


>>> actually its forwarding or consultation, as self is re-bound when you
>>> invoke the outer..
>>
>> In your Python code (and mine), it is false that "self is re-bound"
>> (only an instruction such as "self = ..." would do that, and there is
>> no such instruction in that code).  Sure, when a method A of
>> object B calls a method X of object Y, the local name 'self' is
>> bound to Y in the execution of X while the same name is bound
>> to B in the execution of A.  But that is not re-binding -- just the
>> distinction between lexically-same names in different scopes.
> 
> well, I disagree... there is a difference between virtual and non-virtual
> methods. 

Not in Python: absolutely no difference, since there's no such thing
as a "non-virtual" method.

> The first does not re-bind self, when doing super calls or when
> casting an object to some super class and invoking methods on it (like
> using C++'s :: )

There is no "casting" in Python.  If you refer to such notation as, e.g.:

  class mydict(dict):
      def __getitem__(self, key):
          return dict(self)[key]

I'll inform you that the dict(self) DOES return an object with an id
different from that of self, which would mean (if dict were coded in
Python) that the 'self' received by the superclass's __getitem__ would
be a different one from that in the subclass.  That is different from
the "superclass call" usage
          return dict.__getitem__(self, key)
where an _unbound_ method is extracted from class dict, exactly in
order to be able to pass to it an 'unmodified' self explicitly (the
main advantage being one of efficiency).


>> Anyway, the term "delegation" is common for the operation in
>> question - it is for example used in the "gang of 4"'s Design
>> Pattern book.
> 
> well, 'delegation' is cited in OOPSLA, ECOOP, AOSD etc litterature of
> being defined in the seminal 1986 OOPSLA paper "Using Prototypical Objects
> to Implement Shared Behavior in Object-Oriented Systems" by H. Lieberman.
> the GOF book came out around 9 years later.

...and became an instant best-seller, cementing the usage.  So, e.g., a
proxy is equally well said to provide _delegation_ to an object it proxies
for, as to provide _forwarding_ to that object.  Yes, I know Szyperski tries
to draw a fine distinction -- that "subsequently delegated messages are
dispatched back to the original delegator", which isn't true in forwarding
(the difference would appear in cases of what the gang of 4 call the
'Template Method' design pattern).  What I'm saying is that this terminology
distinction has little practicel currency -- look, for example, at what C#
calls 'delegates' and tell me how delegating to them could `dispatch back`
to the delegator (caller) [answer: it won't].  Or see how Fowler uses the
terms in his "Refactoring" for the "Replace Delegation with Inheritance"
and "Replace Inheritance with Delegation" refactorings (p. 325 ff).


Alex





More information about the Python-list mailing list