पायथन फ़ाइलों को कॉन्फ़िगरेशन फ़ाइलों के रूप में उपयोग करना एक विचार के लिए कितना बुरा है?


72

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

मैंने देखा है कि अजवाइन विन्यास के लिए वास्तविक पायथन फ़ाइलों का उपयोग करता है। शुरू में मुझे इस पर संदेह था। लेकिन विन्यास के लिए सरल पायथन डेटा संरचनाओं का उपयोग करने का विचार मुझ पर बढ़ने लगा है। कुछ पेशेवरों:

  • डेटा संरचनाएं वैसी ही होंगी जैसा कि मैं सामान्य रूप से कोडिंग करता हूं। इसलिए, मुझे मन के फ्रेम को बदलने की आवश्यकता नहीं है।
  • मेरा IDE (PyCharm) कॉन्फ़िगरेशन और कोड के बीच संबंध को समझता है। Ctrl+ Bविन्यास और कोड के बीच आसानी से कूदना संभव बनाता है।
  • मुझे IMO अनावश्यक सख्त JSON के साथ काम करने की आवश्यकता नहीं है । मैं आपको दोहरे उद्धरण चिह्नों, कोई अनुगामी अल्पविराम और कोई टिप्पणी नहीं देख रहा हूं।
  • मैं जिस एप्लिकेशन पर काम कर रहा हूं, उसमें परीक्षण कॉन्फ़िगरेशन लिख सकता हूं, फिर बिना रूपांतरण और JSON पार्सिंग किए आसानी से उन्हें कॉन्फ़िगरेशन फ़ाइल में पोर्ट कर सकता हूं।
  • यदि आवश्यक हो तो कॉन्फ़िगरेशन फ़ाइल में बहुत सरल स्क्रिप्टिंग करना संभव है। (हालांकि यह बहुत, बहुत सीमित होना चाहिए।)

तो, मेरा सवाल यह है: अगर मैं स्विच करता हूं, तो मैं खुद को पैर में कैसे शूट कर रहा हूं?

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

(मैंने YAML पर विचार किया है , लेकिन इसके बारे में कुछ मुझे परेशान करता है। इसलिए, अब के लिए यह अमेरिकी तालिका से बाहर है।)


39
अकुशल आपकी समस्या नहीं है। दुर्भावनापूर्ण है।
ब्लर

9
"ऑफ द अमेरिकन टेबल" से आपका क्या अभिप्राय है ?
पीटर मोर्टेंसन

24
"तो, अब के लिए यह अमेरिकी तालिका से बाहर है।" === "तो अब के लिए यह है, जैसा कि अमेरिकी का कहना है, टेबल से।"
बिशप

7
यदि आप JSON को नापसंद करते हैं, तो आपको याम्ल की कोशिश करनी चाहिए। मुझे यह बहुत पसंद है। विशेष रूप से जब बड़े तार शामिल होते हैं, YAML waaaay अधिक पठनीय है तो JSON।
ईसाई सॉयर

5
@ अंग्रेजी भाषा में "ऑफ द टेबल" अंग्रेजी में अब विचार का कोई मतलब नहीं है, संसदीय गतियों पर चर्चा के लिए संदर्भ के लिए हाउस ऑफ कॉमन्स के बीच में मेज पर रखा जा रहा है, इसलिए 'चर्चा के लिए सक्षम' (संसदीय रिकॉर्ड 1799) books.google.co.uk/… ), AFAIK अमेरिकी अर्थ समान है, लेकिन मुझे नहीं पता कि आपकी संसद में कोई तालिका है या नहीं।
पीट किर्कम

जवाबों:


92

कॉन्फ़िगरेशन फ़ाइल के स्थान पर स्क्रिप्टिंग भाषा का उपयोग करना पहली नज़र में बहुत अच्छा लगता है: आपके पास उस भाषा की पूरी शक्ति उपलब्ध है और वह बस eval()या importयह कर सकती है। व्यवहार में, कुछ गोत्र हैं:

  • यह एक प्रोग्रामिंग लैंग्वेज है, जिसे सीखने की जरूरत है। कॉन्फ़िगरेशन को संपादित करने के लिए, आपको इस भाषा को पर्याप्त रूप से अच्छी तरह से जानना होगा। कॉन्फ़िगरेशन फ़ाइलों में आमतौर पर एक सरल प्रारूप होता है जो गलत होना अधिक कठिन होता है।

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

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

  • यह एक प्रोग्रामिंग भाषा है, जिसका अर्थ है कि कॉन्फ़िगरेशन कुछ भी कर सकता है जो प्रोग्रामिंग भाषा कर सकती है। तो या तो आप एक सैंडबॉक्स समाधान का उपयोग कर रहे हैं जो भाषा के लचीलेपन की बहुत उपेक्षा करता है, या आप कॉन्फ़िगर लेखक में उच्च विश्वास रख रहे हैं।

कॉन्फ़िगरेशन के लिए स्क्रिप्ट का उपयोग करना संभव है, ठीक है यदि आपके टूल के श्रोता डेवलपर हैं, जैसे कि स्फिंक्स कॉन्फिगरेशन या पाइथन प्रोजेक्ट्स में setup.py। निष्पादन योग्य विन्यास वाले अन्य कार्यक्रम बैश जैसे शेल और संपादक जैसे विम हैं।

कॉन्फ़िगरेशन के लिए प्रोग्रामिंग भाषा का उपयोग करना आवश्यक है यदि कॉन्फ़िगरेशन में कई सशर्त अनुभाग होते हैं, या यदि यह कॉलबैक / प्लगइन्स प्रदान करता है। Eval () के बजाय सीधे स्क्रिप्ट का उपयोग करना - कुछ कॉन्फिग फ़ील्ड को अधिक डीबग करने योग्य बनाता है (स्टैक के निशान और लाइन नंबर के बारे में सोचें!)।

