2

I am trying to learn about static variables in python. According to this answer this piece of code should make i unique for all the objects of class Test

The code:

>>> class Test(object):
...     _i = 3
...     @property
...     def i(self):
...             return self._i
...     @i.setter
...     def i(self,val):
...             self._i = val
... 
>>> 
>>> x1 =  Test()
>>> x1.i
3
>>> x2 = Test()
>>> x2.i
3
>>> x1.i = 10
>>> x1.i
10
>>> x2.i
3

But as you can see object x1.i is not equal to x2.i.
I tried to do this in both python 2.7 and 3.4 but the result is same. I think my understanding about this concept is wrong.

Could somebody please explain this to me or guide me to a resource.

6
  • 1
    They are unique as you expected in your second sentence. What exactly is your question? Commented Jun 1, 2016 at 8:33
  • 3
    That linked answer has it wrong. self._i = val will assign to a local to that instance attribute _i (which then shadows the class attr), not the class attribute. Commented Jun 1, 2016 at 8:35
  • You should take a look at this Commented Jun 1, 2016 at 8:36
  • @Selcuk in the linked answer it mentions that x1.i is equal to x2.i, which does not happen when I tried to do the same. my question is if I am wrong or the mentioned answer is misleading. Commented Jun 1, 2016 at 8:41
  • @IljaEverilä That's what confused me. Thanks. Commented Jun 1, 2016 at 8:43

2 Answers 2

1

As noted, the linked answer gets it wrong.

class Test(object):
    i = 0


t = Test()
t.i = 4
print t.i
>>> 4
print t.__class__.i
>>> 0

Fields declared on the class are looked up when not found on the instance, but you cannot modify the class directly via self. self.i = 4 always modifies the instance. You can do stuff like

class Test(object):
    _i = 0

    @property
    def i(self):
        return self._i

    @i.setter
    def i(self, value):
        Test._i = value

But duplicating the class name all over the place does not seem a good idea and self.__class__ does not play too well with inheritance. This also completely hides the fact that i was initially a class variable which may or may not be a good idea, either.

Sign up to request clarification or add additional context in comments.

2 Comments

I'm not sure what you mean by "Fields declared on the class are copied to self's dictionary", but it doesn't sound right. i is not in the instance dict until you set it explicitly on t; rather, when Python resolves the name it falls back to the class-level attribute if it is not found at instance level.
@DanielRoseman Hmm. It seems I fell for dir()'s magic, here (it shows i). Corrected.
0
class Test(object):

    _i = 3

    @property
    def i(self):
        return self._i

    @i.setter
    def i(self,val):
        self._i = val

if __name__ == '__main__':

    x1 =  Test()
    x2 = Test()

    x1.i = 10
    print(x1.__dict__)
    print(Test.__dict__)

{'_i': 10}
{'i': <property object at 0x02551180>, '__weakref__': <attribute '__weakref__' of 'Test' objects>, '_i': 3, '__module__': '__main__', '__doc__': None, '__dict__': <attribute '__dict__' of 'Test' objects>}

x1.i = 10 create values object

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.