将属性设置为只读的更短方法

时间:2018-06-29 14:36:32

标签: python class properties readonly readability

我在许多站点上阅读到,如果我想创建一个只读属性,则应该使用property装饰器。

赞:

class MyClass(object):
  def __init__(self):
    self._a = None

  @property
  def a(self):
    return self._a

如果我在一个类中只有1-3个只读属性,我认为这是一个很好的解决方案。但是,如果我可能有10个呢?这将导致多出40行代码,仅将它们全部标记为只读。在我看来,这真的不适合Python,因为Python是一种无需编写大量代码即可完成小工作的语言。

真的没有更短的方法在Python中将属性设置为只读吗?

1 个答案:

答案 0 :(得分:2)

至少,您可以仅将property作为函数来调用,而不是将其用作装饰器。同时,您可以将基础值存储在列表或dict中,而不是存储为单独的属性。

class MyClass(object):
    def __init__(self):
        self._values = [...]

    a = property(lambda self: self._values[0])
    b = property(lambda self: self._values[1])
    # etc

但是,只读属性实际上并不需要将其值存储在实例dict中。只需直接在getter中对值进行硬编码:

class MyClass(object):

    a = property(lambda self: "foo")
    b = property(lambda self: "bar") 

然后将对属性的调用包装到另一个函数中:)

def constant(value):
    def _(self):
        return value
    return property(_)

class MyClass(object):
    a = constant("foo")
    b = constant("bar")

这是一个纯Python的只读属性,它以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)

这可能比将property子类化并覆盖__set____del__来“取消实现”更为简单。但是,我更喜欢围绕常规属性进行包装的想法。