2010-05-04 16 views
9

मैंने हाल ही में पाइथन के property built-in की खोज की, जो क्लास विधि गेटर्स और सेटर्स को कक्षा की संपत्ति के रूप में छिपाती है। अब मैं इसे इस तरीके से उपयोग करने का लुत्फ उठा रहा हूं कि मुझे पूरा यकीन है कि अनुचित हैं।निर्मित "संपत्ति" का उपयोग कब करें: सहायक कार्यों और जेनरेटर

property कीवर्ड का उपयोग करना स्पष्ट रूप से सही बात है यदि कक्षा A में _x है, जिसके स्वीकार्य मान आप प्रतिबंधित करना चाहते हैं; यानी, यह getX() और setX() निर्माण को प्रतिस्थापित करेगा जो निर्माण C++ में लिख सकता है।

लेकिन एक समारोह को संपत्ति बनाने के लिए और कहां उचित है? उदाहरण के लिए, यदि आप

class Vertex(object): 
    def __init__(self): 
     self.x = 0.0 
     self.y = 1.0 

class Polygon(object): 
    def __init__(self, list_of_vertices): 
     self.vertices = list_of_vertices 
    def get_vertex_positions(self): 
     return zip(*((v.x,v.y) for v in self.vertices)) 

है यह उचित जोड़ने के लिए

vertex_positions = property(get_vertex_positions) 

है?

क्या कोई जनरेटर संपत्ति की तरह दिखना ठीक है? कल्पना करें कि हमारे कोड में बदलाव का मतलब है कि हम अब Polygon.vertices को उसी तरह संग्रहीत नहीं करते हैं। क्या यह Polygon पर जोड़ना ठीक होगा?

@property 
    def vertices(self): 
     for v in self._new_v_thing: 
      yield v.calculate_equivalent_vertex() 

उत्तर

14
  • जब आपके पास सामान्य विशेषता होती है और प्राप्त करने और/या सेटिंग किसी वर्ग के उपयोगकर्ता के लिए समझ में आता है, तो विशेषता को सीधे बेनकाब करें। कुछ भाषाओं में सार्वजनिक सदस्य अनाथाश्रम का एक बड़ा कारण यह है कि यदि आपको कुछ और जटिल करने की आवश्यकता है तो आपको एपीआई परिवर्तन की आवश्यकता होगी; पायथन में आप बस एक संपत्ति को परिभाषित कर सकते हैं।

  • यदि आप कुछ उपयोग कर रहे हैं तो आपको विशेषता पहुंच के रूप में सार होना चाहिए, संपत्ति का उपयोग करें। यदि आप बाहरी स्थिति (अपनी साजिश या वेबसाइट या कुछ) को परिवर्तन के बारे में जानते हैं या यदि आप कुछ पुस्तकालयों को लपेट रहे हैं जो सदस्यों का सीधे उपयोग करते हैं, तो संपत्तियां जाने का रास्ता हो सकती हैं।

  • यदि कुछ विशेषता नहीं है-y, इसे एक संपत्ति न बनाएं। विधि बनाने में कोई हानि नहीं है, और यह फायदेमंद हो सकता है: यह जो भी करता है वह अधिक स्पष्ट है, यदि आपको आवश्यकता हो तो आप कुछ बाध्य विधि को पार कर सकते हैं, आप एपीआई परिवर्तन के बिना कीवर्ड तर्क जोड़ सकते हैं।

    ऐसी स्थिति की कल्पना करना मुश्किल है जहां मैं एक जनरेटर फ़ंक्शन का उपयोग संपत्ति के रूप में करता हूं। एक सामान्य विशेषता रखने का एकमात्र तरीका जो समान रूप से व्यवहार करेगा, उसे बहुत जटिलता की आवश्यकता होगी, ताकि मामला विशेषता पहुंच की याद दिलाता न हो।

  • आप इंगित करते हैं कि आप कुछ आंतरिक विशेषता _x तक पहुंच प्रतिबंधित करने के लिए property का उपयोग कर सकते हैं। यह सच हो सकता है, लेकिन मन

    • में रखना यदि आप सुरक्षा या कुछ महत्वपूर्ण के लिए स्वच्छ इनपुट जैसे कार्य करने जा रहे हैं, स्पष्ट अंतर्निहित से बेहतर है।जब आप ऐसी चीजों की बात करते हैं तो आप कोड की तरह महसूस नहीं करना चाहते हैं, क्योंकि तब आप कोड में भाग लेंगे जो नहीं करता है।

    • कभी-कभी लोग केवल पढ़ने के लिए विशेषताओं को लागू करने के लिए property का उपयोग करते हैं। आम तौर पर सामान्य विशेषता रखने के लिए बेहतर होता है और महसूस होता है कि आप किसी उपयोगकर्ता को कुछ गूंगा और असमर्थित करने से नहीं रोक सकते हैं।

  • आपको दिलचस्प लग सकते nitpicking:

    • property शब्द नहीं है; यह एक सामान्य नाम है जिसे आप रिबाइंड कर सकते हैं। यह की तरह है property एक वाक्यविन्यास चीज़ या कुछ भी नहीं है: यह एक सामान्य वर्ग है जिसे आप शुद्ध पायथन में स्वयं लागू कर सकते हैं। यह उसी तंत्र का उपयोग करता है जो पाइथन -descriptors में विधियों को काम करता है।

    • आप वर्णन करते हैं कि property "क्लास विधि गेटर्स और सेटर्स को छिपाता है", जो काफी मामला नहीं है। property चीजें केवल सामान्य कार्य हैं, और वास्तव में आपकी कक्षा में परिभाषित नहीं होने की आवश्यकता है; property आपके लिए self पास करेगा। जब तक आप उन्हें ऊपर नहीं देखते हैं, तब तक कार्य वास्तव में विधियां नहीं बनते हैं, जब पाइथन ऑन-द-फ्लाई विधि वस्तुएं बनाता है। कक्षा परिभाषा के दौरान, वे सिर्फ कार्य हैं। जब आपके पास सामान्य विधि होती है तो इसे "इंस्टेंस विधि" कहा जाता है; पायथन में "क्लास विधि" का अर्थ another special thing से संबंधित गुणों की तरह है जो एक विशेषता दिखाई देने पर क्या होता है बदलता है।

2

गुण के उपयोग में एक स्पष्ट सीमा नहीं है: यह किसी भी तर्क स्वीकार नहीं करता है, और यह कर कभी नहीं होगा।

तो आपको यह सुनिश्चित करना होगा कि जिस संपत्ति को आप किसी संपत्ति में बदल रहे हैं, उसे कभी भी फ़ंक्शन में दोबारा नहीं किया जाएगा, उदाहरण के लिए, अतिरिक्त डिफ़ॉल्ट तर्क।

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