This code produces a different output in Python 2
and Python 3
.
class Descriptor(object):
def __get__(self, instance, owner):
print('read')
return 1
def __set__(self, instance, value):
print('write')
def __delete__(self, instance):
print('del')
class C():
a = Descriptor()
c = C()
c.a
c.a = 3
del c.a
c.a
print('finished')
The output for Python 2 is:
read
read
finished
For Python 3 it is:
read
write
del
read
finished
Why is this working this way? How are Python 2
descriptors different from Python 3
descriptors?
This makes also no sense, because http://docs.python.org/release/3.0.1/reference/datamodel.html#invoking-descriptors clearly describes exactly the same as http://docs.python.org/reference/datamodel.html#invoking-descriptors
(These are the documentations for Python 2.7
and Python 3.0
.)
Edit: As Ned Deily accurately points out in the comments, the reason this happens is your class C
is an old-style class on Python 2, since you haven't specified object
or another new-style class as its base class.
Because on Python 2, you're creating a new instance attribute c.a
when you do c.a = 3
which hides the descriptor object located at C.a
.
c = C()
c.a
c.a = 3
print c.__dict__['a']
print C.__dict__['a']
del c.a
c.a
gives:
read
3
<__main__.Descriptor object at 0x04625570>
read
finished
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With