Reputation: 1571
I read on many sites that if I want to create a read-only property, I should use the property
decorator.
Like this:
class MyClass(object):
def __init__(self):
self._a = None
@property
def a(self):
return self._a
I think this is a good solution if I have just 1-3 read-only properties in a class. But what if I have maybe 10 of these? This would result in 40 extra lines of code only to mark all of them as read-only. In my opinion this does not really fit to Python which is meant to be a language where you do not have to write a big bunch of code to do little things.
Is there really no shorter way to make a property read-only in Python?
Upvotes: 0
Views: 258
Reputation: 530960
At the very least, you could just call property
as a function, rather than using it as a decorator. At the same time, you can store the underlying values in a list or dict rather than as separate attributes.
class MyClass(object):
def __init__(self):
self._values = [...]
a = property(lambda self: self._values[0])
b = property(lambda self: self._values[1])
# etc
However, a read-only property doesn't really need to store its value in the instance dict; just hard-code the value directly in the getter:
class MyClass(object):
a = property(lambda self: "foo")
b = property(lambda self: "bar")
And then wrap the call to property in another function :)
def constant(value):
def _(self):
return value
return property(_)
class MyClass(object):
a = constant("foo")
b = constant("bar")
Here's a pure-Python read-only property, modeled after the example shown at https://docs.python.org/3/howto/descriptor.html#properties:
class Constant(object):
def __init__(self, value)
def _(self):
return value
self.fget = _
def __get__(self, obj, objtype=None):
if obj is None:
return self
return self.fget(obj)
This is probably simpler than subclassing property
and overriding __set__
and __del__
to "unimplement" them. But, I like my idea of a wrapper around a regular property better.
Upvotes: 2