2012-12-05 18 views
6

Eventuali duplicati:
Private functions/Variables enforcement in pythonPython proprietà di classe statica set/get

si può creare un equivalente per la seguente classe con due proprietà statiche, una sola lettura e l'altra lettura -write in 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; } 
    } 
} 

so read-only class properties sono possibili in Python, ma come non ho visto alcun esempio di proprietà di classe di lettura-scrittura in Python. È possibile? Fondamentalmente voglio:

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 

risposta

14

Penso che si desidera utilizzare il property() built-in. http://docs.python.org/2/library/functions.html#property

Mentre convenzionalmente, è utilizzato su un'istanza, penso che potresti essere in grado di usarlo su una metaclasse per ottenere ciò che desideri.

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

È grandioso. Questa è la risposta più semplice che ho visto. – Amal

+0

Quando ci sono __metaclasses__defined, come si possono aggiungere stringhe di documentazione a queste proprietà di classe? – Amal

+0

Ci sono due modi per usare 'property()'. L'ho mostrato e come decoratore. La forma decoratrice conserva le stringhe doc. Il modo in cui ho mostrato, la docstring sarebbe il quarto argomento, mentre il terzo argomento è un metodo di cancellazione per la proprietà. Di nuovo, vedi il link alla documentazione di Python che ho incluso. –

Problemi correlati