5
class My_Class:
    def __init__(self):
        self._x = 0

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, x):
        self._x = x

If I delete the following getter from the code above:

@property
def x(self):
    return self._x

The code stops working. How can I create a setter without a getter?

Matheus Schaly
  • 163
  • 4
  • 21

3 Answers3

6

The property function does not have to be used as a decorator:decorator can be used as a function:

class My_Class:
    def _set_x(self, value):
        self._x = value

    x = property(fset=_set_x)  # now value has only a setter

    del _set_x  # optional: delete the unneeded setter function

instance = My_Class()
instance.x= 8  # the setter works

print(instance._x) # the "private" value

print(instance.x) # raises: AttributeError: unreadable attribute
zvone
  • 18,045
  • 3
  • 49
  • 77
  • why `del _set_value`?? – juanpa.arrivillaga Jun 19 '18 at 19:50
  • 1
    @juanpa.arrivillaga That is the standard cookbook how `property` was used before `@decorator` syntax was introduced. It deletes the method before it even becomes a method. It is optional, as the comment says, if you want not to have `X._set_value` (or `X._set_x` after I modified the variable names in the answer to fit the question). – zvone Jun 19 '18 at 19:53
2
class My_Class:
    def __init__(self):
        self._x = 0

    @property
    def x(self):
        raise RuntimeError('This property has no getter!')

    @x.setter
    def x(self, x):
        self._x = x
nosklo
  • 217,122
  • 57
  • 293
  • 297
0

Here's an alternative answer to what I already offered: make your own write-only descriptor.

class WriteOnly:
    def __init__(self, private_name):
        self.private_name = private_name

    def __set__(self, obj, value):
        obj.__dict__[self.private_name] = value

    def __get__(self, obj, type=None):
        raise AttributeError('unreadable attribute')


class My_Class:
    x = WriteOnly('_x')

instance = My_Class()
instance.x = 8  # the setter works

print(instance._x) # the "private" value

print(instance.x) # raises: AttributeError: unreadable attribute
zvone
  • 18,045
  • 3
  • 49
  • 77