object oriented programming question

Michael Spencer mahs at telcopartners.com
Sat Dec 17 18:27:26 EST 2005


Daniel Nogradi wrote:
> I have class 'x' with member 'content' and another member  'a'  which is an
> instance of class '_a'. The class '_a' is callable and has a method 'func'
> which I would like to use to modify 'content' but I don't know how to
> address 'content' from the class '_a'. Is it possible?
> 
> Here is the code that I've described above:
> 
> class _a:
>     def __call__(self, v):
>         print v
> 
>     def func():
>         """I would like to do something
>         with ´content´ here"""
> 
> class x:
>     def __init__(self):
>         self.content = [ ]
> 
>     a = _a()
> 
> 
> Now I would like to be able to say
> 
> inst = x()
> x.a(5)
> x.a.func()
> 
> where the second line prints '5' as expected, but I don't know how to make
> the third line change 'x.content'.
> 

Hello Daniel

You've certainly got a lot going on here.

The heart of your question seems to be how a nested (inner) class _a can access 
its parent, x.  The short answer is that, in Python, it can't without some help. 
  _a and its instances are unaware of the context in which they are defined, so 
they hold no references to x or instance of x.  (Technically this is because the 
class is not created until after the statements in the class suite are executed)

Before we get to that, though, note that you've made content an attribute of x's 
instances, not the x class.  So there is no x.content, only inst.content.  I'll 
assume this was a typo, and you intended inst.content.  If this distinction is 
mysterious you may want to check: http://docs.python.org/tut/node11.html

Now, back to the question of how instance a could get a reference to inst.  The 
simplest way to program this is to give it the reference explicitly:


class _a:

     def func(self):
         """I would like to do something
         with ´content´ here.
         """
         print self.__parent__.content


class x:
     def __init__(self):
         self.content = ["I'm", "self.", "content"]

     a = _a()

  >>> inst = x()
  >>> inst.a.__parent__ = inst # give inst.a a reference to its parent
  >>> inst.a.func()
  ["I'm", 'self.', 'content']
  >>>



There is a way to automate "inst.a.__parent__ = inst", although it's not ideal 
"getting starting with Python objects" material.  The solution is to have _a 
implement the descriptor protocol (see: 
http://users.rcn.com/python/download/Descriptor.htm), and make the classes 
"new-style", i.e., derived from 'object':

class _a(object):

##    def __call__(self, v):  Method is irrelevant to this discussion
##        print v

     def func(self):
         """I would like to do something
         with ´content´ here.
         """
         print self.__parent__.content


     def __get__(self, obj, cls):
         """Store a reference to the referring obj"""
         if isinstance(obj, cls):
             self.__parent__ = obj
         return self

class x(object):
     def __init__(self):
         self.content = ["I'm", "self.", "content"]

     a = _a()


  >>> inst = x()
  >>> inst.a.func() #no need to set inst.a.__parent__ = inst manually now
  ["I'm", 'self.', 'content']
  >>>

HTH

Michael











More information about the Python-list mailing list