प्रोग्रामिंग भाषा का सीधे उपयोग करना भी एक अच्छा विचार हो सकता है यदि आपका कॉन्फिगर इतना दोहराव वाला हो कि आप कॉन्फिगरेशन को ऑटोजेनरेट करने के लिए स्क्रिप्ट लिख रहे हों। लेकिन शायद कॉन्फ़िगरेशन के लिए एक बेहतर डेटा मॉडल ऐसे स्पष्ट कॉन्फ़िगरेशन की आवश्यकता को दूर कर सकता है? उदाहरण के लिए, यह मददगार हो सकता है अगर कॉन्फिग फाइल में प्लेसहोल्डर हो सकते हैं जिन्हें आप बाद में विस्तारित करते हैं। एक अन्य विशेषता जो कभी-कभी देखी जाती है वह है विभिन्न कॉन्फिडेंस वाली मल्टीपल कॉन्फिडेंस फाइल्स जो एक-दूसरे को ओवरराइड कर सकती हैं, हालांकि यह स्वयं की कुछ समस्याओं का परिचय देती है।

अधिकांश मामलों में, INI फाइलें, जावा संपत्ति फाइलें, या YAML दस्तावेज विन्यास के लिए ज्यादा बेहतर हैं। जटिल डेटा मॉडल के लिए, XML भी लागू हो सकता है। जैसा कि आपने उल्लेख किया है, JSON के कुछ पहलू हैं जो इसे मानव-संपादन योग्य कॉन्फ़िगरेशन फ़ाइल के रूप में अनुपयुक्त बनाते हैं, हालांकि यह एक अच्छा डेटा विनिमय प्रारूप है।


25
कॉन्फ़िगरेशन फ़ाइल स्वरूपों के एक जोड़े हैं जो "गलती से ट्यूरिंग-पूर्ण" हैं, सबसे प्रसिद्ध हैं sendmail.cf। यह इंगित करेगा कि वास्तविक स्क्रिप्टिंग भाषा का उपयोग करना फायदेमंद हो सकता है, क्योंकि वास्तव में ट्यूरिंग-पूर्ण होने के लिए डिज़ाइन किया गया था । हालांकि , ट्यूरिंग-पूर्णता और "टेट्रिस-पूर्णता" दो अलग-अलग चीजें हैं, और जबकि sendmail.cfमनमाने कार्यों की गणना कर सकते हैं, यह आपके नेट पर नहीं भेज सकता है /etc/passwdया आपकी हार्डडिस्क को प्रारूपित नहीं कर सकता है , जिसे पायथन या पर्ल सक्षम कर पाएंगे।
जॉर्ज डब्ल्यू मित्तग

3
@ JörgWMittag ट्यूरिन-पूर्णता नेटवर्क पर चीजें भेजने या हार्ड डिस्क तक पहुंचने में सक्षम होने के लिए सक्षम नहीं है। यही है, ट्यूरिन-पूर्णता के बारे में प्रसंस्करण है I / O के बारे में नहीं। उदाहरण के लिए सीएसएस को ट्यूरिन पूरा माना जाता है, लेकिन यह आपके स्थायी भंडारण के साथ गड़बड़ नहीं करेगा। आपने कहीं और कहा है कि "इदरीस कुल शुद्ध कार्यात्मक भाषा है, इसलिए यह ट्यूरिंग-ट्यूरिंग-कम्प्लीट नहीं है", जिसका पालन नहीं होता है, और जाहिर है कि यह ट्यूरिन पूर्ण है। मुझे यकीन था कि टेस्टिस-पूर्ण के आपके उपयोग का मतलब यह था कि भाषा ट्यूरिन पूर्ण थी, लेकिन पूर्ण I / O करने में सक्षम नहीं थी ... ऐसा लगता है कि आप क्या मतलब नहीं है।
थारोट

6
@ थरोट: "कुल" का मतलब है कि यह हमेशा लौटता है। ट्यूरिंग मशीन एक अनंत लूप का प्रदर्शन कर सकती है, अर्थात इसमें वापस न आने की क्षमता है। एर्गो, इदरीस एक ट्यूरिंग मशीन जो कुछ भी करता है वह नहीं कर सकता है, जिसका अर्थ है कि यह ट्यूरिंग-पूर्ण नहीं है। यह सभी निर्भर प्रकार की भाषाओं के लिए सही है। एक निर्भर-टाइप की गई भाषा का संपूर्ण बिंदु यह है कि आप कार्यक्रमों के बारे में मनमाने ढंग से गुण तय कर सकते हैं, जबकि ट्यूरिंग-पूर्ण भाषा में आप तुच्छ गुणों को भी तय नहीं कर सकते हैं जैसे कि "क्या यह कार्यक्रम रुकता है?" कुल भाषाएं हैं परिभाषा के द्वारा , नहीं ट्यूरिंग-पूर्ण क्योंकि ट्यूरिंग मशीनें आंशिक रहे हैं।
जोर्ग डब्ल्यू मित्तग

10
"ट्यूरिंग-पूर्ण" की परिभाषा "ट्यूरिंग मशीन को लागू कर सकती है" है। "टेट्रिस-पूर्ण" की परिभाषा "टेट्रिस को लागू कर सकती है" है। इस परिभाषा के पूरे बिंदु यह है कि ट्यूरिंग-पूर्णता वास्तविक दुनिया में बस बहुत दिलचस्प नहीं है। ऐसी बहुत सी उपयोगी भाषाएँ हैं जो ट्यूरिंग-पूर्ण नहीं हैं, उदाहरण के लिए HTML, SQL (पूर्व 1999), विभिन्न DSLs, आदि OTOH, ट्यूरिंग-पूर्णता का तात्पर्य केवल यह है कि आप प्राकृतिक संख्याओं पर कार्य की गणना कर सकते हैं, इसका मतलब यह नहीं है। स्क्रीन पर मुद्रण, नेटवर्क तक पहुंच, उपयोगकर्ता, ओएस, पर्यावरण के साथ बातचीत करना, ये सभी महत्वपूर्ण हैं।
जोर्ग डब्ल्यू मित्तग

