Considering this code: Run on python 3.6
Bar assigns the value to the descriptor instance
Bat assigns the value to the containing class instance.
Code examples I've seen (and used to my endless frustration) use the Bar example. Such as this site
and from the python docs
As seen from the output using the Bar example two instances of a class can't use the same descriptor.
Or am I missing something?
class DescriptorA(object): value = None def __get__(self, instance, owner): return self.value def __set__(self, instance, value): self.value = value class DescriptorB(object): _value = None def __get__(self, instance, owner): return instance._value def __set__(self, instance, value): instance._value = value class Bar(object): foo = DescriptorA() def __init__(self, foo): self.foo = foo class Bat(object): foo = DescriptorB() def __init__(self, foo): self.foo = foo print('BAR') a = Bar(1) print('a', a.foo) b = Bar(2) print('b', b.foo) print('Checking a') print('a', a.foo) print('BAT') c = Bat(3) print('c', c.foo) d = Bat(4) print('d', d.foo) print('Checking c') print('c', c.foo) outputs
BAR a 1 b 2 Checking a a 2 BAT c 3 d 4 Checking c c 3 UPDATE
Just wanted to add this. In response to the good answers. When not using descriptors, but still using class attributes. We get different behavior. This is why I made the mistake of using DescriptorA Eg.
class Bar(object): foo = None def __init__(self, foo): self.foo = foo class Bat(object): foo = None def __init__(self, foo): self.foo = foo print('BAR') a = Bar(1) print('a', a.foo) b = Bar(2) print('b', b.foo) print('Checking a') print('a', a.foo) print('BAT') c = Bat(3) print('c', c.foo) d = Bat(4) print('d', d.foo) print('Checking c') print('c', c.foo) BAR a 1 b 2 Checking a a 1 BAT c 3 d 4 Checking c c 3 
a.foo == 2afterb = Bar(2)