pythonmatlabiterationpython-classmatlab-struct

How to access attributes of a Python class as one would access fields of a Matlab structure in an iterative context


In Matlab, let's consider a structure "structure" and a list of fields "list_of_fields".

structure = struct;
list_of_fields = ["a","b","d"]; % Some specific fields of the structure and not all of them
for field = list_of_field
    structure.(field) = 0;
end

I would like to do the same in Python with the attribute of a class: instead of writing:

class Example
    def __init__(self) :
        self.a = 0
        self.b = 0
        self.d = 0

My goal would be to write a loop that iterates over the specific attribute a, b and d (and no other attribute). How do you achieve that in Python ?

Up to now, I accessed all attribute as in the Python example aforementioned.


Solution

  • As I mentioned what you are trying to do is a very bad idea imho... But if you really want it you can define __getitem__ method and return value if it's in let's say set of values of your interest and raise StopIteration otherwise. This will allow to loop over those attributes using for loop and it won't return neither methods nor other attributes of that object.

    class Example:
        def __init__(self):
            self.a = 0
            self.b = 1
            self.c = 2
            self.other_stuff = [1,None,False]
            self.stuff = {"a":2,"b":3,"c":87}
    
    
        def __getitem__(self, index):
            key = list(self.__dict__.keys())[index]
            if key in {"a", "b", "c"}:
                return self.__dict__[key]
            else:
                raise StopIteration()
    
        def foo(self):pass
    
    e = Example()
    
    for item in e:
        print(f"{item=}")
    
    print(e.__dict__) 
    

    Side notes and why you should NOT do that:

    To see what I mean just change the order and define Example like this and again see the output of e.__dict__:

    class Example:
        def __init__(self):
            self.stuff = {"a":2,"b":3,"c":87}
            self.a = 0
            self.b = 1
            self.c = 2
            self.other_stuff = [1,None,False]
    ...
    ...
    print(e.__dict__) 
    

    The code won't work anymore with that change