Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python descriptors not working in Python 2.7

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.)

like image 830
Dave Halter Avatar asked Jun 12 '12 23:06

Dave Halter


1 Answers

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
like image 178
agf Avatar answered Sep 20 '22 21:09

agf