2012-05-01 9 views
15

मैं काफी अजगर करने के लिए नया हूँ और निम्नलिखित वर्ग से संबंधित प्रश्न है:सर्वश्रेष्ठ अभ्यास जब उदाहरण चर को परिभाषित करने

class Configuration: 
    def __init__(self): 
     parser = SafeConfigParser() 
     try: 
      if parser.read(CONFIG_FILE) is None: 
       raise IOError('Cannot open configuration file') 
     except IOError, error: 
      sys.exit(error) 
     else: 
      self.__parser = parser 
      self.fileName = CONFIG_FILE 

    def get_section(self): 
     p = self.__parser 
     result = [] 
     for s in p.sections(): 
      result.append('{0}'.format(s)) 
     return result 

    def get_info(self, config_section): 
     p = self.__parser 
     self.section = config_section 
     self.url = p.get(config_section, 'url') 
     self.imgexpr = p.get(config_section, 'imgexpr') 
     self.imgattr1 = p.get(config_section, 'imgattr1') 
     self.imgattr2 = p.get(config_section, 'imgattr2') 
     self.destination = p.get(config_section, 'destination') 
     self.createzip = p.get(config_section, 'createzip') 
     self.pagesnumber = p.get(config_section, 'pagesnumber') 

यह इस उदाहरण में, एक और समारोह में अधिक उदाहरण चर जोड़ने के लिए get_info ठीक है, या क्या यह कन्स्ट्रक्टर में सभी इंस्टेंस चर को परिभाषित करने का सबसे अच्छा अभ्यास है? अगर मैं जगह पर नए इंस्टेंस वैरिएबल को परिभाषित करता हूं तो क्या यह स्पेगेटी कोड नहीं ले सकता?

संपादित करें: मैं इस कोड का उपयोग एक साधारण छवि स्क्रैपर के साथ कर रहा हूं। get_section के माध्यम से मैं कॉन्फ़िगरेशन फ़ाइल में सभी अनुभागों को वापस कर देता हूं, और उसके बाद उन सभी साइट पर जाने के लिए पुन: प्रयास करता हूं जिनसे मैं छवियों को स्क्रैप कर रहा हूं। प्रत्येक पुनरावृत्ति के लिए मैं कॉन्फ़िगरेशन फ़ाइल में प्रत्येक अनुभाग के लिए कॉन्फ़िगरेशन सेटिंग्स प्राप्त करने के लिए get_section पर कॉल करता हूं। यदि कोई अन्य दृष्टिकोण के साथ आ सकता है तो यह ठीक रहेगा! धन्यवाद!

+0

http://stackoverflow.com/questions/2964230/python-how-should-i-make-instance-variables-available –

+0

'स्व।__parser = कोई भी '' __init __() 'की शुरुआत में सेट नहीं होना चाहिए। इसका कारण यह है कि '__init __()' को पहले से मौजूद * ऑब्जेक्ट का पहला mentod कहा जाता है। यदि पार्सर कॉन्फ़िगरेशन फ़ाइल को पढ़ने में विफल रहता है और अपवाद उठाता है, तो अपवाद कहीं भी कैच हो सकता है (प्रोग्राम समाप्त नहीं किया जा सकता है)। फिर 'कॉन्फ़िगरेशन' वर्ग का ऑब्जेक्ट अभी भी मौजूद है और बाद में 'get_info() '* एट्रिब्यूट एरर का कारण बन जाएगा: कॉन्फ़िगरेशन इंस्टेंस में कोई विशेषता नहीं है' __parser '। – pepr

+0

@pepr क्या आपको पढ़ना चाहिए कि मुझे '__init __। Py' की शुरुआत में' self.__ parser = none' 'जोड़ना चाहिए या क्या आप पार्सर प्रारंभिकरण को __init __। Py' से दूसरे फ़ंक्शन में ले जाने का सुझाव देते हैं? – happygoat

उत्तर

11

से केवल निजी हैं मैं निश्चित रूप से __init__ में सभी उदाहरण चर घोषणा करेंगे। ऐसा करने के लिए जटिलता और संभावित अप्रत्याशित दुष्प्रभावों की वृद्धि हुई है।

पहुंच के मामले में डेविड हॉल से देखने का एक वैकल्पिक बिंदु प्रदान करने के लिए, इस Google Python style guide से है।

Access Control:

If an accessor function would be trivial you should use public variables instead of accessor functions to avoid the extra cost of function calls in Python. When more functionality is added you can use property to keep the syntax consistent

On the other hand, if access is more complex, or the cost of accessing the variable is significant, you should use function calls (following the Naming guidelines) such as get_foo() and set_foo(). If the past behavior allowed access through a property, do not bind the new accessor functions to the property. Any code still attempting to access the variable by the old method should break visibly so they are made aware of the change in complexity.

