Search code examples
pythonmethodsgetattributespython-datamodel

How to implement the __getitem__ dunder method in python to get attribute values?


I have the following code:

class Personne:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __getitem__(self, *args):
        keys = list(*args)
        return [self.__dict__[key] for key in keys]


if __name__ == '__main__':
    p = Personne('A', 20)
    # age = p['age']
    # print(age)
    # name = p['name']
    # print(name)
    name, age = p['name', 'age']
    print(name, age)

The uncommented part works fine, but the there is a problem in the commented code. How can i achieve the desired behaviour, which is to get attribute values based on arguments (can be one or many) passed to the getitem method.

Thanks.


Solution

  • The problem with passing passing only one string is in that when you call p['age'], the type of *args is a string and therefore list(*args) becomes ['a', 'g', 'e']. When you pass both 'age' and 'name', the *args is interpreted as a tuple and you get the appropriate result. One way to handle this issue could be to check the type of the *args parameter in the getitem(self, *args) method. The following modification would solve the issue you are facing (Python 3), though you might want to clean it a bit.

    class Personne:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __getitem__(self, *args):
            if isinstance(*args, str):
                return self.__dict__[str(*args)]
            keys = list(*args)
            return [self.__dict__[key] for key in keys]
    
    
    if __name__ == '__main__':
        p = Personne('A', 20)
        age = p['age']
        print(age)
        name = p['name']
        print(name)
        name, age = p['name', 'age']
        print(name, age)
        
        
    CONSOLE OUTPUT : 
    
    20
    A
    A 20