[Tutor] Re: c to python

Jimmy verma jim_938@hotmail.com
Thu May 29 04:34:02 2003


What if we have a statement like

#define ABC 0x0001            in my c struct.

I m following like this in python.

class AB:
      def __init__(self):
                self.a = None
                self.b = None
                #statement here ?

Thanks a lot.

Regards.




At 23:04 2003-05-26 +0530, Jimmy verma wrote:
    I have a structure in c like this

struct ab
{
       int a;
       int b;
       int *c;
      struct d *d;
} AB;


And i am using it in my program like

void XYZ(int a , AB *b)


How can this kind of structure be translated in python code?

It's  common to use a tuple in situations where a struct
would be used in C.

B1 = (a, b, c, d)

XYZ(A, B1)

The main difference is that you the access stuff in the data
structure by position, not by name.

def XYZ(A, B):
    a, b, c, d = B

or

def XYZ(A, B):
    a = B[0]
    b = B[1]
    c = B[2]
    d = B[3]

If you want to be able to change your "struct" after you create it,
but feel ok with positional access instead of access by name, you
use a list instead of a tuple.

B2 = [0, 0, [], None]

B2[0] = 4
B2[1] = 2
B2[2].extend([1,2,3,4,5])
B2[3] = B1

A simple way to get access by name instead is to use a dctionary
instead.

B3 = {'a': 0, 'b': 0, 'c': [], 'd': None}

Fourth, and most similar to C/C++ is to use a class. After all,
a struct in C++ is simply a class where attributes are public
by default. (As in Python.)

Due to the dynamic nature of Python, a class that is just for
data storage can be made extremely simple.

class N:
    pass

B4 = N()
B4.a = 42
B4.b = 6 * 8
B4.c = [1,2,3]
B4.d = B3

If you want a little bit more convenience, you might do something
like:

class AB:
    def __init__(self, a=0, b=0, c=[], d=None):
        self.a = a
        self.b = b
        self.c = c
        self.d = d

None of the solutions above have any kind of typechecking whatsoever.
This is fairly typical in Python programs. Don't make any restrictions
that you don't really need. The main reason is that a variable in Python
is just a name for an object--any object. In C, a variable is a named
location in memory, and it only fits particular data types. Very often,
a piece of code can be written so that it works equally well for many
different kinds of data, and this is a great strength. For instance:

>>>def topTen(seq):
...     l = list(seq)
...     l.sort()
...     return l[:10]
...
>>>topTen('asldkfjeorijölkföalksjöalkf')
['a', 'a', 'a', 'd', 'e', 'f', 'f', 'f', 'i', 'j']
>>>topTen([1,2,4,32,5,8,8,5,3,3,5,6,7,56,4,3,8])
[1, 2, 3, 3, 3, 4, 4, 5, 5, 5]
>>>topTen([4,3,8])
[3, 4, 8]
>>>topTen((1,2,5,87,9,5,4,3,4.23,3.14159))
[1, 2, 3, 3.1415899999999999, 4, 4.2300000000000004, 5, 5, 9, 87]

If you do want type checking, you can add that.
There are no such things as int* or structs in
Python though, so let's imagine that a and b should
be integers, c should be a list and d should be an
instance of the same class as the one we implement.

As you see below, the type checking in Python is much
more verbose than in C, but on the other hand, the
mechanisms involved are much, much more powerful.

>>>class AB(object):
...     def __init__(self, a=0, b=0, c=[], d=None):
...             self.a = a
...             self.b = b
...             self.c = c
...             self.d = d
...     def get_a(self):
...             return self.__a
...     def set_a(self, a):
...             assert isinstance(a, int)
...             self.__a = a
...     a = property(get_a, set_a, None, '')
...     def get_b(self):
...             return self.__b
...     def set_b(self, b):
...             assert isinstance(b, int)
...             self.__b = b
...     b = property(get_b, set_b, None, '')
...     def get_c(self):
...             return self.__c
...     def set_c(self, c):
...             assert isinstance(c, list)
...             self.__c = c
...     c = property(get_c, set_c, None, '')
...     def get_d(self):
...             return self.__d
...     def set_d(self, d):
...             assert d is None or isinstance(d, self.__class__)
...             self.__d = d
...     d = property(get_d, set_d, None, '')
...
>>>ab = AB()
>>>ab.a
0
>>>ab.b
0
>>>ab.c
[]
>>>ab.d
>>>print ab.d
None
>>>ab2 = AB(42, 1984, [1,2,3],ab)
>>>ab2.d.d
>>>print ab2.d.d
None
>>>print ab2.d
<__main__.AB object at 0x0127AF40>
>>>print ab2.a, ab2.b, ab2.c
42 1984 [1, 2, 3]
>>>ab3=AB('1', 2, [1,1,], ab2)
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
  File "<interactive input>", line 3, in __init__
  File "<interactive input>", line 10, in set_a
AssertionError
>>>


--
Magnus Lycka (It's really Lyck&aring;), magnus@thinkware.se
Thinkware AB, Sweden, www.thinkware.se
I code Python ~ The shortest path from thought to working program


_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

_________________________________________________________________
Reconnect with old pals. Relive the happy times. 
http://www.batchmates.com/msn.asp With just one click.