inner classes in python as inner classes in Java

Discussion in 'Python' started by Carlo v. Dango, Oct 15, 2003.

  1. Inner classes in Python is merely hidding of structure rather than
    providing a scope as in Java. eg. this program fails in the print-line..


    class A(object):
    def __init__(self):
    self.name = "hans"

    class B(object):
    def foo(self):
    print "my name is " , self.name
    a = A()
    b = a.B()
    b.foo()


    to remedy this, I thought of having an "outer" attribute which was
    accessed when the class itself could not find a given property. However, I
    think the following definition is problematic as it bites itself. in the
    init method i introduce the "outer" field.. however, at this point the
    __getattr__ is called which makes me look in the outer scope.. which was
    not the intention. How to do a proper implementation?


    class A(object):
    def __init__(self):
    self.name = "hans"

    class B(object):
    def __init__(self, outer=None):
    self.outer = outer

    def foo(self):
    print "my name is " , self.name

    def __getattr__(self, name):
    if self.outer != None:
    return self.outer.getattr(name)
    else: raise Error("attribute ", name, " not found!")

    def __setattr__(self, name, value):
    if self.outer != None:
    self.outer.setattr(name, value)
    else: raise Error("attribute ", name, " not found!")

    a = A()
    b = a.B(a)
    b.foo()




    Carlo...

    --
    Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
     
    Carlo v. Dango, Oct 15, 2003
    #1
    1. Advertising

  2. Carlo v. Dango wrote:
    ...
    > init method i introduce the "outer" field.. however, at this point the
    > __getattr__ is called which makes me look in the outer scope.. which was
    > not the intention. How to do a proper implementation?


    I think what's called is __setattr__, NOT __getattr__. __setattr__ if you
    define it is called for EVERY attribute you set by assignment, and there
    is no "finding" involved whatsoever. Do you TRULY want to delegate all
    attribute settings, performed on an instance of the innerclass, to the
    corresponding 'outer' -- _except_ self.outer? If so, then the following
    should be OK:

    class B(object):

    def __init__(self, outer=None):
    # the key issue: bypass B.__setattr__ by delegating to the
    # superclass's (object's) implementation
    object.__setattr__(self, 'outer', outer)

    def foo(self):
    print 'my name is', self.name

    def __getattr__(self, name):
    if self.outer is None:
    raise AttributeError, name
    return getattr(self.outer, name)

    def __setattr__(self, name, value):
    if self.outer is None:
    raise AttributeError, name
    return setattr(self.outer, name, value)

    I have taken the occasion to correct other errors you had with
    attribute getting and setting, and indent with spaces, not with
    tabs (your post was indented with tabs thus unreadable with such
    newsreaders as KDE's KNode, Outlook Express, et al: please do
    NOT post code indented with tabs, thanks).

    It's not very clear to me what you mean to obtain with this
    class B, but, in any case, this is how to do this kind of
    automatic delegation in Python.


    Alex
     
    Alex Martelli, Oct 15, 2003
    #2
    1. Advertising

  3. > Do you TRULY want to delegate all
    > attribute settings, performed on an instance of the innerclass, to the
    > corresponding 'outer' -- _except_ self.outer?


    No, what a strange idea ;-) All attributes not found in the class should
    be forwarded to it's outer instance (as I want to simulate that the inner
    class instance is within the scope of its outer class instance.

    > tabs (your post was indented with tabs thus unreadable with such
    > newsreaders as KDE's KNode, Outlook Express, et al: please do
    > NOT post code indented with tabs, thanks).


    why is that? has TAB-technology not reached linux yet? :) I try to
    remember it, I just prefer tabs over spaces..


    > class B, but, in any case, this is how to do this kind of
    > automatic delegation in Python.


    actually its forwarding or consultation, as self is re-bound when you
    invoke the outer..


    <- carlo ->


    --
    Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
     
    Carlo v. Dango, Oct 15, 2003
    #3
  4. Comming to think of it, it can't be done in python! Since there is no way
    to denote you want to access a field rather than creating a new one,
    __setattr__ will have no changes of knowing when to create the field or
    look it up in the outer scope... this suxx man... I never understood the
    smart thing about that feature in python.. anyone care to enlighten me?

    <- carlo ->


    --
    Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
     
    Carlo v. Dango, Oct 15, 2003
    #4
  5. Carlo v. Dango wrote:

    >> Do you TRULY want to delegate all
    >> attribute settings, performed on an instance of the innerclass, to the
    >> corresponding 'outer' -- _except_ self.outer?

    >
    > No, what a strange idea ;-) All attributes not found in the class should
    > be forwarded to it's outer instance (as I want to simulate that the inner
    > class instance is within the scope of its outer class instance.


    What does "found" have to do with attribute setting? In Python:

    class X: pass

    x=X()
    x.foo=23

    sets attribute named 'foo' to the value of 23 on x. "found"...?! What
    can you possibly mean?

    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.


    >> tabs (your post was indented with tabs thus unreadable with such
    >> newsreaders as KDE's KNode, Outlook Express, et al: please do
    >> NOT post code indented with tabs, thanks).

    >
    > why is that? has TAB-technology not reached linux yet? :) I try to
    > remember it, I just prefer tabs over spaces..


    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.


    >> class B, but, in any case, this is how to do this kind of
    >> automatic delegation in Python.

    >
    > 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.

    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.


    Alex
     
    Alex Martelli, Oct 15, 2003
    #5
  6. Carlo v. Dango wrote:

    > Comming to think of it, it can't be done in python! Since there is no way
    > to denote you want to access a field rather than creating a new one,


    When you access a field you access it, e.g:

    print blah.bluh

    this accesses it -- it will never create anything. When you ASSIGN to a
    field you create it if it wasn't there (if it was there, the previous value
    is removed, and the field is created afresh again). You can use
    descriptors (in new-style classes) to handle assignments (and accesses
    too, if you want) in special ways for some attributes.


    > __setattr__ will have no changes of knowing when to create the field or
    > look it up in the outer scope... this suxx man... I never understood the
    > smart thing about that feature in python.. anyone care to enlighten me?


    If you can't see that it's simpler to let

    target = value

    have the same semantics whether target was already bound to something
    or not, it's hard to see what will convince you.

    For the case of someobject.attr = value, you do get to add complications
    if you want -- e.g., when wrapping someobject in your proxy, you can
    introspect to find what attributes it had at that time, and prepare a
    custom class with the set of descriptors you want. Or, if you are in no
    hurry, you can to such checks at the time of eahc assignment.

    Such tender loving care will typically break the semantics of your
    proxying in general cases, but if you have total control on the class
    whose instances you're wrapping that need not be the case. It's
    still hard to say what benefits you'll be getting, of course, but there
    may be some cunning plan behind it all.


    Alex
     
    Alex Martelli, Oct 15, 2003
    #6
  7. On Wed, 15 Oct 2003 22:20:44 GMT, Alex Martelli <> wrote:



    >> __setattr__ will have no changes of knowing when to create the field or
    >> look it up in the outer scope... this suxx man... I never understood the
    >> smart thing about that feature in python.. anyone care to enlighten me?

    >
    > If you can't see that it's simpler to let
    >
    > target = value
    >
    > have the same semantics whether target was already bound to something
    > or not, it's hard to see what will convince you.


    I can't... mispelling occours and leed to stupid bugs rather than compile
    errors which are simple to check. Even smalltalk has this feature..



    > its still hard to say what benefits you'll be getting, of course, but
    > there
    > may be some cunning plan behind it all.


    aaaah come on :) you really cannot see the nice things of having a scope
    for inner class instances?? It's like inner method.. atleast they share
    scope with their outer method... if it didn't it would render inner
    methods almost useless..

    class A(object):
    def foo(self):
    i = 3
    def bar():
    print i

    bar()





    --
    Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
     
    Carlo v. Dango, Oct 16, 2003
    #7
  8. On Wed, 15 Oct 2003 21:52:32 GMT, Alex Martelli <> 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
    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"



    > 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.. I doubt that there are many news readers where
    you cannot set TAB == 4 spaces




    >> 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. 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 :: )


    > 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.


    Carlo

    --
    Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
     
    Carlo v. Dango, Oct 16, 2003
    #8
  9. Carlo v. Dango

    Duncan Booth Guest

    "Carlo v. Dango" <> wrote in
    news:eek::

    >> 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 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"


    What you want wouldn't necessarily be impossible. You should be able to
    create a metaclass for the inner class that automatically creates
    properties in the inner class which access the outer class fields. That way
    you could expand:

    self.a = 42

    to something equivalent to:

    self.__outer.a = 42

    Actually, thinking about it you need to put the metaclass on the outer
    class rather than the inner one. That way when the outer class is created,
    you can check its dictionary for any classes it contains and give each of
    those classes the appropriate properties.

    I think it ought also to be possible to add a __get__ method to the inner
    class so that accessing the inner class through an instance of the outer
    class returns what would effectively be a 'bound class' (cf bound method)
    which sets the __outer member automatically when you create an instance of
    the inner class.

    --
    Duncan Booth
    int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
    "\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
     
    Duncan Booth, Oct 16, 2003
    #9
  10. Carlo v. Dango wrote:

    > On Wed, 15 Oct 2003 21:52:32 GMT, Alex Martelli <> 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
     
    Alex Martelli, Oct 16, 2003
    #10
  11. On Thu, 16 Oct 2003 09:48:52 +0200, "Carlo v. Dango" <>
    wrote:

    [text snipped]

    >
    >aaaah come on :) you really cannot see the nice things of having a scope
    >for inner class instances?? It's like inner method.. atleast they share
    >scope with their outer method... if it didn't it would render inner
    >methods almost useless..
    >
    >class A(object):
    > def foo(self):
    > i = 3
    > def bar():
    > print i
    >
    > bar()


    What do you *really* want? As far as I remember (it's been a long time
    since I've dealt with Java), the biggest use for inner classes in Java
    is in faking closures. That's a non-issue in Python, in part because
    *every* object is a first class citizen, functions, methods and
    classes included. There is no such thing as a class-scope, only
    function definitions open a new (local) scope. As others have posted
    you *can* fake that with __setattr__ and/or a metaclass solution, but
    *why* would you want to go down that path that is what I cannot
    fathom.

    With my best regards,
    G. Rodrigues
     
    Gonçalo Rodrigues, Oct 16, 2003
    #11
  12. Carlo v. Dango wrote:

    > On Wed, 15 Oct 2003 22:20:44 GMT, Alex Martelli <> wrote:
    >
    >>> __setattr__ will have no changes of knowing when to create the field or
    >>> look it up in the outer scope... this suxx man... I never understood the
    >>> smart thing about that feature in python.. anyone care to enlighten me?

    >>
    >> If you can't see that it's simpler to let
    >>
    >> target = value
    >>
    >> have the same semantics whether target was already bound to something
    >> or not, it's hard to see what will convince you.

    >
    > I can't... mispelling occours and leed to stupid bugs rather than compile
    > errors which are simple to check. Even smalltalk has this feature..


    So does pychecker, e.g., given the following erroneous a.py:

    def func(lead):
    "return the argument if true, else 23"
    if not lead: leed = 23
    return lead

    running "pychecker a" will easily warn you:

    a.py:4: Local variable (leed) not used

    et voila, the "stupid bug" is squashed, without any need to burden
    down the language with ``declarations'' for the purpose. Some of
    pychecker's functionality is likely to get incorporated in future
    versions of Python interpreter (just like good old tabnanny.py's
    functionality was once incorporated via the -t switch).


    >> its still hard to say what benefits you'll be getting, of course, but
    >> there may be some cunning plan behind it all.

    >
    > aaaah come on :) you really cannot see the nice things of having a scope
    > for inner class instances?? It's like inner method.. atleast they share
    > scope with their outer method... if it didn't it would render inner
    > methods almost useless..
    >
    > class A(object):
    > def foo(self):
    > i = 3
    > def bar():
    > print i
    >
    > bar()


    Your stubborn refusal to follow Python's recommended style, which
    I already repeatedly explained to you (indent with spaces, not tabs)
    makes your code look like the above -- flat and meaningless -- in
    KDE's KNode (and MS Outlook Express, too, also widely used).

    In any case, I cannot see any _usefulness_ whatsoever in the above
    snippet, no matter how one inserts whitespace in it -- it appears
    to use a def statement for 'bar' in a totally gratuitous way,
    without any benefit whatsoever. There ARE, of course, good use
    cases for nested functions (the inner one just isn't a method no
    matter how much you waste your breath saying it is); many of them
    relate to returning the function object created by the inner def
    (the 'closure' idiom):

    def make_summator(addend):
    def summator(augend): return augend + addend
    return summator

    this is about the simplest case that is of any use. When Python
    did not nest scopes, this was equivalently implemented as:

    def make_summator(addend):
    def summator(augend, addend=addend): return augend + addend
    return summator

    and you can still code it that way (it's marginally faster at
    runtime, but not enough to matter). It's fractionally handier
    to not have to inject names explicitly, but, again, it's hardly
    a major issue in terms of programmer's productivity.

    A simple but non-toy use case for a class defined within another
    class might be an iterable/iterator pair:

    class tree(object):

    # snipped: most definitions of tree's methods

    def __getitem__(self, tree_index):
    # somehow locate and return the item of this tree
    # corresponding to key 'tree_index', or raise
    # IndexError if tree_index is out of bounds

    class iterator(object):
    def __init__(self, tree):
    self.tree = tree
    self.index = 0 # or whatever means "first item's index"
    def __iter__(self):
    return self
    def next(self):
    try: item = self.tree[self.index]
    except IndexError: raise StopIteration
    self.index += 1 # or whatever means "next item's index"
    return item

    def __iter__(self):
    return self.iterator(self)

    Note the amount of 'overhead' you have here to let the tree's
    __iter__ method specifically pass 'self' when instantiating the
    tree_iterator class: essentially negligible when compared to
    the amount of other code in even such a simple example as this
    one. In contrast, a closure might want to bind some number of
    names from the outer scope, and the amount of other code
    involved can be tiny, so the admittedly-small overhead of
    explicitly injecting (binding) names stands out more. At
    the same time, having tree.iterator intrinsically "inherit"
    names from the scope of class tree would be potentiallly quite
    problematic: e.g. the user might erronously 'index' an iterator
    and be in fact indexing the whole tree (if name __getitem__ got
    thus transparently injected), quite ignoring the current index
    in the iterator. The incredibly tiny benefits of having a
    class automatically get names from the scope of the containing
    class would obviously be dwarfed by the evident problems.

    Further note that neither in nested functions, neither in
    nested classes, is there any need in the above examples to
    BIND any name in the containing scope. Indeed, nested
    functions just don't support that: the inner function can
    ACCESS outer names, but NOT rebind them. The interest of
    binding outer names WOULD be there -- in examples not quite
    as trivial as these, but almost -- but there is absolutely
    no interest in having that be 'transparent'. There is
    currently no syntax to rebind names from an inner function
    in the outer scope (you need to achieve similar ends by
    _mutating_ mutable objects in the outer scope, a very
    different concept from that of rebinding names). Rebinding
    names from the inner to the outer class is achieved in just
    the same way as accessing them -- i.e. normally by explicit
    non-transparent syntax such as self.tree.foobar (be it for
    access or for rebinding).

    But what is the purported usefulness of having the inner
    class act as a somewhat transparent proxy for the outer one?
    The iterable/iterator example does nothing of the kind and
    has no need for any such transparency (which indeed would
    seriously impair it). What are the use cases for instances
    of the nested (inner) class acting as proxies for instances
    of the containing (outer) one, intercepting some but not all
    of the attribute rebindings (and presumably deletions? have
    not seen you implement __delattr__ for that purpose) yet
    handling other rebindings "on its own", AND somehow choosing
    which re-bindings to delegate and which to intercept in a
    totally automatic/introspective way (e.g. based on what set
    of attributes happen to be defined on the outer class's
    instance at some given point in time)?

    As I said, there may be some cunning plan behind this weird
    kind of specs, but you surely have not given any indication
    of what need you might have for them (indeed, haven't given
    any complete non-contradictory set of specs that I've seen
    for the rebinding behavior you appear to desire). And no,
    I "cannot see the nice things" unless you indicate a use case:
    I have neither had nor seen such a specific need in 4 years
    of Python usage, writing, teaching, mentoring, tutoring, and
    consulting. I _have_ used inner classes in Java, mostly as
    workarounds for the lack of multiple inheritance (a lack
    which Python doesn't share), but also marginally for other
    things -- but none that would require transparent rebinding
    in a Python setting. If you _do_ finally deign to indicate
    the use cases you have in mind, as well as the exact, precise
    and non-contradictory semantics for attribute access and for
    attribute rebinding that you think are best suited to handle
    your use cases, it's possible that experienced Pythonistas may
    be able to indicate preferable approaches, as well as to
    advise on how to implement the approach you think you need.


    Alex
     
    Alex Martelli, Oct 16, 2003
    #12
  13. > Carlo v. Dango wrote:
    >> 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


    Alex Martelli wrote:
    > 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.


    Inner classes (not static inner classes) in Java work as follows:
    - the inner class has a reference to an object of the enclosing class
    - any identifier is searched in the method scope, the inner class scope, the
    enclosing class scope, so an identifier A can mean A (local), this.A
    (inner), this.__enclosing__.A (enclosing), depending on where the compiler
    finds it.

    A Python implementation for inner classes would be:
    class Inner:
    def __init__ (self, enclosing):
    self.__enclosing__ = enclosing

    def __getattr__ (self, name):
    return getattr (self.__enclosing__, name)

    def __setattr__ (self, name, value):
    if hasattr (self.__enclosing__):
    setattr (self.__enclosing__, name, value)
    else:
    setattr (self, name, value)

    Java hides the 'enclosing' when creating objects, so
    new Inner ()
    becomes
    new Inner (this)

    Not that I think that hiding the real access path is a good idea.

    Daniel
     
    Daniel Dittmar, Oct 16, 2003
    #13
  14. On Thu, 16 Oct 2003 08:30:06 +0000 (UTC), Duncan Booth
    <> wrote:

    > "Carlo v. Dango" <> wrote in
    > news:eek::
    >
    >>> 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 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"

    >
    > What you want wouldn't necessarily be impossible. You should be able to
    > create a metaclass for the inner class that automatically creates
    > properties in the inner class which access the outer class fields. That
    > way
    > you could expand:
    >
    > self.a = 42
    >
    > to something equivalent to:
    >
    > self.__outer.a = 42
    >
    > Actually, thinking about it you need to put the metaclass on the outer
    > class rather than the inner one. That way when the outer class is
    > created,
    > you can check its dictionary for any classes it contains and give each of
    > those classes the appropriate properties.


    that is a nice idea, however, how do I know which fields are defined in
    the outer class?? fields can be defined in every method and on runtime..

    class A(object):
    def foo(self, arg):
    if arg == 0:
    self.i = 3 # create a 'i'
    else
    self.j = 4 # create a 'j'


    so when the metaclass examines my A class, are both i and j defined in the
    class or how?



    > I think it ought also to be possible to add a __get__ method to the inner
    > class so that accessing the inner class through an instance of the outer
    > class returns what would effectively be a 'bound class' (cf bound method)
    > which sets the __outer member automatically when you create an instance
    > of
    > the inner class.


    that would be rather cool, but Im not sure I fully understand your idea.
    could you produce some (pseudo) code?


    -carlo






    --
    Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
     
    Carlo v. Dango, Oct 18, 2003
    #14
  15. Carlo v. Dango wrote:
    ...
    > that is a nice idea, however, how do I know which fields are defined in
    > the outer class?? fields can be defined in every method and on runtime..


    You can check if class A has [at this very moment] an attribute named 'x' by
    hasattr(A, 'x').

    More likely, you will be interested in whether some INSTANCE a of class A
    has that attribute [at this very moment], i.e. hasattr(a, 'x').

    You can of course only check the situation "at this very moment", not if a
    will at some future point during its lifetime acquire or lose such an
    attribute (that cannot, in general, be forecast).

    Given that your purpose is to set (i.e., bind or rebind) an attribute 'x'
    either on a or on some other object b, I cannot see any usefulness in
    making that decision based on whether a had that attribute now or had
    it at some time in the past. I have repeatedly asked you to show a use
    case where dispatching attribute-setting in such ways serves a purpose
    useful to the application program, but received no usable answer. This
    reinforces my current working hypothesis that whatever purpose you
    think you need to serve this way might likely be best served otherwise,
    but, without knowing of that purpose, I cannot advance further suggestions.

    E.g., you've repeatedly mentioned some analogy to inner functions - which
    CANNOT re-bind names in their outer scope! -- thus failing to provide any
    usefulness whatsoever in understanding your perceived binding needs...!

    If and when the purpose that's supposed to be served by such dispatching
    is made clear, THEN mechanisms to achieve such dispatching may be
    meaningfully discussed, compared, and contrasted; not before.


    Alex
     
    Alex Martelli, Oct 19, 2003
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Neil Zanella

    Java inner classes and static methods

    Neil Zanella, Oct 27, 2003, in forum: Java
    Replies:
    1
    Views:
    2,696
    Chris Smith
    Oct 27, 2003
  2. lonelyplanet999
    Replies:
    1
    Views:
    2,288
    VisionSet
    Nov 13, 2003
  3. Razvan
    Replies:
    5
    Views:
    11,366
    Dale King
    Jul 27, 2004
  4. Christian Bongiorno
    Replies:
    5
    Views:
    568
    Chris Uppal
    Aug 30, 2004
  5. Pyenos
    Replies:
    2
    Views:
    420
    Pyenos
    Dec 27, 2006
Loading...

Share This Page