From PEP8

For simple public data attributes, it is best to expose just the attribute name, without complicated accessor/mutator methods. Keep in mind that Python provides an easy path to future enhancement, should you find that a simple data attribute needs to grow functional behavior. In that case, use properties to hide functional implementation behind simple data attribute access syntax.

Note 1: Properties only work on new-style classes.

Note 2: Try to keep the functional behavior side-effect free, although side-effects such as caching are generally fine.

Note 3: Avoid using properties for computationally expensive operations; the attribute notation makes the caller believe that access is (relatively) cheap.

अजगर जावा/सी # नहीं है, और यह कैसे दिखना चाहिए सकता है और लिखा जा के बारे में बहुत मजबूत विचारों है। यदि आप पाइथन कोडिंग कर रहे हैं तो यह पाइथन की तरह दिखने और महसूस करने के लिए समझ में आता है। अन्य लोग आपके कोड को अधिक आसानी से समझ पाएंगे और आप अन्य पायथन कोड को भी बेहतर समझ पाएंगे।

+1

+1 क्योंकि मैं पाइथन में "हम सभी वयस्क हैं" दर्शन से सहमत हैं। मेरा मुख्य गोमांस कक्षाओं के साथ है जहां आपको कक्षा को वैध स्थिति में रखने के लिए एक निश्चित कार्य को कॉल करना है। –

+0

@ डेविडहॉल पिछले वर्षों में "कक्षाओं को लिखना बंद करो" में वास्तव में दिलचस्पी रखने वाली बात थी, यहां हैकर समाचार धागा है जिसकी कुछ अच्छी चर्चा है। धागे और वीडियो दोनों पढ़ने के लायक हैं। http://news.ycombinator.com/item?id=3717715 –

+0

चीयर्स - मुझे एक नज़र आएगी। जैसा कि आप शायद बता सकते हैं कि मैं एक सी ++/सी # डेवलपर हूं जो कुछ अजगर जानता है इसलिए इस तरह की चर्चाएं पढ़ने के लिए बहुत अच्छी हैं। –

5

मैं get_info() जैसे कार्यों कि एक वैध राज्य में वर्ग डाल करने के लिए आवश्यक हैं होने से अधिक निर्माता के सारे उदाहरण चर की स्थापना एहसान होगा।

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

यदि आप कुछ कॉन्फ़िगरेशन मानों के बारे में चिंतित हैं जिनकी हमेशा आवश्यकता नहीं होती है और गणना करने के लिए महंगी होती है (जो मुझे लगता है कि आपके पास get_info() है, जो स्थगित निष्पादन की अनुमति देता है), तो मैं या तो उस सबसेट को पुनः प्रतिक्रिया देने पर विचार करता हूं एक दूसरी कक्षा में कॉन्फ़िगर करने या properties या मूल्यों को वापस करने वाले कार्यों को शुरू करने के लिए।

गुणों के साथ या स्टाइल फ़ंक्शन प्राप्त करने के लिए आप कक्षा के उपभोक्ताओं को एक परिभाषित इंटरफ़ेस के माध्यम से जाने और encapsulation में सुधार करने के लिए प्रोत्साहित करते हैं।

एक बार जब आप उदाहरण चर आप अपने आप को एक से अधिक बस एक NameError अपवाद फेंक कुछ करने के लिए विकल्प दे के उस कैप्सूलीकरण है - आप शायद get_info() खुद कहते हैं, या एक कस्टम अपवाद फेंक कर सकते हैं।


1. आप अजगर के साथ 100% कैप्सूलीकरण प्रदान नहीं कर सकते क्योंकि निजी उदाहरण चर एक अग्रणी डबल अंडरस्कोर द्वारा सूचित किया जाता सम्मेलन

+0

मुझे सार्वजनिक आवृत्ति चर पर गुणों का लाभ नहीं दिखाई देता है। आप बस सब कुछ एक सार्वजनिक आवृत्ति चर बना सकते हैं, और यदि आपको बाद में इसे मूल्य/सेटिंग प्राप्त करने के अलावा कुछ और करने की आवश्यकता है तो आप इसे हमेशा किसी संपत्ति में परिवर्तित कर सकते हैं। – interjay

+0

अच्छा बिंदु - सार्वजनिक आवृत्ति चर के साथ मेरी मुख्य समस्या उन्हें उन कार्यों में तत्काल कर रही है जैसे get_info कक्षाओं का उपयोग करने के लिए अनावश्यक रूप से कठिन बनाता है। लेकिन आप और एंड्रयू बरेट ने मुझे रचनाओं पर जोर देने के लिए मेरे जवाब को संपादित करने के लिए प्रेरित किया है। –

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