4
एडविन ब्रैडी ने इस उदाहरण का उपयोग क्यों किया, इसका कारण यह है कि बहुत से लोग सोचते हैं कि ट्यूरिंग-पूर्ण नहीं होने वाली भाषाओं का उपयोग सामान्य प्रयोजन प्रोग्रामिंग के लिए नहीं किया जा सकता है। मैं खुद भी यही सोचता था कि, आखिरकार, कई दिलचस्प कार्यक्रम अनिवार्य रूप से अंतहीन लूप हैं जिन्हें हम रोकना नहीं चाहते हैं , जैसे कि सर्वर, ऑपरेटिंग सिस्टम, एक जीयूआई में इवेंट लूप, गेम लूप। बहुत सारे प्रोग्राम अनंत डेटा की प्रक्रिया करते हैं, उदाहरण के लिए इवेंट स्ट्रीम। मैं सोचता था कि आप इसे कुल भाषा में नहीं लिख सकते, लेकिन मैंने सीखा है कि आप कर सकते हैं , और इसलिए मुझे उस क्षमता के लिए एक अच्छा विचार है।
जोर्ग डब्ल्यू मित्तग

50

अमोन के जवाब में सब कुछ के लिए +1 । मैं इसे जोड़ना चाहूंगा:

पहली बार जब आप एक अलग भाषा में लिखे गए कोड के भीतर से समान कॉन्फ़िगरेशन आयात करना चाहते हैं, तो आप पाइथन कोड का उपयोग करके अपनी कॉन्फ़िगरेशन भाषा पर पछतावा करेंगे। उदाहरण के लिए यदि कोड आपकी परियोजना का हिस्सा है और यह C ++ या रूबी में लिखा गया है या कुछ और विन्यास में खींचने की आवश्यकता है, तो आपको पायथन दुभाषिया को एक पुस्तकालय के रूप में लिंक करना होगा या पायथन कोप्रोसेस में कॉन्फ़िगरेशन को पार्स करना होगा, दोनों जो अजीब, कठिन या उच्च-भूमि के ऊपर हैं।

आज के इस कॉन्फ़िगरेशन को आयात करने वाले सभी कोड पाइथन में लिखे जा सकते हैं, और आप सोच सकते हैं कि यह कल भी सच होगा, लेकिन क्या आप निश्चित रूप से जानते हैं?

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

रिकॉर्ड के लिए ईडीआईटी : कई लोगों ने इस उत्तर पर टिप्पणी की है कि यह कैसे संभव है या संभावना नहीं है कि एक परियोजना को कभी भी किसी अन्य भाषा में पूरी तरह से फिर से लिखा जाएगा। यह कहना उचित है कि एक पूर्ण पिछड़े-संगत पुनर्लेखन को शायद ही कभी देखा गया हो। मेरे मन में वास्तव में एक ही परियोजना के टुकड़े और टुकड़े थे (और एक ही विन्यास तक पहुंच की आवश्यकता थी) विभिन्न भाषाओं में लिखे जा रहे थे। उदाहरण के लिए, गति के लिए C ++ में स्टैक की सेवा, पायथन में बैच डेटाबेस क्लीनअप, गोंद के रूप में कुछ शेल स्क्रिप्ट। तो उस मामले के लिए भी एक विचार खर्च :)


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

12
@ मुझे लगता है कि आप इसे गलत ठहरा रहे हैं। इस उत्तर (मूल और संपादित दोनों) से मैंने जो बिंदु लिया, वह यह है कि एक प्रोग्रामिंग भाषा में विन्यास फाइल लिखने का विकल्प यह है कि इससे दूसरी भाषा में कोड लिखना कठिन हो जाता है। जैसे आप अपने ऐप को Anrdoid / iPhone में पोर्ट करने का निर्णय लेते हैं और दूसरी भाषा का उपयोग करेंगे। आपको या तो (ए) मोबाइल फोन ऐप (आदर्श नहीं) पर पायथन दुभाषिया पर भरोसा करना होगा, (ख) कॉन्फ़िगरेशन को भाषा-स्वतंत्र प्रारूप में फिर से लिखना होगा और इसका इस्तेमाल करने वाले पायथन कोड को फिर से लिखना होगा, या (सी) बनाए रखना होगा। दो विन्यास प्रारूप आगे जा रहे हैं।
जॉन बेंटले

4
@JonBentley मुझे लगता है कि अगर बहु-भाषा परियोजनाओं को करने की योजना है तो यह चिंता प्रासंगिक होगी। मुझे वह छाप ओपी से नहीं मिली। इसके अतिरिक्त, कॉन्फ़िगरेशन के लिए पाठ फ़ाइलों का उपयोग करना अभी भी वास्तविक पार्सिंग / मूल्यों के रूपांतरण के लिए अतिरिक्त कोड (सभी भाषाओं में) की आवश्यकता है। तकनीकी रूप से, यदि वे key=valueविन्यास के लिए पायथन पक्ष को असाइनमेंट तक सीमित करते हैं, तो मैं नहीं देखता कि एक जावा / सी ++ प्रोग्राम पायथन फाइल को एक सादे पाठ फ़ाइल के रूप में क्यों नहीं पढ़ सकता है और यदि उन्हें किसी और चीज़ में स्थानांतरित करने की आवश्यकता है तो इसे उसी तरह पार्स करें भविष्य। मैं एक पूर्ण अजगर दुभाषिया की आवश्यकता नहीं देख रहा हूँ।
code_dredd

