2012-12-05 92 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文档链接。 –