Reputation: 6527
I have a python class that inherits a priority queue and I also use a descriptor to add an attribute to the class, like this:
from Queue import PriorityQueue
class My_Class(PriorityQueue):
my_attr = NonNegativeInt(0)
def __init__(self):
PriorityQueue.__init__(self)
The descriptor is implemented like this:
class NonNegativeInt(object):
def __init__(self, default):
self.default = default
self.data = WeakKeyDictionary()
def __get__(self, instance, owner):
return self.data.get(instance, self.default)
def __set__(self, instance, value):
if type(value) is not int:
raise TypeError('Value must be an int')
if value < 0:
raise ValueError("Value must be above 0")
self.data[instance] = value
When I call My_Class.my_attr = -1
I don't get any exception. However, if I change My_Class
to this I get the exception fine:
class My_Class(object):
my_attr = NonNegativeInt(0)
def __init__(self):
pass
Interestingly, the first implementation of My_Class
starts with the my_attr
attribute, it just doesn't execute the __set__
function in NonNegativeInt
.
Why is it that changing the superclass changes how my descriptor works? Does it have to do with this line: PriorityQueue.__init__(self)
? How can I give the subclass the behavior I want?
Upvotes: 1
Views: 409
Reputation: 1122162
Descriptors only work on new-style classes (those that directly or indirectly inherit from object
). There is some support for descriptor __get__
methods on old-style classes but this support is limited.
The PriorityQueue
class you are using probably doesn't inherit from object
. If this is the Queue.PriorityQueue
class then that's certainly the case, the classes in that module are all old-style.
The fact that you call PriorityQueue.__init__
has nothing to do with this.
Upvotes: 2