Reputation: 99526
>>> class Const(object): # an overriding descriptor, see later
... def __init__(self, value):
... self.value = value
... def __set__(self, value):
... self.value = value
... def __get__(self, *_): # always return the constant value
... return self.value
...
>>>
>>> class X(object):
... c = Const(23)
...
>>> x=X()
>>> print(x.c) # prints: 23
23
>>> x.c = 42
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __set__() takes 2 positional arguments but 3 were given
What does
TypeError: __set__()
takes 2 positional arguments but 3 were given`
means?
Is __set__()
a method belonging to the descriptor type Const
?
What is __set__()
's signature?
Thanks.
Upvotes: -2
Views: 307
Reputation: 226624
The signature for _set_ is documented here:
object._set_(self, instance, value) Called to set the attribute on an instance instance of the owner class to a new value, value.
The TypeError is tell you that the instance parameter is missing, it should be def __set__(self, instance, value): ...
.
Here's one approach to making the Constant class work correctly:
class Const(object):
def __init__(self, value):
object.__setattr__(self, '_value', value)
def __set__(self, inst, value):
raise TypeError('Cannot assign to a constant')
def __get__(self, inst, cls=None):
return self._value
class X(object):
c = Const(23)
Trying it out in an interactive session gives:
>>> x = X()
>>> print(x.c)
23
>>> x.c = 42
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
x.c = 42
File "/Users/raymond/Documents/try_forth/tmp.py", line 5, in __set__
raise TypeError('Cannot assign to a constant')
TypeError: Cannot assign to a constant
Upvotes: 3