"literal" objects

Francis Avila francisgavila at yahoo.com
Wed Dec 24 10:32:34 CET 2003

Moosebumps wrote in message
>    int a;
>    float b;
>} mystruct;
>mystruct x = { 3, 5.0f };
>mystruct y = { 5, 15.0f };
>These are just "data".  Obviously in python you could just write an init
>function like this:
>x.a = 3;
>x.b = 5;
>y.a = 5;
>y.b = 15;

Obviously?  I have no idea what the above snippet is supposed to correspond
to in Python.

A class is like (using like in a very, very loose sense here) a struct, not
like an instance of a struct.  I'm really streching the C analogy in every
possible way, but that much is at least sorta true.  The equivalent Python
to your C code is:

class mystruct(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

x = mystruct(3, 5.0)
y = mystruct(5, 15.0)

Is this what you consider inelegant?  If it's too over-engineered (!) for
you, use a more basic data type, like a dict (as you suggest later).  Or you
can simply bypass init and assign directly:

x = object()
x.a = 3
x.b = 5.0

But since you *know* the struct's structure, you might as well use __init__
to formalize it.  And you're still executing object's __init__, anyway.

>And that would work fine, but the programmer in me says that that's a
>inelegant way to do it.  Why execute code when all you need is to put data
>in the program?

The programmer in you is optimizing prematurely and/or trying to turn Python
into C. :)

The point of classes are to package data and a set of operations proper to
that data.  C doesn't have classes (although similar concepts can be
emulated with structs and function pointers).  Python uses them liberally.
However, one would rarely have such a bare class that's simply holding two
attributes; it would also implement methods that operated on the data it
held.  If all you want to do are hold two numbers efficiently, use a
list/tuple or somesuch, and access them by index instead of name (if the
name doesn't matter).  Or see below.

>A thought that occured to me is that classes are implemented as
>(correct?).  So you could have a dictionary like this:

No.  Classes are objects.  Dictionaries implement attribute access to
objects (i.e. namespaces).

>x = {'a': 3, 'b': 5}
>y = {'a': 5, 'b': 15}
>This would be the __dict__ attribute of an object I suppose.  But I don't
>see anyway to assign it to a variable so you could access them like x.a and
>y.a.  I don't know if this would be a "nice" way to do it or not.

What you're asking for is a "bunch".  It's a common cookbook recipe:

class Bunch(object):
    def __init__(self, **kwargs):

Use it like x = object() above, except you can preinitialize name/value

x = Bunch(a=3, b=5.0)
print x.a # 3
x.z = 'new attribute'

Be careful not to clobber attribute names (object only has __*__ special
names, so you don't need to worry too much).

The moral of this story is that your question is too abstract.  What your
data structure should look like depends on what purpose it has, how it is
used, and what requirements it must fulfill.  Python can produce *much*
richer data structures than C, what with OO and all, so there are many more
possibilities than simply a C struct.

Further, C is radically different from Python, so it's not healthy to try
and make Python conform to your C expectations.  For one, C is a compiled
language, whereas Python is bytecode interpreted.  In C, struct only exists
to the compiler and to you--it is an entirely logical construct used to make
coding easier; it, variable names, etc, *cease to exist* when they are
turned into code.  This makes C very tight and efficient.  But in Python,
even down to the bytecode, name lookups are done, classes and functions are
*real things*, etc.  This makes Python very powerful and far easier to use,
but you give up speed.  However, you rarely *need* the speed, and there are
always ways of getting alot of it back.

>Question 2:
>If "subfolder" is a folder under "basefolder", and basefolder contains
>"base.py", and subfolder contains "sub.py", how do I import sub.py into
>base.py?  From what I can tell so far it only works if the files are in the
>same directory.  I need to be able to do this without modifying any
>environment variables or anything.  Because the scripts will be run on many
>different machines and I have no way of automatically configuring them.

Any directory which contains a file called __init__.py is a package.  If you
create such a file in subfolder, you can import sub from base.py as

import subfolder.sub as sub
from subfolder import sub

will both put sub into the current namespace.  See the bottom of the page on
the import statement in the Python Language Reference.
Francis Avila

More information about the Python-list mailing list