Better way to initialize python ctypes structure field
Question: Is there a better way to initialize a ctypes field that is meant to be
static/constant than what I have below?

    
    
    from ctypes import *
    
    class foo(LittleEndianStructure):
      _fields_ = [
        ("signature", c_ulonglong),
        ]
    
      def __init__(self):
          super(LittleEndianStructure,self).__init__()
          self.signature = 0x896489648964
    
    f = foo()
    print hex(f.signature)
    

For example, I was hoping I could do something similar to how you could do it
with a normal python object:

    
    
    class bar:
        signature = 0x896489648964
    
    b = bar()
    print hex(b.signature)
    


Answer: The short answer is no, you can't do this, and shouldn't want to.

* * *

Your normal Python object sample doesn't do what you think. It's not
automatically initializing an instance attribute; it's creating a class
attribute instead.

They work similarly in some cases, but they're not the same thing. For
example, compare:

    
    
    >>> class Foo(object):
    ...     bar=[]
    ...     def __init__(self):
    ...         self.baz=[]
    ... 
    >>> f1 = Foo()
    >>> f2 = Foo()
    >>> f1.bar.append(100)
    >>> f1.baz.append(100)
    >>> f2.bar
    [100]
    >>> f2.baz
    []
    

Here, `f1` and `f2` each initialize their own `baz`, but they do _not_
automatically initialize their own `bar`—they share a single `bar` with every
other instance.

And, more directly relevant to this case:

    
    
    >>> f1.__dict__
    {'baz': [1]}
    

The `bar` class attribute is not part of `f1`'s dictionary.

So, translating the same thing to `ctypes`, your `"signature"` would not be a
member of your structure if you made it a class attribute—that is, it wouldn't
be laid out in memory as part of each instance. Which would defeat the entire
purpose of having it.

* * *

If you know C++, it may help to look at it in C++ terms.

A class attribute, like `bar` above, is sort of* like a static member variable
in C++, while an instance attribute is like a normal instance member variable.

In this C++ code:

    
    
    struct bar {
        static const long signature = 0x896489648964;
    };
    

… each `bar` is actually an empty structure; there's a single `bar::signature`
stored somewhere else in memory. You can reference it through `bar` instances,
but only because the compiler turns `b1.signature` into `bar::signature`.

* * *

* The reason I say "sort of" is that Python class attributes can be overridden by subclasses, while C++ static members can't, they really are just global variables, and they can only be "hidden" by subclasses.