3
@ सही है, लेकिन उत्तर अभी भी इस आधार पर उपयोगी है कि प्रश्न केवल उस व्यक्ति पर लागू नहीं होना चाहिए जो उन्हें पोस्ट करता है। यदि आप एक मानकीकृत प्रारूप (जैसे INI, JSON, YAML, XML, आदि) का उपयोग करते हैं, तो आप संभवतः अपना स्वयं का लिखने के बजाय मौजूदा पार्सिंग लाइब्रेरी का उपयोग कर रहे होंगे। पार्सिंग लाइब्रेरी के साथ इंटरफेस करने के लिए सिर्फ एडॉप्टर क्लास के लिए अतिरिक्त काम को कम करता है। यदि आप अपने आप को कुंजी = मान तक सीमित कर रहे हैं, तो यह ओपी के अधिकांश कारणों को पहले पायथन का उपयोग करने के लिए दूर करता है और आप केवल एक मान्यता प्राप्त प्रारूप के साथ जा सकते हैं।
जॉन बेंटले

3
मुझे यह कुछ साल पहले करना था जब Lua में लिखे एक उपकरण ने Lua स्क्रिप्ट का उपयोग इसके विन्यास के रूप में किया था, तब वे चाहते थे कि हम C # में एक नया उपकरण लिखें, और विशेष रूप से हमें Lua config स्क्रिप्ट का उपयोग करने के लिए कहा। उनके पास कुल 2 लाइनें थीं जो वास्तव में प्रोग्राम करने योग्य थीं और सरल x = y नहीं थीं, लेकिन मुझे अभी भी उनके कारण .net के लिए ओपन सोर्स Lua दुभाषियों के बारे में सीखना था। यह विशुद्ध सैद्धांतिक तर्क नहीं है।
केविन शुल्क

21

अन्य उत्तर पहले से ही बहुत अच्छे हैं, मैं कुछ परियोजनाओं में वास्तविक दुनिया के उपयोग के अपने अनुभव को लाऊंगा।

पेशेवरों

वे ज्यादातर पहले से ही बाहर हैं:

  • यदि आप पायथन कार्यक्रम में हैं, तो पार्सिंग एक हवा है ( eval); यह और भी अधिक जटिल डेटा प्रकार के लिए स्वचालित रूप से काम करता है (हमारे कार्यक्रम में, हम ज्यामितीय अंक और परिवर्तनों, जो फेंक दिया / के माध्यम से ठीक लोड कर रहे हैं repr/ eval);
  • कोड की केवल कुछ पंक्ति के साथ "नकली कॉन्फ़िगरेशन" बनाना तुच्छ है;
  • आपके पास बेहतर संरचनाएं हैं और, IMO, JSON की तुलना में बेहतर सिंटैक्स है (जीज़ में भी केवल टिप्पणियां हैं और शब्दकोश कुंजियों के आसपास दोहरे उद्धरण नहीं देना एक बड़ी पठनीयता जीत है)।

विपक्ष

  • दुर्भावनापूर्ण उपयोगकर्ता कुछ भी कर सकते हैं जो आपका मुख्य कार्यक्रम कर सकता है; मैं इस समस्या पर ज्यादा विचार नहीं करता, क्योंकि आम तौर पर अगर कोई उपयोगकर्ता एक कॉन्फ़िगरेशन फ़ाइल को संशोधित कर सकता है, तो वह पहले से ही आवेदन कर सकता है;
  • यदि आप अब पायथन प्रोग्राम में नहीं हैं, तो अब आपको एक समस्या है। जबकि हमारे कई कॉन्फ़िगरेशन फ़ाइल निजी रूप से उनके मूल अनुप्रयोग में बने रहे, एक विशेष रूप से कई अलग-अलग कार्यक्रमों द्वारा उपयोग की जाने वाली जानकारी को संग्रहीत करने के लिए आया, जिनमें से अधिकांश वर्तमान में C ++ में हैं, जो अब एक बीमार-परिभाषित छोटे के लिए हैक किए गए-पार्सर के साथ है पायथन का उपसमूह repr। स्पष्ट रूप से यह एक गलत चीज़ है।
  • यहां तक ​​कि अगर आपका कार्यक्रम पायथन में रहता है, तो आप पायथन संस्करण को बदल सकते हैं। मान लीजिए कि आपका आवेदन पायथन 2 में शुरू हुआ; बहुत सारे परीक्षण के बाद आप इसे पायथन 3 में स्थानांतरित करने में कामयाब रहे - दुर्भाग्य से, आपने वास्तव में अपने सभी कोड का परीक्षण नहीं किया है - आपके पास अपने ग्राहकों की मशीनों पर पड़ी हुई सभी कॉन्फ़िगरेशन फाइलें हैं, जो पायथन 2 के लिए लिखी गई हैं, और जिस पर आप डॉन नहीं करते हैं। 'वास्तव में नियंत्रण नहीं है। आप पुरानी कॉन्फ़िगरेशन फ़ाइलों (जो अक्सर फ़ाइल स्वरूपों के लिए किया जाता है) को पढ़ने के लिए "संगतता मोड" भी प्रदान नहीं कर सकते, जब तक कि आप पायथन 2 दुभाषिया को बंडल / कॉल करने के लिए तैयार नहीं होते हैं!
  • यहां तक ​​कि अगर आप पायथन में हैं, तो कोड से कॉन्फ़िगरेशन फ़ाइल को संशोधित करना एक वास्तविक समस्या है, क्योंकि ... ठीक है, कोड को संशोधित करना बिल्कुल भी तुच्छ नहीं है, विशेष रूप से कोड जिसमें एक समृद्ध वाक्यविन्यास है और यह LISP या समान में नहीं है। हमारा एक कार्यक्रम एक विन्यास फाइल अजगर, मूल रूप से हाथ से लिखा है कि है, लेकिन जो बाद में (किसी विशेष सेटिंग चीज़ों की सूची है कि है पता चला है कि यह सॉफ्टवेयर के माध्यम से हेरफेर करने के लिए उपयोगी होगा जिस तरह से सरल एक GUI का उपयोग कर पुन: व्यवस्थित करने के लिए)। यह एक बड़ी समस्या है, क्योंकि:

    • यहां तक ​​कि सिर्फ एक पार्स प्रदर्शन करना → एएसटी → फिर से लिखना राउंडट्रिप तुच्छ नहीं है (आप ध्यान देंगे कि प्रस्तावित समाधानों में से आधे को बाद में "अप्रचलित, उपयोग न करें, सभी मामलों में काम नहीं करता" के रूप में चिह्नित किया गया है);
    • भले ही उन्होंने काम किया हो, एएसटी रास्ता बहुत ही निम्न-स्तर का है; आप आम तौर पर फ़ाइल में किए गए अभिकलन के परिणाम में हेरफेर करने में रुचि रखते हैं , न कि इसे लाने वाले चरणों में;
    • जो हमें उस सरल तथ्य तक पहुंचाता है जिसे आप केवल उन मूल्यों को संपादित नहीं कर सकते हैं जिनके साथ आप रुचि रखते हैं, क्योंकि वे कुछ जटिल संगणना द्वारा उत्पन्न हो सकते हैं जिन्हें आप अपने कोड के माध्यम से समझ / हेरफेर नहीं कर सकते हैं।

    इसकी तुलना JSON, INI या (ईश्वर न करे!) XML से करें, जहाँ इन-मेमोरी प्रतिनिधित्व को हमेशा डेटा के नुकसान के बिना या तो वापस संपादित और लिखा जा सकता है (XML, जहाँ अधिकांश DOM पार्सर्स टेक्स्ट नोड्स और कमेंट नोड्स में व्हाट्सएप रख सकते हैं) या कम से कम सिर्फ कुछ स्वरूपण खो रहा है (JSON, जहां प्रारूप स्वयं उस कच्चे डेटा की तुलना में अधिक अनुमति नहीं देता है जो आप पढ़ रहे हैं)।


