2012-12-05 13 views
6

Powiel możliwe:
Private functions/Variables enforcement in pythonPython zestaw statyczna właściwość klasa/dostać

można stworzyć równoważnym do następnej klasy z dwóch właściwości statycznych, jeden tylko do odczytu i drugiej przeczytane -pisz w języku 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; } 
    } 
} 

wiem read-only class properties są możliwe w Pythonie, ale jak ja nie widziałem żadnych przykładów właściwości klasy odczytu w Pythonie. Czy to możliwe? Zasadniczo chcę:

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 

Odpowiedz

14

Myślę, że chcesz użyć wbudowanego property(). http://docs.python.org/2/library/functions.html#property

Podczas gdy zwykle używa się go na instancję, myślę, że możesz go użyć w metaklasy, aby osiągnąć to, co chcesz.

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

To świetnie. To najprostsza odpowiedź, jaką widziałem. – Amal

+0

Kiedy zdefiniowano __metaclasses__defined, w jaki sposób można dodać ciągi dokumentacji do tych właściwości klasy? – Amal

+0

Istnieją dwa sposoby używania 'property()'. Pokazałem i jako dekorator. Formularz dekoratora zachowuje ciągi dokumentów. Sposób, w jaki pokazałem, że doktryna jest czwartym argumentem, podczas gdy trzeci argument jest metodą usuwania dla propery. Ponownie, zapoznaj się z dołączonym linkiem do dokumentacji Pythona. –

Powiązane problemy