7

If I define a simple class

class someClass():
    var = 1

x = someClass()
someClass.var = 2

This will make x.var equal 2. This is confusing to be because normally something akin to this like:

a = 1
b = a
a = 2

will leave b intact as b==1. So why is this not the same with class variables? Where is the difference? Can call all class variables mutable? In a way the class variables work more like assigning a list to a=[1] and doing a[0]=2.

Basically the problem is how is x.var acessing someClass.var it must be something different then is used when two variables are set equal in python. What is happening?

Kuhlambo
  • 371
  • 3
  • 13
  • 2
    now set `x.var = 3` and see what happens to `someClass.var` – juanpa.arrivillaga Jun 15 '17 at 09:18
  • I know but thats not the point – Kuhlambo Jun 15 '17 at 09:19
  • 1
    No, that *is* the point. Essentially, when you do `SomeClass.var` and `someInstance.var` **are not necessarily same thing**. – juanpa.arrivillaga Jun 15 '17 at 09:20
  • not at all this is about the fact that someClass.var = 2 changes x.var and how x.var is bound to the class variable compared to the normal functioning of variables in python – Kuhlambo Jun 15 '17 at 09:21
  • So why does someClass.var = 2 change x.var then? – Kuhlambo Jun 15 '17 at 09:21
  • `someClass.var` **does not** change `x.var`. Sometimes, an instance attribute *shadows* a class-attribute. That is the behavior you are seeing. – juanpa.arrivillaga Jun 15 '17 at 09:21
  • If `x` doesn't have its own `var` property, it uses the classes. When it does, the two become disentangled. – deceze Jun 15 '17 at 09:22
  • try it python2.7 – Kuhlambo Jun 15 '17 at 09:22
  • I've tried it before. Many many times. As an aside, mutability isn't the issue here at all, actually. But ok, try this. `x = SomeClass(); x.var = 'foo'; SomeClass.var = 'bar'`. Did `SomeClass.var` change `x.var`? – juanpa.arrivillaga Jun 15 '17 at 09:23
  • Try `someclass.var = 1`, then `x.var` will be 1, then `x.var = 2`, `someclass.var` will not be 2, then `someclass.var = 3` and `x.var` will still be 2. – C.Fe. Jun 15 '17 at 09:24
  • So again, the issue isn't *mutability*. The issue is *namespaces*. Usually, we think of namespaces as distinct, but in OOP, *instances can have access to their class namespace* – juanpa.arrivillaga Jun 15 '17 at 09:24
  • 1
    A picture is worth a thousand words: https://stackoverflow.com/a/34126204/476 – deceze Jun 15 '17 at 09:28
  • @ C.Fe I know this but still the behavior works like this the other way around which is completely different from what happens if x.var was somehow defined by x.var = someClass.var. I do not see this addressed in the "Static class variables in Python " thread. – Kuhlambo Jun 15 '17 at 09:29
  • @pindakaas what do you mean exactly? `xvar = someClass.var` and then `x.var = 'something else'`, now did `someClass.var` change? – juanpa.arrivillaga Jun 15 '17 at 09:32
  • @pindakaas I was going to post [this](https://gist.github.com/juanarrivillaga/ab85dfcf70feff2d61a7a25175586aef) as an answer before this got targeted as a duplicate. Let me know if it helps clear things up a bit. – juanpa.arrivillaga Jun 15 '17 at 09:35
  • @deceze that's the best dupe target I think – juanpa.arrivillaga Jun 15 '17 at 09:36
  • @ juanpa.arrivillaga I think it does. – Kuhlambo Jun 15 '17 at 09:38
  • I think in the second duplicate "Python: Difference between class and instance attributes" , the quesion is not really a match but the answer certainly is. Thanks for the link – Kuhlambo Jun 15 '17 at 09:40

1 Answers1

3

var is a static class variable of someClass.

When you reach out to get x.var, y.var or some_other_instance.var, you are accessing the same variable, not an instance derived one (as long as you didn't specifically assigned it to the instance as a property).

Uriel
  • 15,579
  • 6
  • 25
  • 46