तो, हमेशा की तरह, कोई स्पष्ट समाधान नहीं है; इस मुद्दे पर मेरी वर्तमान नीति है:

  • यदि कॉन्फ़िगरेशन फ़ाइल है:

    • निश्चित रूप से एक पायथन आवेदन और इसके लिए निजी - जैसा कि, कोई और कभी भी इससे पढ़ने की कोशिश नहीं करेगा;
    • हस्तलिखित;
    • एक विश्वसनीय स्रोत से आ रहा है;
    • लक्ष्य एप्लिकेशन डेटा प्रकारों का उपयोग करना वास्तव में एक प्रीमियम है;

    एक पायथन फाइल एक वैध विचार हो सकता है;

  • यदि इसके बजाय:

    • हो सकता है कि इसमें से कुछ अन्य एप्लिकेशन पढ़ने की संभावना हो;
    • इस बात की संभावना है कि यह फ़ाइल किसी एप्लिकेशन द्वारा संपादित की जा सकती है, संभवतः मेरे आवेदन की भी;
    • एक अविश्वसनीय स्रोत द्वारा प्रदान किया जाता है।

    एक "केवल डेटा" प्रारूप एक बेहतर विचार हो सकता है।

ध्यान दें कि इसे एक ही विकल्प बनाने की आवश्यकता नहीं है - मैंने हाल ही में एक एप्लिकेशन लिखा है जो दोनों दृष्टिकोणों का उपयोग करता है। मेरे पास पहले-सेटअप, हस्तलिखित सेटिंग्स के साथ लगभग-कभी-संशोधित फ़ाइल है जहां अच्छा पायथन बोनस होने के फायदे हैं, और UI से संपादित कॉन्फ़िगरेशन के लिए एक JSON फ़ाइल है।


1
कॉन्फ़िगरेशन को फिर से बनाने या पुन: लिखने के बारे में बहुत अच्छी बात! लेकिन XML के अलावा कुछ प्रारूप आउटपुट में टिप्पणियों को बनाए रख सकते हैं, जिन्हें मैं कॉन्फ़िगरेशन के लिए बेहद महत्वपूर्ण मानता हूं। अन्य प्रारूप कभी-कभी एक note:फ़ील्ड का परिचय देते हैं जिसे कॉन्फ़िगरेशन के लिए अनदेखा किया जाता है।
आमोन

2
"यदि कोई उपयोगकर्ता एक कॉन्फ़िगरेशन फ़ाइल को संशोधित कर सकता है, तो वह पहले से ही जो कुछ भी कर सकता है वह आवेदन कर सकता है" - यह बिल्कुल सच नहीं है। चमकदार कॉन्फिग की तुलना में परीक्षण के बारे में किसी को पता नहीं है जिसे आपने पास्टबिन पर अपलोड नहीं किया है?
दिमित्री ग्रिगोरीव

2
@DmitryGrigoryev: यदि आप उस लक्ष्य पर निशाना साध रहे हैं, तो आप अपने शिकार को कुछ कॉपी-पेस्ट करने के लिए कह सकते हैं curl ... | bash, यह एक परेशानी से भी कम है। :-P
मट्टियो इटालिया

@DmitryGrigoryev: और यह उस प्रकार की चीज है जो किसी को काम पर अपने पहले दिन उत्पादन प्रणाली को पूरी तरह से खत्म करने की अनुमति दे सकती है। यदि 'eval' आपका पार्सर है, तो इसका मतलब है कि इसे पढ़ने से पहले समस्याओं की जाँच करने का कोई अवसर नहीं है। (यही कारण है कि शेल स्क्रिप्ट उत्पादन में बहुत खराब हैं)। INI, YAML या JSON इस संबंध में सुरक्षित हैं।
जो

1
: अपनी समस्या को ठीक करो! ")। इसके अलावा, गैर-निष्पादन योग्य कॉन्फ़िगरेशन फ़ाइलों के साथ भी नुकसान की बहुत अधिक संभावना है - यहां तक ​​कि केवल दुर्भावनापूर्ण रूप से महत्वपूर्ण फ़ाइलों पर लॉगिंग को इंगित करते हुए (यदि एप्लिकेशन पर्याप्त विशेषाधिकार के साथ चलता है) तो आप सिस्टम पर कहर बरपा सकते हैं। यही कारण है कि मुझे लगता है कि व्यवहार में यह सुरक्षा की दृष्टि से बहुत अंतर नहीं है
मट्टियो इटालिया

