Python: why can't descriptors be instance variables?
Asked Answered
C

2

5

Say I define this descriptor:

class MyDescriptor(object):

   def __get__(self, instance, owner):
        return self._value

    def __set__(self, instance, value):
        self._value = value

    def __delete__(self, instance):
        del(self._value)

And I use it in this:

class MyClass1(object):
    value = MyDescriptor()


>>> m1 = MyClass1()
>>> m1.value = 1
>>> m2 = MyClass1()
>>> m2.value = 2
>>> m1.value
2

So value is a class attribute and is shared by all instances.

Now if I define this:

class MyClass2(object)
    value = 1

>>> y1 = MyClass2()
>>> y1.value=1
>>> y2 = MyClass2()
>>> y2.value=2
>>> y1.value
1

In this case value is an instance attribute and is not shared by the instances.

Why is it that when value is a descriptor it can only be a class attribute, but when value is a simple integer it becomes an instance attribute?

Contact answered 10/5, 2011 at 3:20 Comment(0)
M
11

You're ignoring the instance parameter in your implementation of MyDescriptor. That is why it appears to be a class attribute. Perhaps you want something like this:

class MyDescriptor(object):

    def __get__(self, instance, owner):
        return instance._value

    def __set__(self, instance, value):
        instance._value = value

    def __delete__(self, instance):
        del(instance._value)
Mango answered 10/5, 2011 at 3:22 Comment(5)
How would you implement MyDescriptor() to make it behave like an instance variable?Contact
Did you try what I suggested?Mango
It worked. Thanks! My previous comment was made before I saw the updates you made to your answer.Contact
Great! I usually try to get the answer up before going off to test sample code. :)Mango
Continuation: Simple, just operate on the instance :)Odele
F
0

Will not work if you try the code below:

class MyClass1(object):
    value = MyDescriptor()
    value2 = MyDescriptor()

c = MyClass1()
c.value = 'hello'
c.value2 = 'world'

# where c.value also equals to "world"
Freeland answered 12/9, 2012 at 1:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.