c to python

Steven Taschuk staschuk at telusplanet.net
Mon May 26 16:17:41 EDT 2003


Quoth Jimmy verma:
  [...]
> struct ab
> {
>         int a;
>         int b;
>         int *c;
>        struct d *d;
> } AB;
  [...]
> How can this kind of structure be translated in python code?

To start with:

    >>> class Foo(object):
    ...     pass
    ... 
    >>> foo = Foo() # create a Foo object
    >>> foo.a       # not assigned yet
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    AttributeError: 'Foo' object has no attribute 'a'
    >>> foo.a = 3
    >>> foo.a
    3

So far so good.  Now for attributes referring to objects, like
your struct d *d above:

    >>> bar = Foo() # another Foo object
    >>> foo.d = bar # make foo.d refer to the same object as bar
    >>> bar.a = 4   # change bar via name 'bar'
    >>> foo.d.a     # view change via name 'foo.d'
    4

Just like you'd expect a pointer to work.  Trying this with ints,
though, will expose the fact that it's not really pointers the way
you think of them in C:

    >>> foo.a = bar.a    # try to make foo.a and bar.a refer to "same" int
    >>> bar.a = 18       # change bar.a
    >>> foo.a            # expect foo.a to be changed
    4                    # darn!

What's going on here is that variables in Python are not spots in
memory, as they are in C; instead they are simply names for
objects.  Assignment with = doesn't copy a value from one spot in
memory to another; it makes the name on the left refer to the
object calculated on the right.  For example 'x = y' means "make
the name 'x' refer to the same object as 'y' currently refers to".

So:

    >>> x = 5    # make 'x' refer to the object 5
    >>> y = x    # make 'y' refer to the object 5
    >>> x = 6    # make 'x' refer to the object 6...
    >>> y        # ...which doesn't change which object 'y' refers to
    5

To get something which works like int * in C, you need a holder
for an integer value.  In C this is simply a variable of type int;
in Python variables are not holders, so you have to make a holder
explicitly.  One simple way is to use a list (which is like a C
array, except it can hold items of any type and can be resized):

    >>> x = [5]     # a new list with one element, 5
    >>> y = x       # make 'y' refer to same list
    >>> x[0] = 6    # so changes to the list via 'x'...
    >>> y[0]        # ...are visible via 'y'
    6

(I don't much like this approach, but it's hard to guess what
would serve your purposes better, since you haven't explained what
you need struct ab for.)

Putting it all together,

    >>> class AB(object):
    ...     def __init__(self, a, b, c, d):
    ...         self.a = a
    ...         self.b = b
    ...         self.c = c
    ...         self.d = d
    ... 
    >>> x = AB(1, 2, [5], None)
    >>> x.d = AB(3, 4, x.c, None)
    >>> x.a, x.b, x.c, x.d
    (1, 2, [5], <__main__.AB object at 0x812ade4>)
    >>> x.d.a, x.d.b, x.d.c, x.d.d
    (3, 4, [5], None)
    >>> x.c[0] = 6
    >>> x.d.c
    [6]

Your next stop should be the Python Tutorial:

    <http://www.python.org/doc/current/tut/tut.html>

-- 
Steven Taschuk                               staschuk at telusplanet.net
"[T]rue greatness is when your name is like ampere, watt, and fourier
 -- when it's spelled with a lower case letter."      -- R.W. Hamming





More information about the Python-list mailing list