Home > OS >  How to access class instance attributes indirectly?
How to access class instance attributes indirectly?

Time:03-03

If I have a class instance with some attributes defined, how do I access them indirectly? My first thought was to put them in a dict and then access them with the keywords but that doesn't work as I expect - example below:

class Test:
    def __init__(self):
        self.testval=0
    
test=Test()
testfuncs={'A':test.testval}

print(test.testval)
testfuncs['A']=1
print(test.testval)

This prints '0' and then '0' as I have not modified the class variable, I've just altered the dictionary value to be the integer '1'.

So I want to be able to access and modify the attribute testval. The reason for this is that in a larger program there are some defined class instance variables that I want to assign once and then reuse throughout. Then by just updating the dict they will change everywhere (they are voltage channels that may change as application changes).

CodePudding user response:

Use the getattr() function to get an attribute of an object if you have its name in a variable, and setattr() to set it in similar circumstances.

class Test:
    def __init__(self):
        self.testval = 0

test=Test()
A = "testval"

print(test.testval)
setattr(test, A, 1)
print(test.testval)

You can also define your class to have a __setitem__ method; then you can use dictionary-like syntax to set attributes.

class Test:

    def __init__(self):
        self.testval = 0

   def __setitem__(self, key, value):
        setattr(self, key, value)

test=Test()
A = "testval"

print(test.testval)
test[A] = 1
print(test.testval)

Finally, you could make a class that holds a reference to an object and an attribute name. This is convenient when you want to pass around such references.

class Test:
    def __init__(self):
        self.testval = 0

class IndirectAttribute:

    def __init__(self, obj, attr):
        self.obj = obj
        self.attr = attr

    def set(self, value):
        setattr(self.obj, self.attr, value)

test = Test()
A = IndirectAttribute(test, "testval")

print(test.testval)
A.set(1)
print(test.testval)

CodePudding user response:

You can set the value of the dictionary to be your test object

class Test:
    def __init__(self):
        self.testval = 0


test = Test()
testfuncs = {'A': test}

print(test.testval) # prints 0
testfuncs['A'].testval = 1
print(test.testval) # prints 1
  • Related