Jackson
Jackson

Reputation: 405

Python 3 Overriding class method with attribute

I have a class with a bunch of properties. I want to override an arbitrary number of them with a dict parsed from a yaml file. I've tried a few approaches inculding __getattributes__ and setting the instance __dict__ with the new variable.

The yaml would look like

property_a: 1
property_b: 2

The first approach I tried with __getattribute__ results in a recursion error because I'm trying to access self.yamlsettings over and over again

import yaml

class Properties(object):
    def __init__(self):
        with open("config/staging/kjh.yaml") as f:
            yamlsettings = yaml.load(f)
            self.yamlsettings = yamlsettings

    def __getattribute__(self, attr):
        try:
            return self.yamlsettings[attr]
        except KeyError:
            return object.__getattribute__(self, attr)

    @property
    def property_a(self):
        return "a"

    @property
    def property_b(self):
        return "b"

    @property
    def property_c(self):
        return "c"

The second approach I tried was setting the instance's dict to the key value pair in the yaml file.

The problem is why I'm trying to access the attribute it calls the property rather than the attribute.

import yaml

class Properties(object):
    def __init__(self):
        with open("config/staging/kjh.yaml") as f:
            yamlsettings = yaml.load(f)
            for k, v in yamlsettings.items():
                self.__dict__[k] = v

    @property
    def property_a(self):
        return "a"

    @property
    def property_b(self):
        return "b"

    @property
    def property_c(self):
        return "c"
prop = Properties()
prop.__dict__
>> {'property_a': 1, 'property_b': 2}

prop.property_a
>> 'a'

Can anyone point me in the right direction? I think I might be able to achieve this through a getter but it seems extremely verbose because I have so many properties.

Thanks!

Upvotes: 0

Views: 69

Answers (1)

N Chauhan
N Chauhan

Reputation: 3515

To avoid the recursion error, use the superclass (object) method to access self.yamlsettings:

...
def __getatttibute__(self, attr):
    try:
        return object.__getattribute__(
            self, 'yamlsettings'
        )[attr]
    except KeyError:
        return object.__getattribute__(self, attr)

Upvotes: 1

Related Questions