2

I am trying to modify an attribute that is defined in a class. For this problem, I had to modify the names of the attributes to include private_ in the beginning. So, if it was previously self.a, it is now self.private_a in self.__dict__. However, it should still work with the methods defined in the class. I have this bump method that increments some of the attributes, and when getattr is implemented, the updated values are added to a new key instead.

For example, if my self.dict is

{'private_a': 1, 'private_b': 2, 'c': 3, 'd': 5} 

and I call bump, I get this

{'private_a': 1, 'private_b': 2, 'c': 4, 'd': 5, 'a': 2, 'b': 3}

What I want is:

{'private_a': 2, 'private_b': 3, 'c': 4, 'd': 5 }

What am i doing wrong?

def bump(self):
    self.a += 1
    self.b += 1
    self.c += 1

def __getattr__(self,name):
    calling = inspect.stack()[1]

    if calling.function in C.__dict__:
        actual = 'private_' + name
        if actual in self.__dict__:
            return self.__dict__[actual]


    if name not in self.__dict__:
        raise NameError
3
  • 1
    suggest you implement __setattr__ and make sure that private_ is always prepended to the attribute's name.__getattr__ isn't used for setting attributes. Commented Apr 27, 2017 at 2:30
  • I should clarify that I already have a setattr method. The point of the assignment and for this particular question is to be able to use getattr to be able to add to modify attributes that don't have private_ in their name Commented Apr 27, 2017 at 2:48
  • When you say self.a += 1, Python will essentially (not literally) do something like self.__setattr__('a', self.__getattr__('a') + 1). I'm not sure how you could modify __getattr__ for modifying attributes, or why anyone would want you to do that.. Commented Apr 27, 2017 at 2:56

1 Answer 1

1

You mean this ?

class A(object):

    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def __getattribute__(self, item):
        if not item.startswith('__'):
            return object.__getattribute__(self, 'private_' + item)
        return object.__getattribute__(self, item)

    def __getitem__(self, item):
        return object.__getattribute__(self, 'private_' + item)

    def __setitem__(self, key, value):
        object.__setattr__(self, 'private_' + key, value)

    def __setattr__(self, key, value):
        object.__setattr__(self, 'private_' + key, value)

The result is:

> a = A(a=1, b=2, c=3)
> a.__dict__
{'private_a': 1, 'private_c': 3, 'private_b': 2}
>a['a']
1

>a['d']= 1
>a.__dict__
{'private_d': 1, 'private_a': 1, 'private_c': 3, 'private_b': 2}
>a['d'] += 1
>a.__dict__
{'private_d': 2, 'private_a': 1, 'private_c': 3, 'private_b': 2}

>a.f = 1
>a.__dict__
{'private_d': 2, 'private_f': 1, 'private_a': 1, 'private_c': 3, 'private_b': 2}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.