How should I expose read-only fields from Python classes?

前端 未结 5 1907
野趣味
野趣味 2020-12-28 13:51

I have many different small classes which have a few fields each, e.g. this:

class Article:
    def __init__(self, name, available):
        self.name = name         


        
5条回答
  •  悲哀的现实
    2020-12-28 14:12

    Based in the Chris answer, but arguably more pythonic:

    def ro_property(field):
        return property(lambda self : self.__dict__[field])
    
    class Article(object):
        name = ro_property('_name')
    
        def __init__(self):
            self._name = "banana"
    

    If trying to modify the property it will raise an AttributeError.

    a = Article()
    print a.name # -> 'banana'
    a.name = 'apple' # -> AttributeError: can't set attribute
    

    UPDATE: About your updated answer, the (little) problem I see is that you are modifying the definition of the property in the class every time you create an instance. And I don't think that is such a good idea. That's why I put the ro_property call outside of the __init__ function

    What about?:

    def ro_property(name):
        def ro_property_decorator(c):
            setattr(c, name, property(lambda o: o.__dict__["_" + name]))
            return c
        return ro_property_decorator
    
    @ro_property('name')
    @ro_property('other')
    class Article(object):
        def __init__(self, name):
            self._name = name
            self._other = "foo"
    
    a = Article("banana")
    print a.name # -> 'banana'
    a.name = 'apple' # -> AttributeError: can't set attribute
    

    Class decorators are fancy!

提交回复
热议问题