8

मुख्य प्रश्न यह है: क्या आप चाहते हैं कि आपकी कॉन्फ़िगरेशन फ़ाइल कुछ ट्यूरिंग पूर्ण भाषा (जैसे पायथन है) में हो? यदि आप ऐसा चाहते हैं, तो आप कुछ अन्य (ट्यूरिंग कम्प्लीट) स्क्रिप्टिंग लैंग्वेज जैसे कि गुइल या लुआ को एम्बेड करने पर भी विचार कर सकते हैं (क्योंकि वहाँ का अर्थ "सरल" के रूप में माना जा सकता है, या पायथन की तुलना में एम्बेड करना है, एक्सटेंडिंग & amp ; अध्याय पढ़ें पाइथन एंबेडिंग )। मैं उस पर आगे चर्चा नहीं करूँगा (क्योंकि अन्य उत्तर-अमोन द्वारा - चर्चा की गई है कि गहराई से) लेकिन ध्यान दें कि आपके आवेदन में एक स्क्रिप्टिंग भाषा एम्बेड करना एक प्रमुख वास्तुशिल्प विकल्प है , जिसे आपको बहुत जल्दी विचार करना चाहिए; मैं वास्तव में उस विकल्प को बाद में बनाने की सलाह नहीं देता!

एक कार्यक्रम का एक जाना-पहचाना उदाहरण "थ्रू स्क्रिप्ट्स" है, जो GNU एमएसीएस संपादक है (या मालिकाना क्षेत्र में शायद ऑटोकैड ); इसलिए ध्यान रखें कि यदि आप स्क्रिप्टिंग को स्वीकार करते हैं, तो कुछ उपयोगकर्ता अंततः-और शायद दुर्व्यवहार का उपयोग करेंगे, आपके दृष्टिकोण में- कि सुविधा बड़े पैमाने पर और एक बहु-हजार लाइनें स्क्रिप्ट बना सकती हैं; इसलिए एक अच्छी स्क्रिप्टिंग भाषा का चुनाव महत्वपूर्ण है।

हालाँकि (कम से कम POSIX सिस्टम पर), आप कॉन्फ़िगरेशन को "फ़ाइल" सक्षम करने के लिए सुविधाजनक मान सकते हैं , आरंभिक समय में गतिशील रूप से गणना की जा सकती है (ज़ाहिर है, आपके सिस्टम व्यवस्थापक या उपयोगकर्ता के लिए एक सामान्य कॉन्फ़िगरेशन का बोझ छोड़कर; वास्तव में यह एक कॉन्फ़िगरेशन है; पाठ जो कुछ फ़ाइल या कुछ कमांड से आता है)। उसके लिए, आप बस कन्वेंशन (और इसे दस्तावेज कर सकते हैं) को गोद ले सकते हैं, जैसे कि एक !या एक |से शुरू होने वाली कॉन्फ़िगरेशन फ़ाइल पथ वास्तव में एक शेल कमांड है जिसे आप पाइपलाइन के रूप में पढ़ेंगे । यह आपके उपयोगकर्ता को जो भी "पूर्वप्रक्रमक" या "स्क्रिप्टिंग भाषा" का उपयोग करने के विकल्प के साथ छोड़ देता है, वह सबसे परिचित है।

(यदि आप गतिशील रूप से गणना किए गए कॉन्फ़िगरेशन को स्वीकार करते हैं तो आपको सुरक्षा मुद्दों के बारे में अपने उपयोगकर्ता पर भरोसा करने की आवश्यकता है)

इसलिए आपके आरंभीकरण कोड में, आपकी mainइच्छा (उदाहरण के लिए) कुछ --config तर्क को स्वीकार करती हैconfarg और इससे कुछ FILE*configf;प्राप्त करती है। यदि वह तर्क इसके साथ शुरू होता है !(यानी यदि (confarg[0]=='!')....), तो आप configf = popen(confarg+1, "r");उस पाइप का उपयोग और बंद कर देंगे pclose(configf);। अन्यथा आप configf=fopen(confarg, "r");उस फ़ाइल का उपयोग और बंद कर देंगे fclose(configf);(त्रुटि जाँच को न भूलें)। देखें पाइप (7) , popen (3) , fopen (3) । एक आवेदन के लिए पायथन में os.popen , आदि के बारे में पढ़ा ...

( ऊपर दिए गए ट्रिक को दरकिनार !foo.configकरने के ./!foo.configलिए नामांकित कॉन्फ़िगरेशन फ़ाइल को पास करने के इच्छुक अजीब उपयोगकर्ता के लिए भी दस्तावेज़ popen)

BTW, इस तरह की ट्रिक केवल एक सुविधा है (उन्नत फ़ाइल की आवश्यकता के लिए उन्नत उपयोगकर्ता से बचने के लिए कॉन्फ़िगरेशन फ़ाइल उत्पन्न करने के लिए कुछ शेल स्क्रिप्ट को कोड करना )। यदि उपयोगकर्ता किसी भी बग की रिपोर्ट करना चाहता है, तो उसे आपको उत्पन्न कॉन्फ़िगरेशन फ़ाइल भेजनी चाहिए ...

ध्यान दें कि आप अपने एप्लिकेशन को शुरुआती समय में प्लगइन्स का उपयोग करने और लोड करने की क्षमता के साथ डिजाइन कर सकते हैं , उदाहरण के लिए dlopen (3) के साथ (और आपको उस प्लगइन के बारे में अपने उपयोगकर्ता पर भरोसा करने की आवश्यकता है)। फिर, यह एक बहुत ही महत्वपूर्ण वास्तु निर्णय है (और आपको इन प्लगइन्स और आपके आवेदन के बारे में कुछ स्थिर एपीआई और सम्मेलन को परिभाषित करने और प्रदान करने की आवश्यकता है )।

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

