2012-12-05 17 views
6

संभव डुप्लिकेट:
Private functions/Variables enforcement 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; } 
    } 
} 

मैं जानता हूँ कि read-only class properties पायथन में संभव है, लेकिन मैं कैसे पायथन में पढ़ने-लिखने की कक्षा गुणों का कोई उदाहरण नहीं देखा है। क्या यह संभव है? असल में मैं चाहता हूँ:

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

वहाँ 'संपत्ति का उपयोग करने के दो तरीके हैं()'। मैंने दिखाया और एक सजावटी के रूप में। सजावटी फार्म डॉक्टर स्ट्रिंग को संरक्षित करता है। जिस तरह से मैं पता चला है, docstring, चौथा तर्क होगा जबकि तीसरा तर्क प्रॉपर्टी के लिए एक हटाने विधि है। दोबारा, मैंने शामिल पायथन दस्तावेज लिंक देखें। –