0

I have an object which contains many of it's fields in a numpy array (they are all of type float64). Some of these fields have meaningful names that I would like to use when accessing/writing, but with my current knowledge, I have to access and write like this:

//access:
value = data[0]
//write:
data[0] = value

If I was working in C, I would do something like this:

#define fieldname data[0]
//access:
value = fieldname
//write:
fieldname = value

How can I do something just as clean in python?

EDIT: All of these fields must stay in the numpy array because they get updated by a linear transformation using numpy matrix operations.

EDIT: If I write this method:

def fieldname(self):
  return self.data[0]

my accesses look as desired, but I cannot write back to data in the same way.

//access:
value = self.fieldname

(self was omitted in the code before this because I felt the problem generalized to situations outside of objects.)

This post about overloading the assignment operator might be close to what I want: How to Emulate Assignment Operator Overloading in Python?

SOLUTION: Write __getattr__ and __setattr__ methods that take field names and do the necessary operations on self.data. These will not get called when the field name provided matches the field name of another attribute other than data, and add the functionality of getting stuff from data when names of these special attributes are provided.

2
  • There's not enough context to tell if this would work for you, but look into the NamedTuple class: docs.python.org/2/library/… Commented Jan 14, 2013 at 19:28
  • That's not exactly the same since Python uses references, in this case to an immutable object. If the value of data[0] changed the value of value would not change. It would be whatever it was when first referenced. Commented Jan 14, 2013 at 19:33

2 Answers 2

1

The first method you posted seems clean and sufficiently clear to me. Keep in mind that

value = data[0]

and

data[0] = value

are just syntactic sugar for

value = data.__getitem__(0)

and

data.__setitem__(0, value)

respectively.

If you really, really want to make row access more clear, consider defining constants for different field names.

FIELDNAME1, FIELDNAME2, FIELDNAME3 = range(3)

data[FIELDNAME1] = value

value = data[FIELDNAME2]
Sign up to request clarification or add additional context in comments.

2 Comments

This will work just fine. I have to use field names for access because there are many fields, and it would be hard to remember which number each field was.
@user1123936: The fact is, python just doesn't do pointer arithmetic. You could bend over backwards (figuratively) and write something that works like a pointer, but I'd say that would be much more confusing than accessing values by their key/index as above. The equivalent python idiom is: "There should be one-- and preferably only one --obvious way to do it."
1

If you have descriptive lables for all your fields you can do an enum-like thing. Python doesn't have enums, but there are are numerous ways to do similar things, as discussed here: How can I represent an 'Enum' in Python?

For example, and at the risk of the usual enum debate, you could do something like:

def enum(**enums):
    return type('Enum', (), enums)

Numbers = enum(ONE=1, TWO=2, THREE='three')
print Numbers.ONE
print Numbers.TWO
print Numbers.THREE

3 Comments

If I used this, it seems that my accesses would look like this: value = data[Numbers.FIELDNAME], which isn't as nice as value = data[FIELDNAME], in Joel Cornett's solution.
@user1123936: Actually I prefer this method, as it reduces namespace clutter.
I actually meant data.ONE, data.TWO, etc. But you and Joel Cornett are right. I withdraw my proposal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.