Earlier quoted context omitted.
>really it's the behaviour of the two cases taken together that can seem inconsistent. Why do you think so? I think that both cases seem consistent, or rather, correct (and therefore this example should not be treated as a common Python mistake), because x is not assigned a value anywhere in class C, and C inherits from A, so it should be clear to anyone knowing OOP and inheritance, that C's x is the same as A's x. (…
What's happening here is that a variable is inheriting its value from the superclass, except for when it doesn't. And when it doesn't, why is that? Well presumably it's because something's been overridden - OO tells us that's how we change the properties that are inherited from the superclass. No wait, that's not it; nothing's been overridden here. All that's happened is we've assigned a value to B.x, and doing so se…
>>> x = 1
>>> def a():
...: print(x)
...:
>>> def b():
...: x = 2
...: print(x)
...:
>>> def c():
...: print(x)
...:
>>> a(), b(), c()
1
2
1
>>> x = 3
>>> a(), b(), c()
3
2
3
I think there is an argument to be made that classes are special and "reaching upwards" into the superclass scope should not occur - a unique copy should be made - but I also think that Python's way of doing it makes enough sense that it is not confusing. The Python devs are at least consistent about having their own way of doing things.