代码之家  ›  专栏  ›  技术社区  ›  Praind

使属性只读的较短方法

  •  0
  • Praind  · 技术社区  · 8 年前

    我在很多网站上看到,如果我想创建只读属性,我应该使用 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 回复  |  直到 8 年前
        1
  •  2
  •   chepner    8 年前

    至少,你可以打个电话 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)
    

    这可能比子类化更简单 财产 和超越 __set__ __del__ 让他们“无动于衷”。但是,我更喜欢用包装器包装常规属性的想法。

    推荐文章