मेरे पास कई अलग-अलग छोटे वर्ग हैं जिनमें प्रत्येक फ़ील्ड हैं, उदाहरण के लिए इस:मुझे पायथन कक्षाओं से केवल पढ़ने वाले फ़ील्ड का खुलासा कैसे करना चाहिए?
class Article:
def __init__(self, name, available):
self.name = name
self.available = available
क्या सबसे आसान और/या सबसे मुहावरेदार रास्ता name
क्षेत्र केवल पढ़ने के लिए बनाने के लिए है, ताकि
a = Article("Pineapple", True)
a.name = "Banana" # <-- should not be possible
अब संभव नहीं है क्या है?
यहाँ मैं अब तक क्या माना जाता है:
एक गेटर का उपयोग करें (! ओह)।
class Article: def __init__(self, name, available): self._name = name self.available = available def name(self): return self._name
बदसूरत, गैर pythonic - और बॉयलरप्लेट कोड का एक बहुत कुछ लिखने के लिए (विशेष रूप से अगर मैं एक से अधिक फ़ील्ड है बनाने के लिए केवल पढ़ने के लिए)। हालांकि, यह नौकरी करता है और यह देखना आसान है कि ऐसा क्यों है।
उपयोग
__setattr__
:class Article: def __init__(self, name, available): self.name = name self.available = available def __setattr__(self, name, value): if name == "name": raise Exception("%s property is read-only" % name) self.__dict__[name] = value
फोन करने वाले पक्ष पर सुंदर लग रहा है, काम करने के लिए मुहावरेदार तरह से हो रहा है - लेकिन दुर्भाग्य से मैं केवल एक को पढ़ने के बनाने के लिए केवल कुछ क्षेत्रों के साथ कई वर्गों की है। तो मुझे उन सभी को
__setattr__
कार्यान्वयन जोड़ने की आवश्यकता होगी। या शायद कुछ प्रकार के मिश्रण का उपयोग करें? किसी भी मामले में, मुझे अपने दिमाग को बनाने की आवश्यकता होगी कि क्लाइंट केवल पढ़ने-योग्य फ़ील्ड को मान निर्दिष्ट करने का प्रयास करता है। कुछ अपवाद पैदा करें, मुझे लगता है - लेकिन कौन सा?गुणों (और वैकल्पिक रूप से गेटर्स) को स्वचालित रूप से परिभाषित करने के लिए उपयोगिता फ़ंक्शन का उपयोग करें। यह मूलतः एक ही विचार के रूप में (1) सिवाय इसके कि मैं स्पष्ट रूप ही टिककर खेल नहीं लिखते बल्कि करते हैं
class Article: def __init__(self, name, available): # This function would somehow give a '_name' field to self # and a 'name()' getter to the 'Article' class object (if # necessary); the getter simply returns self._name defineField(self, "name") self.available = available
कुछ है इस बात का नकारात्मक पक्ष यह है कि मैं भी या अगर यह संभव हो सकता है पता नहीं है (है इसे कैसे कार्यान्वित करें) क्योंकि मैं पायथन में रनटाइम कोड पीढ़ी से परिचित नहीं हूं। :-)
अब तक, (2) तथ्य यह है कि मैं अपने सभी वर्गों के लिए __setattr__
परिभाषाओं की आवश्यकता होगी के अलावा मेरे लिए सबसे होनहार प्रतीत होता है। मेरी इच्छा है कि 'एनोटेट' फ़ील्ड का एक तरीका था ताकि यह स्वचालित रूप से हो। क्या किसी के पास एक बेहतर विचार है?
इसके लायक होने के लिए, मैं पायथन 2.6 गाता हूं।
अद्यतन: सभी दिलचस्प प्रतिक्रियाओं के लिए धन्यवाद! अब तक, मेरे पास यह है:
def ro_property(o, name, value):
setattr(o.__class__, name, property(lambda o: o.__dict__["_" + name]))
setattr(o, "_" + name, value)
class Article(object):
def __init__(self, name, available):
ro_property(self, "name", name)
self.available = available
ऐसा लगता है कि यह काफी अच्छी तरह से काम करता है। केवल परिवर्तन मूल वर्ग के लिए आवश्यक हैं
- मैं
object
वारिस की जरूरत है (जो इस तरह के एक बेवकूफ बात वैसे भी नहीं है, मुझे लगता है) - मैं
ro_property(self, "name", name)
कोself._name = name
बदलने की जरूरत है।
यह मेरे लिए काफी साफ दिखता है - क्या कोई इसके साथ नकारात्मक देख सकता है?
आपकी 'ro_property' बहुत जटिल है - या तो स्वेन या क्रिस का जवाब जाने का तरीका है। –
@EthanFurman यह मुश्किल है, लेकिन शायद वह कीमत है जो आपको भुगतान करना है यदि आप मौजूदा कक्षाओं में किए गए परिवर्तनों को कम से कम रखना चाहते हैं? –
मैं वास्तव में याद नहीं कर सकता जब मैंने आखिरकार एक इंस्टेंस की विशेषता (उदाहरण के तरीकों के बाहर से) लिखा था, सिवाय इसके कि बंदर-किसी और के कोड को पैच करते समय। उदाहरण के उदाहरण नहीं हैं लगभग हमेशा अभ्यास में पढ़ने के लिए? इंस्टेंस गुण आमतौर पर '__init__' में सेट होते हैं और बाद में नहीं बदला जाता है, जब तक कि इंस्टेंस पर कोई विधि न कहें। मुझे लगता है कि मैं इस उचित कोडिंग शैली पर विचार करता हूं। –