Python: access class property from string [duplicate]

I have a class like the following:

class User:
    def __init__(self):
        self.data = []
        self.other_data = []

    def doSomething(self, source):
        // if source = 'other_data' how to access self.other_data

I want to pass a string for the source variable in doSomething and access the class member of the same name.

I have tried getattr which only works on functions (from what I can tell) as well as having User extend dict and using self.__getitem__, but that doesn't work either. What is the best way to do this?


Solution 1:

x = getattr(self, source) will work just perfectly if source names ANY attribute of self, including the other_data in your example.

Solution 2:

A picture's worth a thousand words:

>>> class c:
        pass
o = c()
>>> setattr(o, "foo", "bar")
>>> o.foo
'bar'
>>> getattr(o, "foo")
'bar'

Solution 3:

  • getattr(x, 'y') is equivalent to x.y
  • setattr(x, 'y', v) is equivalent to x.y = v
  • delattr(x, 'y') is equivalent to del x.y

Solution 4:

Extending Alex's answer slightly:

class User:
    def __init__(self):
        self.data = [1,2,3]
        self.other_data = [4,5,6]
    def doSomething(self, source):
        dataSource = getattr(self,source)
        return dataSource

A = User()
print A.doSomething("data")
print A.doSomething("other_data")

will yield:

[1, 2, 3]
[4, 5, 6]

However, personally I don't think that's great style - getattr will let you access any attribute of the instance, including things like the doSomething method itself, or even the __dict__ of the instance. I would suggest that instead you implement a dictionary of data sources, like so:

class User:
    def __init__(self):

        self.data_sources = {
            "data": [1,2,3],
            "other_data":[4,5,6],
        }

    def doSomething(self, source):
        dataSource = self.data_sources[source]
        return dataSource

A = User()

print A.doSomething("data")
print A.doSomething("other_data")

again yielding:

[1, 2, 3]
[4, 5, 6]