+ 2

Class or instance - who owns that name?

Let me give a piece of code first. class C: x = 5; def f(self): self.x += 1; c = C() c.f() print(c.x, C.x) My understanding says that an instance will look up a name within itself, and if there's no such name, it will search the class. So x doesn't really belong to c, it belongs to C - it's a class member. If the function said x = 6, I would understand the result: c gets its own x and the class's x will never be looked up. However, x += 1 means (or should mean) that an already existing value is incremented. In a regular situation, if there is no such name in the scope, this would throw an error. Since c looks up C's x, I would understand if the class member would be altered. Instead, an instance x is CREATED! The output: 6 5 What's going on here?

25th Apr 2019, 2:39 PM
HonFu
HonFu - avatar
3 Answers
+ 4
~ swim ~, there should be no instance variable x. It is afaik the mechanism of Python that you can also look up *class variables* with 'self'. If you don't use self, the method will read out into the module's global instead, so you have to use self (or the class name) to get to the class variable. If c has it's own x, the class's x will never be found; if not - as is the case here - x is looked up in the class instead. ImHowever, it still belongs to the class and is read from there! If for example you try to erase x from c with delattr(), you'll get an AttributeError. Do you understand better now why I think this shouldn't work as it does?
25th Apr 2019, 3:36 PM
HonFu
HonFu - avatar
+ 4
~ swim ~, wow, so the reference to self.x really creates an instance copy, the dicts show it. Well, we knew it had to be that way, otherwise my initial example would have made no sense. It still feels unlogical to me, like it shouldn't really happen. 'increment a value that doesn't exist' - only that suddenly it does. I wonder if this can be explained with a general principle or if it's just some ducktypy 'well, += is magicmethoded that way, that's why, duh' sort of thing.
25th Apr 2019, 10:11 PM
HonFu
HonFu - avatar
0
If you didn't call c(f), the instance wouldn't increment to 6 and the output would be 5 5. Because you assign 5 to x in class C, C.x will forever be 5. c.x would have inherited the 5 at c=C() and incremented by 1 at c.f().
28th Apr 2019, 2:56 AM
Brent Grigsby
Brent Grigsby - avatar