2012-12-05 93 views
6

可能重複:
Private functions/Variables enforcement in pythonPython的靜態類屬性集/獲取

可以在一兩個靜態屬性,一個只讀和其他讀創建一個相當於下面的類在Python中寫入?

class Foo 
{ 
    private static string _rdy = "RO"; 
    public static string rd 
    { 
     get { return _rd; } 
    } 

    private static string _rw = "RW"; 
    public static string rw 
    { 
     get { return _rw ; } 
     set { _rw = value; } 
    } 
} 

我知道read-only class properties在Python是可能的,但我怎麼沒見過在Python讀寫類屬性的任何實例。可能嗎?基本上我想:

class classproperty(object): 

    def __init__(self, getter 
      #, setter 
     ): 
     self.getter = getter 
    # self.setter = setter 

    def __get__(self, instance, owner): 
     return self.getter(owner) 

    # Could there be a __set__ here? 
    #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 
    #def __set__(self, instance, owner, value): 
    # self.setter(owner, value) 
    #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

class Foo(object): 

    _ro = "RO" 
    _rw = "RW" 

    @classproperty 
    def ro(cls): 
     return cls._ro 

    # How would you this? 
    #vvvvvvvvvvvvvvvvvvvv 
    #@classproperty.setter 
    #^^^^^^^^^^^^^^^^^^^^ 
    #def rw(cls, value): 
    # cls._rw, value 

# This is what I need 
>>> Foo.ro 
RO 
>>> Foo.ro = 'X'  # Hypothetical Exception 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: class 'Foo' attribute 'ro' is not writable! 
>>> Foo.rw 
RW 
>>> Foo.rw = 'NEW' 
>>> Foo.rw 
NEW 

回答

14

我想你想使用內置的property()http://docs.python.org/2/library/functions.html#property

傳統上,它被用於一個實例,我認爲你可能能夠在元類上使用它來實現你想要的。

class MetaFoo(type): 
    _ro = "RO" 
    _rw = "RW" 

    def _get_ro(self): 
     return self._ro 
    def _get_rw(self): 
     return self._rw 
    def _set_ro(self, value): 
     raise AttributeError("class 'Foo' attribute 'ro' is not writable!") 
    def _set_rw(self, value): 
     self._rw = value 
    ro = property(_get_ro, _set_ro) 
    rw = property(_get_rw, _set_rw) 


class Foo(object): 
    __metaclass__=MetaFoo 


assert Foo.rw == "RW" 
Foo.rw = 'NEW' 
assert Foo.rw == "NEW" 

assert Foo.ro == "RO" 

try: 
    Foo.ro = 'X' 
except Exception as e: 
    assert str(e) == "class 'Foo' attribute 'ro' is not writable!", str(e) 
    assert type(e) == AttributeError 
+1

太好了。這是我見過的最簡單的答案。 – Amal

+0

當有__metaclasses__defined時,如何向這些類屬性添加文檔字符串? – Amal

+0

有兩種使用'property()'的方法。我展示並作爲裝飾者。裝飾器表格保留文檔字符串。我展示的方式是docstring將是第四個參數,而第三個參數是propery的刪除方法。再次看到我包含的python文檔鏈接。 –