BlandCorporation
BlandCorporation

Reputation: 1344

How should an object's attribute be accessed if it could be a list or a single value?

I have an Event object that can has many attributes, some of which are single values and some of which are lists of values.

class Event(object):
    pass

event = Object()
event.b = [10, 20, 30]
event.c = 15

I am trying to access all of the attributes such that I end up with a lot of single values, in a way a bit like this:

print(Variable(event = event, name = "b[0]")
print(Variable(event = event, name = "b[1]")
print(Variable(event = event, name = "b[2]")
print(Variable(event = event, name = "c"   )

In order to do this, I have created a Variable class:

class Variable(object):

    def __init__(
        self,
        name  = None,
        value = None,
        event = None,
        ):

        self._name  = name
        self._value = value
        self._event = event

        if self._value is None:
            # add magic here
            self._value = getattr(self._event, self._name)

    def name(
        self
        ):

        return self._name

    def value(
        self
        ):

        return self._value

I want this variable class to understand that something like "[2]" at the end of the specified name means that the attribute is a list and that its element of index 2 should be accessed and set as the variable instance's single value. What would be a good way to do this?

Note that this is a simplified version of what I'm doing -- in reality I am dealing with millions of events and thousands of attributes and I am trying to minimize the amount of code I have to write (and subsequently change) by making the variable class intelligent.

Upvotes: 0

Views: 39

Answers (1)

Daniel Underwood
Daniel Underwood

Reputation: 2261

I don't know of an elegant way to do it, but you could use the fact that normal variables shouldn't have brackets to separate the index and then write a function that basically wraps getattr with checking for brackets:

# Get a variable, index tuple if the name contains an index
def pair_from_name(name):
    if '[' in name:
        parts = name.split('[')
        var = parts[0]
        index = int(parts[-1].split(']')[0])
        return var, index
    else:
        return None

# Basically getattr, but will process indices
def get_var(name, obj):
    pair = index_from_name(name)
    if pair:
        name, index = pair
        iterable = getattr(obj, name)
        return iterable[index]
    else:
        return getattr(obj, name)

This isn't really meant to handle extreme name cases or errors, but it'll hopefully put you in the right track.

Upvotes: 1

Related Questions