Python/Java OOish type question

Tom nospam at nospam.com
Thu Aug 31 10:59:01 EDT 2000


I think you are basically correct about how Python works.

An instance contains a dictionary of its regular attributes, but not its
methods.  As well as these 'regular' attributes, an instance (like the other
types) includes several 'special' attributes.  One of these is '__class__',
which is a reference to the instance's class object, which has function
objects for its methods and it's own special attribute that points to its
base classes.

This means that the number of methods defined for a class doesn't affect the
size of the instances.

C++ works in a similar way.  I'm very surprised to hear that in Java the
number of methods defined for a class affects the size of the instances.  Am
I understanding you correctly?

One thing you can do in Python but not in more 'static' languages, regarding
the size of instances, is to add and delete instances attributes at
run-time.

Tom

"Kirby Urner" <urner at alumni.princeton.edu> wrote in message
news:6hvrqs83a1aq4krle2r7h6d4htgfk9ii0b at 4ax.com...
>
>
> Trying to get clear on something.
>
> I want to have a class with lots of operations defined,
> and thousands of objects which don't carry the overhead
> of those operations in memory (because they've already
> been defined and should be the same for every instance).
>
> In Java, you can do these abstract classes full of static
> ops, and subclass these for the purpose of making objects.
> But these objects will inevitably have some instantiated
> variables that feed into the ops -- and yet static methods
> can't contain instantiated variables.  So I end up with
> something like:
>
>  abstract class quatops {
>
>      protected quat add(quat a, quat b){
>         return new quat(a.value + b.value);
>      }
>  }
>
>  class quat extends quatops {
>
>     int value = 0;
>
>     public quat(int value){
>         this.value = value;
>     }
>
>     public quat add(quat b){
>         return super.add(this,b);
>     }
>  }
>
>  public class play1 {
>     public static void main(String[] args){
>         quat a = new quat(1);
>         quat b = new quat(2);
>         quat c = a.add(b);
>         System.out.println(c.value);
>     }
>  }
>
> When the above executes (which it does), I get 3 (the expected
> answer).
>
> However, I think it's a pity to carry the overhead of an 'add'
> method in each quat (above example), merely for the purpose of
> invoking a static superclass version of this operation -- even
> if the unreplicated static version is in principle much longer
> than these subclass invocations (which might be one-liners).
>
> Of course there's another way to go, which is like what Java
> does with the abstract Math class -- you don't subclass Math,
> but take advantage of its static methods as external to your
> objects (passed as parameters).
>
> But I'm philosophically invested in a design which stuffs ops
> inside the objects in question, which is why the above (why
> this line of questioning).
>
> My impression is Python gets around this by saving the method
> once, statically, even though the method is on the receiving
> end of instantiated variables, i.e. when I write:
>
>   class quat:
>
>      def __init__(self,value):
>          self.value = value
>
>      def add(self,b):
>          return quat(self.value + b.value)
>
> and then go:
>
>   >>> q1 = quat(1)
>   >>> q2 = quat(2)
>   >>> q3 = q1.add(q2)
>   >>> q3.value
>   3
>
> I'm NOT getting copies of the 'add' method inside every quat
> object.  Or am I?  Isn't it the case that quat is basically
> instantiating once, leaving room for 'self' to go through as
> a kind of parameter, different for each object of type quat
> (including subtypes)?
>
> Methods are like class variables in this sense (more dictionary
> entries).  So whereas Java abstract classes have no room for
> any instantiated object data (are "flat"), Python classes are
> just deep enough to give every instantiated object an anchor
> back to the same method bytecodes.
>
> I think this because of what I see in the __dict__ of each
> of the above:
>
>  >>> q1.__dict__
>  {'value': 1}
>  >>> q2.__dict__
>  {'value': 2}
>  >>> quat.__dict__
>  {'__init__': <function __init__ at 12afb00>, '__doc__': None,
>  'add': <function   add at 12afe10>, '__module__': '__main__'}
>
> Only the class dictionary contains the function.
>
> You can get memory references for q1.add and q2.add, but the
> different returns correspond to the locations of q1 and q2
> as objects -- doesn't tell me whether the add method is
> actually taking up bytes inside q1 and q2.
>
>  >>> q1.add
>  <method quat.add of quat instance at 1ae9b00>
>  >>> q2.add
>  <method quat.add of quat instance at 1aeb3d0>
>  >>> q2
>  <__main__.quat instance at 1aeb3d0>
>
> I may be rather confused here.  Anyone with the patience to
> help me sort it out?
>
> Kirby
>





More information about the Python-list mailing list