Mailing List Archive

building embedded classes as in C/C++
Hi,

I'd like to build an embedded structure (Python class) much like I do in
C if possible. When I do the following, multiple instances of my final
class overwrite each others sub-class values!

-------------------------------------------------------------------------
class Point:
x = 0
y = 0
z = 0

class Object:
pos = Point()
ang = Point()


obj1 = Object()
obj2 = Object()

obj1.ang.x = 123

print obj2.ang.x <<-- AND I FIND IT CONTAINS OBJ1's X VALUE
-------------------------------------------------------------------------



In C, this would be:

-------------------------------------------------------------------------
typedef struct Point {
float x;
float y;
float z;
} Point;

typedef struct Object {
Point pos;
Point ang;
} Object;

Object obj1;
Object obj2;

obj1.ang.x = 123;
printf("%f", obj2.ang.x); <<-- AND NOW THE VALUES IN OBJ1 AND OBJ2
WILL NOT BE RELATED (OBJ2 WILL JUST
CONTAIN GARGAGE AT THIS POINT).
-------------------------------------------------------------------------


I've found that writing something like:

class Object(Point):
...

works, but then I don't have a wrapper around the (x, y, z) values
anymore and I
don't know how to bring in Point more than once. Is it possible to do
this in Python. I've looked in the tutorial and Mark Lutz's book to no
avail.

Thanks,
Andy Beall
building embedded classes as in C/C++ [ In reply to ]
On Tue, 03 Aug 1999 17:12:41 -0700, Andy Beall <beall@psych.ucsb.edu> wrote:
>Hi,
>
>I'd like to build an embedded structure (Python class) much like I do in
>C if possible. When I do the following, multiple instances of my final
>class overwrite each others sub-class values!
>
>-------------------------------------------------------------------------
>class Point:
> x = 0
> y = 0
> z = 0
^^^^^^ no mention of "self" anywhere
>
>class Object:
> pos = Point()
> ang = Point()
^^^^^^ no mention of "self" here either
>
>
>obj1 = Object()
>obj2 = Object()
>
>obj1.ang.x = 123
>
>print obj2.ang.x <<-- AND I FIND IT CONTAINS OBJ1's X VALUE

[snip]

(N.B. C++ code in this posting is untested. Caveat emptor)

Well ... not exactly. Your Python code is more analogous to:
class Point {
public:
static int x;
static int y;
static int z;
Point() {} // <=== Note no mention of "this->anything" here
};
int Point::x = 0;
int Point::y = 0;
int Point::z = 0;

That is, if you don't attach the variables to the object being instantiated,
they're considered "class statics". In C++ you have to explicitly declare
variables as class statics, whereas Python makes them so by default. The
correct Python code is more likely:

class Point:
def __init__(self):
self.x = 0
self.y = 0
self.z = 0

class Object:
def __init__(self):
self.pos = Point()
self.ang = Point()

obj1 = Object()
obj2 = Object()
obj1.ang.x = 123
print obj2.ang.x

Note the parallel concepts of using the explicit class method argument "self"
in Python and the C++ implicit arg "this".


>-------------------------------------------------------------------------
>
>
>I've found that writing something like:
>
>class Object(Point):
> ...
>
>works, but then I don't have a wrapper around the (x, y, z) values
>anymore and I
>don't know how to bring in Point more than once. Is it possible to do
>this in Python. I've looked in the tutorial and Mark Lutz's book to no
>avail.
>
>Thanks,
>Andy Beall

