2011-04-23 15 views
6

मैं वर्तमान में पुस्तकालय से एक वर्ग की संपत्ति को अधिक बहुमुखी बनाने के लिए पैच कर रहा हूं।संपत्ति क्यों है। केवल पढ़ने योग्य विशेषता प्राप्त करें?

मैं निम्नलिखित कोड है जो ठीक काम करता है का उपयोग करते हुए इस कर रहा हूँ:

_orig_is_xhr = BaseRequest.is_xhr.fget 
_orig_is_xhr_doc = BaseRequest.is_xhr.__doc__ 
BaseRequest.is_xhr = property(lambda self: _orig_is_xhr(self) or 
    '_iframe-xhr' in request.form, doc=_orig_is_xhr_doc) 

हालांकि, यह बहुत अच्छा होगा अगर मैं बस गेटर समारोह इतना docstring संरक्षित है के ऊपर लिख सकता है:

_orig_is_xhr = BaseRequest.is_xhr.fget 
BaseRequest.is_xhr.fget = lambda self: (_orig_is_xhr(self) or 
    '_iframe-xhr' in request.form) 

यह काम नहीं करता है क्योंकि property.fget केवल पढ़ने योग्य विशेषता है (TypeError: readonly attribute इसे असाइन करने का प्रयास करते समय)। मुझे उत्सुकता है कि इसके लिए कोई विशेष कारण है या यह पाइथन डेवलपर्स ने सोचा है कि इसे किसी नए के साथ बदलने के बिना इसे बनाने के बाद किसी संपत्ति को संशोधित करने का कोई मतलब नहीं है।

उत्तर

6

आप शायद सही हैं, कि यह केवल उन गुणों को पढ़ने के लिए एक सम्मेलन है, जिसे संपत्ति "सभी या कुछ भी नहीं" बनाने के लिए चुना गया है। ऐसा लगता है कि यह कुछ और "पायथनिक" होगा, ताकि इन तथ्यों के बाद इन्हें असाइन किया जा सके, लेकिन Python 2.2 release notes (जब गुण पेश किए गए थे) में तर्क नहीं मिला।

Objects/descrobject.c में संपत्ति के सदस्य विशेषताओं के रूप में केवल पढ़ने के लिए परिभाषित कर रहे हैं:

static PyMemberDef property_members[] = { 
     {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, 
     {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY}, 
     {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY}, 
     {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), READONLY}, 
     {0} 
    }; 
एक तरफ

: यदि आप 0 साथ READONLY की जगह और संकलन, बस इतना ही यह fget, fset, .. आवंटित करने के लिए अनुमति देने के लिए ले जाता है:

class Test(object): 
    def __init__(self): 
     self.flag = True 
    prop = property(lambda self: self.flag) 

obj = Test() 
print obj.prop 
Test.prop.fget = lambda self: not self.flag 
print obj.prop 

आउटपुट:

True 
False 
+0

हे, अच्छा - मैं अजगर हैक करने नहीं जा रहा हूँ स्रोत हालांकि: पी – ThiefMaster

+2

बेशक :-) मैं बस यह इंगित कर रहा था कि केवल पढ़ने-पढ़ने के पीछे कुछ और विदेशी नहीं है। – samplebias

+1

उत्परिवर्तनीय गुण अनजाने दुष्प्रभावों के लिए कुछ डरावने अवसर पैदा करेंगे। 'Thread.ident.fget = Thread.daemon.fget' कोई भी? – ncoghlan

0

एक निष्क्रिय खोल में एनाकोंडा 2.3.0 (अजगर 3.4.3) के साथ परीक्षण किया

>>> p = property() 
>>> p.fget 
>>> p.__init__(lambda obj: None) 
>>> p.fget 
<function <lambda> at 0x0121FF18> 
>>> p.fget = lambda obj: None 
Tracebabk (most recent call last): 
    File "<pyshell#19>", line 1, in <module> 
    p.fget = lambda obj: None 
AttributeError: readonly attribute 
>>> 

मेरे लिए इतना केवल पढ़ने के लिए नहीं लगता है;)

संबंधित मुद्दे