Search code examples
pythonpython-3.xpython-3.8python-class

python override dot syntax functionality in a class method


is this possible? I want to assign a value to a custom dictionary using <class_name>.<attribute_name> syntax.

here's an example:

class Foo:
    def __init__(self):
        self.__values__ = {}
    def add_a_value_using_dot_syntax(self, index, value): # what should this be?
        self.__values__[index] = value

bar = Foo()
bar.baz = 'hello'

print(bar.baz) # hello
print(bar.__values__) # {'baz': 'hello'}

I know that this can be done with bracket syntax by overriding __setitem__ but it doesn't seem to work for dot syntax..

Thanks


Solution

  • You'd need to override __getattr__ and __setattr__, but since these are fundamental to how the class works, you'd need some extra logic, and there's an enormous minefield of potentially undefined behavior. I think you'd want

    class Foo:
        def __init__(self):
            self.__values__ = {}
            super().__init__()
    
        def __setattr__(self, name, value):
            if name == '__values__':
                self.__dict__['__values__'] = value
                return
            try:
                self.__getattr__(name)
            except AttributeError:
                self.__values__[name] = value
            return super().__setattr__(name, value)
    
        def __getattr__(self, name):
            if name == '__values__':
                return self.__dict__['values']
            try:
                return super().__getattr__(name)
            except AttributeError:
                try:
                    return self.__values__[name]
                except KeyError:
                    raise AttributeError
    

    This is extremely evil/cursed, and should never be done.