आपकी कॉन्फ़िगरेशन फ़ाइल के लिए पाठ प्रारूप के बारे में (यह जेनरेट किया गया है या नहीं), मेरा मानना ​​है कि आपको ज्यादातर इसे अच्छी तरह से दस्तावेज करने की आवश्यकता है (और कुछ विशेष प्रारूप का विकल्प उतना महत्वपूर्ण नहीं है; हालांकि, मैं आपको उपयोगकर्ता को डालने में सक्षम होने की सलाह देता हूं; कुछ -स्कैप्ड- इसके अंदर टिप्पणियां)। आप JSON इस्तेमाल कर सकते हैं (अधिमानतः कुछ JSON पार्सर को स्वीकार करने और हमेशा की तरह के साथ टिप्पणी लंघन साथ //EOL या जब तक /*... */...), या YAML, या XML, या INI या अपने खुद के बात। कॉन्फ़िगरेशन फ़ाइल पार्स करना बहुत आसान है (और आपको उस कार्य से संबंधित कई लाइब्रेरी मिलेंगी)।


प्रोग्रामिंग भाषाओं की ट्यूरिंग-पूर्णता का उल्लेख करने के लिए +1। कुछ दिलचस्प कार्यों से पता चलता है कि इनपुट प्रारूप की कम्प्यूटेशनल शक्ति को सीमित करना इनपुट हैंडलिंग लेयर को सुरक्षित करने के लिए महत्वपूर्ण है। ट्यूरिंग-पूर्ण प्रोग्रामिंग भाषा का उपयोग करना विपरीत दिशा में जाता है।
माथियस मोरेरा

2

आमोन के जवाब में जोड़कर , क्या आपने विकल्पों पर विचार किया है? JSON शायद आपकी आवश्यकता से अधिक है, लेकिन पायथन फाइलें शायद आपको भविष्य में ऊपर बताए गए कारणों के लिए समस्याएँ देंगी।

हालाँकि पाइथन के पास पहले से ही एक बहुत साधारण विन्यास भाषा के लिए एक कॉन्फिगर पैरसर है जो आपकी सभी जरूरतों को पूरा कर सकता है। ConfigParserमॉड्यूल एक सरल config भाषा लागू करता है।


1
Microsoft Windows INI फ़ाइलों के समान कुछ का उपयोग करना एक बुरा विचार प्रतीत होता है, दोनों इस आधार पर कि यह एक विशेष रूप से लचीला प्रारूप नहीं है, और क्योंकि 'समान' का अर्थ अनिर्दिष्ट असंगति है।
पीट किर्कम

1
@PeteKirkham खैर, यह सरल है, यह प्रलेखित है और यह पायथन मानक पुस्तकालय का हिस्सा है। यह ओप्स की जरूरतों के लिए सही समाधान हो सकता है, क्योंकि वह ऐसी चीज की खोज कर रहा है जो सीधे पायथन द्वारा समर्थित है और जोसन की तुलना में सरल है। जब तक वह आगे यह नहीं बताता कि उसकी जरूरतें क्या हैं, मुझे लगता है कि यह जवाब उसके लिए मददगार हो सकता है।
कोडमोंकी

1
मैं अनिवार्य रूप से यह सुझाव देने जा रहा था - देखें कि किस प्रकार की कॉन्फ़िगरेशन फाइलें पायथन लिबास का समर्थन करती हैं और उनमें से एक को चुनती हैं। इसके अलावा, पॉवर्सशेल में डेटा अनुभागों की धारणा है - जो सीमित पॉवर्सशेल भाषा निर्माणों की अनुमति देता है - दुर्भावनापूर्ण कोड के खिलाफ सुरक्षा। यदि पाइथन के पास एक लिब है जो कॉन्फ़िगरेशन के लिए पाइथन के सीमित उपसमूह का समर्थन करता है, तो यह ओपी में विचार के खिलाफ कम से कम एक को कम करता है।
.pΧ

1
@PeteKirkham यह अधिक संभावना है कि दूसरी तरह से एक समस्या है। विंडोज में अनजाने क्रैप का एक गुच्छा है जो आप पर फूटता है। पाइथन अच्छी तरह से प्रलेखित और सीधा है। उस ने कहा, यदि आप सभी की जरूरत है सरल कुंजी / मूल्य जोड़े ( शायद वर्गों के साथ), यह एक बहुत अच्छा विकल्प है। मुझे संदेह है कि इसमें 90% उपयोग के मामले शामिल हैं। यदि .NET स्कीम की फाइलें राक्षसी XML के बजाय एक स्कीमा के साथ आईएनआई होती हैं जो वास्तव में कोड के रूप में कोडिंग है, तो हम सभी बहुत बेहतर होंगे।
jpmc26

1
@PeteKirkham वास्तव में नहीं। पहली जगह में सरल उपयोग के मामलों के लिए सबसे अच्छा होने के नाते, संभावना है कि आप किसी भी असंगति से बच सकते हैं। यदि आप दो अलग-अलग भाषाओं के साथ फ़ाइल का उपभोग नहीं कर रहे हैं, तो भी कोई फर्क नहीं पड़ता, और यदि आप हैं, तो आप संभवतः किसी भी भाषा में खुले कार्यान्वयन पा सकते हैं (आपको या तो असंगतताएं नहीं हैं या कम से कम, वास्तव में क्या पता है वो हैं)। मैं इस बात से सहमत हूं कि यदि आप का उपयोग मामला वास्तव में इतना जटिल है कि आप उनमें भागना शुरू कर दें या यदि आपको कोई मौजूदा कार्यान्वयन नहीं मिल रहा है जिस पर आप भरोसा कर सकते हैं, तो आपको एक और प्रारूप का उपयोग करना चाहिए, लेकिन यह आम नहीं है।
jpmc26

1

मैंने लंबे समय से कुछ प्रसिद्ध सॉफ्टवेयर के साथ काम किया है जिसमें इसकी कॉन्फ़िगरेशन फाइलें टीसीएल में लिखी गई हैं, इसलिए यह विचार नया नहीं है। यह काफी अच्छी तरह से काम करता है, क्योंकि जिन उपयोगकर्ताओं को भाषा नहीं पता थी वे अभी भी एक set name valueस्टेटमेंट का उपयोग करके सरल कॉन्फ़िगरेशन फ़ाइलों को लिख / संपादित कर सकते हैं , जबकि अधिक उन्नत उपयोगकर्ता और डेवलपर्स इसके साथ परिष्कृत ट्रिक खींच सकते हैं।

मुझे नहीं लगता कि "डिबग फ़ाइलों को डिबग करना मुश्किल हो सकता है" एक वैध चिंता का विषय है। जब तक आपका एप्लिकेशन उपयोगकर्ताओं को स्क्रिप्ट लिखने के लिए बाध्य नहीं करता है, तब तक आपके उपयोगकर्ता हमेशा अपनी कॉन्फ़िगरेशन फ़ाइलों में सरल असाइनमेंट का उपयोग कर सकते हैं, जो कि JSON या XML की तुलना में सही प्राप्त करना शायद ही कोई अधिक कठिन है।

कॉन्फ़िगरेशन को फिर से लिखना एक समस्या है, हालांकि यह उतना बुरा नहीं है जितना लगता है। मनमाना कोड अपडेट करना असंभव है, लेकिन किसी फाइल से कॉन्फिग लोड करना, उसे बदलना और उसे वापस सेव करना है। मूल रूप से, यदि आप एक विन्यास फाइल में कुछ स्क्रिप्टिंग करते हैं जो केवल-पढ़ने के लिए नहीं है, तो आप set name valueसहेजने के बाद सिर्फ बयानों की समकक्ष सूची के साथ समाप्त करेंगे । एक अच्छा संकेत है कि यह होगा फ़ाइल की शुरुआत में एक "संपादित न करें" टिप्पणी है।

एक बात पर विचार करें कि आपकी कॉन्फिग फाइलें साधारण रीगेक्स-आधारित टूल्स द्वारा विश्वसनीय रूप से पठनीय नहीं होंगी, जैसे कि sed, लेकिन जहां तक ​​मैं समझता हूं कि यह पहले से ही आपकी वर्तमान JSON फाइलों के मामले में नहीं है, इसलिए खोने के लिए बहुत कुछ नहीं है।

बस सुनिश्चित करें कि आप अपनी विन्यास फाइल को निष्पादित करते समय उचित सैंडबॉक्सिंग तकनीकों का उपयोग करें।


1
"सॉफ्टवेयर" एक बेशुमार संज्ञा है, इसलिए इसे " कुछ प्रसिद्ध सॉफ्टवेयर " होना चाहिए ।
jpmc26

1

यहां अन्य अच्छे उत्तरों के सभी मान्य बिंदुओं के अलावा (वाह, उन्होंने ट्यूरिंग-पूर्ण अवधारणा का भी उल्लेख किया है), वास्तव में कुछ ठोस व्यावहारिक कारण हैं जो आपके कॉन्फ़िगरेशन के रूप में पायथन फाइल का उपयोग नहीं करते हैं, तब भी जब आप पायथन पर काम कर रहे हों- केवल परियोजना।

  1. पायथन स्रोत फ़ाइल के अंदर की सेटिंग तकनीकी रूप से निष्पादन योग्य स्रोत कोड का हिस्सा है, बजाय एक रीड-ओनली डेटा फ़ाइल के। यदि आप इस मार्ग पर जाते हैं, तो आप आमतौर पर करते हैं import config, क्योंकि उस तरह की "सुविधा" संभवतः एक प्रमुख कारण था जो लोगों ने पायथन फ़ाइल को पहली जगह के रूप में कॉन्फ़िगर करने के साथ शुरू किया था। जब आप पहली बार आपके प्रोग्राम को चलाने का प्रयास करते हैं, तो आप उस कॉन्फ़िगरेशन को अपने रेपो में करने का प्रयास करते हैं, अन्यथा आपका अंतिम उपयोगकर्ता एक भ्रामक ImportError से सामना करेगा।

  2. यह मानते हुए कि वास्तव में आप उस रेमपॉम को अपने रेपो में शामिल कर रहे हैं, अब आपकी टीम के सदस्यों के पास अलग-अलग वातावरण में अलग-अलग सेटिंग्स होंगी। किसी दिन कल्पना करें कि किसी सदस्य ने गलती से रेपो में अपनी स्थानीय कॉन्फ़िगरेशन फ़ाइल डाल दी है।

  3. अंतिम लेकिन कम से कम नहीं, आपकी परियोजना कॉन्फ़िगरेशन फ़ाइल में पासवर्ड हो सकती है। (यह अपने आप में एक बहस का अभ्यास है, लेकिन यह वैसे भी होता है।) और यदि आपकी कॉन्फ़िगरेशन फ़ाइल रेपो में मौजूद है, तो आप सार्वजनिक रेपो में अपनी साख को जोखिम में डालते हैं।

अब, केवल डेटा कॉन्फ़िगरेशन फ़ाइल, जैसे कि यूनिवर्सल JSON प्रारूप का उपयोग करके, उपरोक्त सभी 3 समस्याओं से बच सकते हैं, क्योंकि आप उपयोगकर्ता को अपने स्वयं के config.json के साथ आने के लिए यथोचित पूछ सकते हैं और इसे अपने प्रोग्राम में फीड कर सकते हैं।

PS: यह सच है कि JSON में कई प्रतिबंध हैं। ओपी द्वारा उल्लिखित सीमाओं में से 2 को कुछ रचनात्मकता द्वारा हल किया जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.