Of course it is ... everything is possible in Python, since it is Turing
complete. On a different philosophical note, there are two concepts which
can be expressed best by inheritance (according to the conventional C++
wisdom which I'll parrot to the best of my ability).

The most common notion is "is-a", modeled in C++ by public inheritance.
For example, "class Penguin(Bird)" conceptually represents the notion that a
penguin is a bird and thus could be expected to do anything a bird can do and
respond to any input that other birds would respond to.

The other common notion expressed by inheritance is "is-implemented-by".
For example, "class TCPSocket(File)" conceptually means that a TCPSocket
works exactly like a file, so we'll be stealing his methods directly instead
of writing our own. In C++ this would likely be accomplished through
private inheritance.

Extra credit if you can think of an example that matches protected
inheritance.

Since your example classes "Object" and "Point" actually model neither
"is-a" nor "is-implemented-by", you may take as a first approximation that
inheritance isn't going to work for you here.


hoping-some-of-this-helps-ly y'rs,
+Mitchell

(Dang, now you've got me hyphenating!)
building embedded classes as in C/C++ [ In reply to ]
Andy Beall <beall@psych.ucsb.edu> writes:
> I'd like to build an embedded structure (Python class) much like I do in
> C if possible. When I do the following, multiple instances of my final
> class overwrite each others sub-class values!

You did not pay attention, however; you set _class_wide_ variables, global
to all instances (pos, ang). Thus, the behavior was to be expected.

Try this instead:

class Object:
def __init__(self):
self.pos = Point()
self.ang = Point()

>
> -------------------------------------------------------------------------
> class Point:
> x = 0
> y = 0
> z = 0
>
> class Object:
> pos = Point()
> ang = Point()
>
>
> obj1 = Object()
> obj2 = Object()
>
> obj1.ang.x = 123
>
> print obj2.ang.x <<-- AND I FIND IT CONTAINS OBJ1's X VALUE
> -------------------------------------------------------------------------
>
>
>
> In C, this would be:
>
> -------------------------------------------------------------------------
> typedef struct Point {
> float x;
> float y;
> float z;
> } Point;
>
> typedef struct Object {
> Point pos;
> Point ang;
> } Object;
>
> Object obj1;
> Object obj2;
>
> obj1.ang.x = 123;
> printf("%f", obj2.ang.x); <<-- AND NOW THE VALUES IN OBJ1 AND OBJ2
> WILL NOT BE RELATED (OBJ2 WILL JUST
> CONTAIN GARGAGE AT THIS POINT).
> -------------------------------------------------------------------------

--

"If you want to travel around the world and be invited to speak at
a lot of different places, just write a Unix operating system."
-- Linus Torvalds
building embedded classes as in C/C++ [ In reply to ]
Python has no member variable declarations.
You create your member variables in a constructor.
Try this (didn't try it, hope there's no typo):

class Point:
def __init__(self):
self.x = 0

class Object:
def __init__(self):
self.pos = Point()
self.ang = Point()
obj1 = Object()
obj2 = Object()

obj1.ang.x = 123

print obj2.ang.x

--
Dirk
Where did you want to go again?
Andy Beall schrieb in Nachricht <37A78579.9856D16@psych.ucsb.edu>...
>Hi,
>
>I'd like to build an embedded structure (Python class) much like I do in
>C if possible. When I do the following, multiple instances of my final
>class overwrite each others sub-class values!
>
>-------------------------------------------------------------------------
>class Point:
> x = 0
> y = 0
> z = 0
>
>class Object:
> pos = Point()
> ang = Point()
>
>
>obj1 = Object()
>obj2 = Object()
>
>obj1.ang.x = 123
>
>print obj2.ang.x <<-- AND I FIND IT CONTAINS OBJ1's X VALUE
>-------------------------------------------------------------------------
>
>
>
>In C, this would be:
>
>-------------------------------------------------------------------------
>typedef struct Point {
> float x;
> float y;
> float z;
>} Point;
>
>typedef struct Object {
> Point pos;
> Point ang;
>} Object;
>
>Object obj1;
>Object obj2;
>
>obj1.ang.x = 123;
>printf("%f", obj2.ang.x); <<-- AND NOW THE VALUES IN OBJ1 AND OBJ2
> WILL NOT BE RELATED (OBJ2 WILL JUST
> CONTAIN GARGAGE AT THIS POINT).
>-------------------------------------------------------------------------
>
>
>I've found that writing something like:
>
>class Object(Point):
> ...
>
>works, but then I don't have a wrapper around the (x, y, z) values
>anymore and I
>don't know how to bring in Point more than once. Is it possible to do
>this in Python. I've looked in the tutorial and Mark Lutz's book to no
>avail.
>
>Thanks,
>Andy Beall
building embedded classes as in C/C++ [ In reply to ]
Yes, thanks for the reply--I now see what I was doing wrong. What
through me off (besides not reading thoroughly enough) was that non-list
and non-class variables are not class wide when declared using the
convention I did. I understand now how to do what I want but why do
simple scalar-like variables work one way and lists and classes
another. I'm definitely missing some subtlety of Python here...

For example,

class Object:
p = 0
pos = Point()
ang = Point()

Here, 'p' does not seem to be class-wide while 'pos' and 'ang' are. Why
the discrepancy?

Thanks for any enlightenment,
Andy-



Markus Stenberg wrote:
>
> Andy Beall <beall@psych.ucsb.edu> writes:
> > I'd like to build an embedded structure (Python class) much like I do in
> > C if possible. When I do the following, multiple instances of my final
> > class overwrite each others sub-class values!
>
> You did not pay attention, however; you set _class_wide_ variables, global
> to all instances (pos, ang). Thus, the behavior was to be expected.
>
> Try this instead:
>
> class Object:
> def __init__(self):
> self.pos = Point()
> self.ang = Point()
>
> >
building embedded classes as in C/C++ [ In reply to ]
Andy Beall writes:
> Here, 'p' does not seem to be class-wide while 'pos' and 'ang' are. Why
> the discrepancy?

Andy,
The 'p' set in the class statement is class-wide. Setting 'p' on an
instance creates a new instance-specific binding for 'p', which is
retrieved on subsequent attribute accesses since it overrides the
class-wide value. If you accessed it as Object.p, the original value
would still be available.
This is a situation where the "binding" and "namespaces" terminology
is pretty important and makes it easier to understand. There really
aren't variables in the C/C++/lots-of-others sense. Sections 9.1 and
9.2 in the tutorial may be worth reviewing here:

http://www.python.org/doc/current/tut/node11.html


-Fred

--
Fred L. Drake, Jr. <fdrake@acm.org>
Corporation for National Research Initiatives
building embedded classes as in C/C++ [ In reply to ]
In article <slrn7qf4g2.3vvqed5.mmorris@finin.morrisland.com>,
Mitchell Morris <mmorris@mindspring.com> wrote:

>Of course it is ... everything is possible in Python, since it is Turing
>complete. On a different philosophical note, there are two concepts which
>can be expressed best by inheritance (according to the conventional C++
>wisdom which I'll parrot to the best of my ability).
>
>The most common notion is "is-a", modeled in C++ by public inheritance.
>For example, "class Penguin(Bird)" conceptually represents the notion that a
>penguin is a bird and thus could be expected to do anything a bird can do and
>respond to any input that other birds would respond to.
>
>The other common notion expressed by inheritance is "is-implemented-by".
>For example, "class TCPSocket(File)" conceptually means that a TCPSocket
>works exactly like a file, so we'll be stealing his methods directly instead
>of writing our own. In C++ this would likely be accomplished through
>private inheritance.
>
>Extra credit if you can think of an example that matches protected
>inheritance.

"Ooh! ooh!" The classic usage is to model "is-implemented-by-for-my-kids-sake"
behavior:

AbstractFoo
^
+-------------+
| |
(protected) (public,virtual)
| |
CommonFooImpl |
^ +
+-private--+OneOfManyDerivedFOos

The derived classes can exploit the AbstractFoo-ness of CommonFooImpl, but
nobody else can.

>
>Since your example classes "Object" and "Point" actually model neither
>"is-a" nor "is-implemented-by", you may take as a first approximation that
>inheritance isn't going to work for you here.
>
>
>hoping-some-of-this-helps-ly y'rs,
>+Mitchell
>
>(Dang, now you've got me hyphenating!)

It's-catching-idn't-it-ly,

Tres.


--
---------------------------------------------------------------
Tres Seaver tseaver@palladion.com 713-523-6582
Palladion Software http://www.palladion.com