2011-09-07 8 views
12

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

मेरे मामले में, सॉफ़्टवेयर का उपयोग वैज्ञानिक सिमुलेशन करने के लिए किया जाता है। लगभग 200 विकल्प हैं जिनमें से अधिकांश में सेन डिफ़ॉल्ट हैं। आम तौर पर उपयोगकर्ता को केवल एक दर्जन या तो निर्दिष्ट करना होता है। मुझे जिस कठिनाई का सामना करना पड़ता है वह है कि मेरा आंतरिक कोड कैसे डिज़ाइन किया जाए। कई वस्तुओं को बनाने की आवश्यकता है जो कई विन्यास विकल्पों पर निर्भर करते हैं। उदाहरण के लिए किसी ऑब्जेक्ट को कई पथों की आवश्यकता हो सकती है (जहां डेटा संग्रहीत किया जाएगा), कुछ विकल्प जिन्हें ऑब्गोरिदम को पारित करने की आवश्यकता होती है, ऑब्जेक्ट कॉल करेंगे, और कुछ विकल्प जो सीधे ऑब्जेक्ट द्वारा उपयोग किए जाते हैं।

इससे वस्तुओं को बनाने के लिए बहुत बड़ी संख्या में तर्क की आवश्यकता होती है। इसके अतिरिक्त, चूंकि मेरा कोडबेस बहुत सक्रिय विकास में है, इसलिए कॉल स्टैक के माध्यम से जाने और इसे एक नए कॉन्फ़िगरेशन विकल्प के साथ पास करने के लिए एक बड़ा दर्द है जहां इसकी आवश्यकता होती है।

उस दर्द को रोकने का एक तरीका वैश्विक कॉन्फ़िगरेशन ऑब्जेक्ट होना है जिसे कोड में कहीं भी आसानी से उपयोग किया जा सकता है। मुझे विशेष रूप से इस दृष्टिकोण को पसंद नहीं है क्योंकि यह उन कार्यों और वर्गों की ओर जाता है जो कोई भी (या केवल एक) तर्क नहीं लेते हैं और यह पाठक के लिए स्पष्ट नहीं है कि कार्य/वर्ग किस डेटा से संबंधित है। यह कोड पुन: उपयोग को रोकता है क्योंकि सभी कोड एक विशाल कॉन्फ़िगरेशन ऑब्जेक्ट पर निर्भर करता है।

किसी को भी मुझे कैसे इस तरह एक कार्यक्रम संरचित किया जाना चाहिए के बारे में कुछ सलाह दे सकते हैं?

class A: 
    def __init__(self, config): 
     self.config = config 

    def foo(self, arg): 
     algo(arg, config) 

उदाहरण पायथन लेकिन मेरे में हैं:

class A: 
    def __init__(self, opt_a, opt_b, ..., opt_z): 
     self.opt_a = opt_a 
     self.opt_b = opt_b 
     ... 
     self.opt_z = opt_z 

    def foo(self, arg): 
     algo(arg, opt_a, opt_e) 

यहाँ वैश्विक config शैली का एक उदाहरण है:

यहाँ मैं विन्यास विकल्प गुजर शैली के लिए क्या मतलब का एक उदाहरण है प्रश्न किसी भी समान प्रोग्रामिंग लैंगेज के लिए खड़ा है।

+0

वैश्विक कॉन्फ़िगरेशन ऑब्जेक्ट एक साथ सभी कोड जोड़ता है। कार्यक्रम को अधिक मॉड्यूलर होना अच्छा लगेगा। मुझे @HYRY द्वारा दिखाया गया समाधान पसंद है। यह दोनों दुनिया के सर्वश्रेष्ठ की तरह लगता है। – qsc

उत्तर

5

matplotlib कई विन्यास विकल्प के साथ एक बड़े पैकेज है। यह सभी डिफ़ॉल्ट पैरामीटर प्रबंधित करने के लिए एक आरसी पैराम्स मॉड्यूल का उपयोग करता है। rcParams एक डिफ़ॉल्ट में सभी डिफ़ॉल्ट पैरामीटर को बचाओ।

हर कार्यों कीवर्ड argurments से विकल्प मिल जाएगा:

उदाहरण के लिए

:

def f(x,y,opt_a=None, opt_b=None): 
    if opt_a is None: opt_a = rcParams['group1.opt_a'] 
2

कुछ डिजाइन पैटर्न में मदद मिलेगी

  • प्रोटोटाइप
  • फैक्टरी और सार फैक्टरी

विन्यास वस्तुओं के साथ इन दो पैटर्न का उपयोग करें। प्रत्येक विधि तब एक कॉन्फ़िगरेशन ऑब्जेक्ट ले जाएगी और इसकी आवश्यकता के लिए उपयोग करेंगी। कॉन्फ़िगर पैरामीटर में लॉजिकल ग्रुपिंग को लागू करने पर विचार करें और इनपुट की संख्या को कम करने के तरीकों के बारे में सोचें।

छद्म कोड

// Consider we can run three different kinds of Simulations. sim1, sim2, sim3 

ConfigFactory configFactory = new ConfigFactory("/path/to/option/file"); 
.... 
Simulation1 sim1; 
Simulation2 sim2; 
Simulation3 sim3; 

sim1.run(configFactory.ConfigForSim1()); 
sim2.run(configFactory.ConfigForSim2()); 
sim3.run(configFactory.ConfigForSim3()); 

प्रत्येक कारखाने विधि यह एक प्रोटोटाइप वस्तु से एक विन्यास (कि "समझदार" चूक के सभी है) और विकल्प फ़ाइल बना सकता है के अंदर सिर्फ चीजें हैं जो से अलग हैं हो जाता है चूक। यह वही इन चूक रहे हैं पर स्पष्ट प्रलेखन और जब एक व्यक्ति (या अन्य प्रोग्राम) उन्हें बदल सकते हैं के साथ रखा जाएगा।

** संपादित करें: ** भी विचार है कि प्रत्येक config कारखाना द्वारा दिया समग्र config का एक सबसेट है।

2

या तो config पार्स वर्ग के आसपास दर्रा, या एक वर्ग है कि यह लपेटता है और समझदारी से अनुरोध किया विकल्पों की खींचती लिखें।

पायथन की मानक लाइब्रेरी configparser मैपिंग प्रोटोकॉल का उपयोग करके आईएनआई स्टाइल कॉन्फ़िगरेशन फ़ाइल के अनुभागों और विकल्पों का खुलासा करता है, और इसलिए आप सीधे अपने विकल्पों को पुनर्प्राप्त कर सकते हैं जैसे कि यह एक शब्दकोश था।

myconf = configparser.ConfigParser() 
myconf.read('myconf.ini') 
what_to_do = myconf['section']['option'] 

आप स्पष्ट रूप से विकल्प विशेषता अंकन का उपयोग प्रदान करने के लिए चाहते हैं, एक वर्ग है कि __getattr__ ओवरराइड करता है बनाने के लिए:

class MyConf: 
    def __init__(self, path): 
     self._parser = configparser.ConfigParser() 
     self._parser.read('myconf.ini') 
    def __getattr__(self, option): 
     return self._parser[{'what_to_do': 'section'}[option]][option] 

myconf = MyConf() 
what_to_do = myconf.what_to_do 
0

अपने नाम स्थान के लिए एक मॉड्यूल लोड पैरामीटर है, तो यह आयात और प्रयोग भी आप चाहते हैं।
संबंधित प्रश्न here

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