Reputation: 116
Given the simple example below, a few strange observations are made:
Parameter.__set__
function is never calledself.color = Parameter()
the inspector shows color as being of type ParameterWhy is the descriptor __set__
method not called when color is being assigned to? I'd expect it to be called for both the 'red' and 'blue' assignments.
class Parameter(object):
def __init__(self, value=None):
self.value = value
def __set__(self, instance, value):
print('in __set__')
self.value = value
def __get__(self, instance, owner):
return self.value
def __delete__(self, instance):
pass
class Fruit(object):
def __init__(self):
self.color = Parameter()
class Apple(Fruit):
def __init__(self):
super().__init__()
self.color = 'red'
f = Apple()
f.color = 'blue'
print(f.color)
Upvotes: 1
Views: 244
Reputation: 116
Turns out the answer had nothing to do with inheritance but rather with how descriptors work using the instance dictionary. I found a great article (https://realpython.com/python-descriptors/) that goes over the details of descriptors and showed how to properly design the pattern I was shooting for.
note: this only works with Python 3.6+ due to using the __set_name__()
method.
class Parameter(object):
def __set_name__(self, owner, name):
self.name = name
def __set__(self, instance, value) -> None:
print('in __set__')
instance.__dict__[self.name] = value
def __get__(self, instance, obj_type=None) -> object:
return instance.__dict__.get(self.name) or 0
class Fruit(object):
color = Parameter()
class Apple(Fruit):
def __init__(self):
super().__init__()
self.color = 'red'
f = Apple()
f2 = Apple()
print(f.color)
f.color = 'blue'
print(f.color)
print(f2.color)
Output
in __set__
in __set__
red
in __set__
blue
red
Upvotes: 1