वैश्विक चर बुराई क्यों हैं? [बन्द है]


120

मैं यह पता लगाने की कोशिश कर रहा हूं कि globalअजगर (और सामान्य रूप से प्रोग्रामिंग में) के उपयोग को बुरा क्यों माना जाता है। कोई समझा सकता है? अधिक जानकारी के लिंक की भी सराहना की जाएगी।


फिर से खोलने के लिए वोटिंग - मैंने सवाल को स्पष्टीकरण के लिए और ऑफ-साइट संसाधनों से दूर स्थानांतरित करने के लिए संपादित किया। (मुझे लगता है कि के कारण है कि यह बंद हो गया, लेकिन सिर्फ मामले में यह के बुरे व्यवहार के बारे में एक सवाल किया जा रहा है के साथ कुछ, जो अभी भी खुले हैं बुरा व्यवहार के बारे में इन अन्य प्रश्न तुलना: eval, import *, स्ट्रिंग संयोजन , चरid , विशेषता छाया )
wjandrea

जवाबों:


156

इसका अजगर से कोई लेना-देना नहीं है; वैश्विक चर किसी भी प्रोग्रामिंग भाषा में खराब हैं।

हालांकि, वैश्विक स्थिरांक वैचारिक रूप से वैश्विक चर के समान नहीं हैं ; वैश्विक स्थिरांक पूरी तरह से हानिरहित हैं। अजगर में दोनों के बीच का अंतर विशुद्ध रूप से सम्मेलन द्वारा है: CONSTANTS_ARE_CAPITALIZEDऔर globals_are_not

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

हालाँकि, वैश्विक प्रोग्रामिंग में भी (जैसे कि स्थानीय राज्य और परिवर्तनशीलता) है, का गतिशील उपयोग स्वीकार्य है, यहाँ तक कि एल्गोरिथम ऑप्टिमाइज़ेशन, कम जटिलता, कैशिंग और मेमोइज़ेशन, या पोर्टिंग संरचनाओं की व्यावहारिकता के लिए, जो मुख्य रूप से अपूर्ण कोडबेस में उत्पन्न होती है।

सभी के सभी, आपके प्रश्न का उत्तर कई तरीकों से दिया जा सकता है, इसलिए आपका सबसे अच्छा शर्त सिर्फ Google "वैश्विक चर खराब क्यों हैं" है। कुछ उदाहरण:

यदि आप गहराई में जाना चाहते हैं और यह जानना चाहते हैं कि दुष्प्रभाव क्यों हैं, और कई अन्य ज्ञानवर्धक चीजें हैं, तो आपको कार्यात्मक प्रोग्रामिंग सीखना चाहिए:


35

हां, सिद्धांत रूप में , ग्लोबल्स (और सामान्य रूप से "राज्य") बुराई हैं। व्यवहार में, यदि आप अपने अजगर के पैकेज निर्देशिका में देखते हैं, तो आप पाएंगे कि अधिकांश मॉड्यूल वैश्विक घोषणाओं के एक समूह के साथ शुरू होते हैं। जाहिर है, लोगों को उनसे कोई समस्या नहीं है।

विशेष रूप से अजगर के लिए, ग्लोबल्स की दृश्यता एक मॉड्यूल तक सीमित है, इसलिए कोई "सच" ग्लोबल्स नहीं हैं जो पूरे कार्यक्रम को प्रभावित करते हैं - जो उन्हें एक तरह से कम हानिकारक बनाता है। एक और बिंदु: कोई भी नहीं है const, इसलिए जब आपको एक निरंतरता की आवश्यकता होती है तो आपको एक वैश्विक उपयोग करना होगा।

मेरे व्यवहार में, यदि मैं किसी फ़ंक्शन में किसी वैश्विक को संशोधित करने के लिए होता हूं, तो मैं हमेशा इसके साथ घोषित करता हूं global, भले ही तकनीकी रूप से इसके लिए कोई आवश्यकता न हो, जैसे कि:

cache = {}

def foo(args):
    global cache

    cache[args] = ...

इससे ग्लोबल्स की जोड़-तोड़ आसान हो जाती है।


3
कई मायनों में, अजगर में एक मॉड्यूल एक सिंगलटन वर्ग के समान है, और मॉड्यूल ग्लोबल्स वर्ग गुणों के समान हैं।
Corley Brigman

9
@CorleyBrigman: सिंगलटन क्लासेस वास्तव में अक्सर उन्हीं समस्याओं से पीड़ित होती हैं जिन्हें आमतौर पर ग्लोबल्स के लिए जिम्मेदार ठहराया जाता है :)
एरिक कप्लुन

4
अजगर मॉड्यूल की दृश्यता एक मॉड्यूल तक सीमित नहीं है। वे पूरे दुभाषिया में उपलब्ध हैं, और (यहाँ महत्वपूर्ण बात) पूरे दुभाषिया को प्रभावित करते हैं। यह एक स्ट्रिंग की तरह नहीं है जिसे आप इंस्टेंस बनाते हैं ... यह सभी स्ट्रिंग इंस्टेंस को संशोधित करने जैसा है। बंदर की बदबू
ग्रा।

2
अधिकांश मॉड्यूल स्थिरांक को छोड़कर ग्लोबल्स को परिभाषित करने से शुरू नहीं होते हैं । ग्लोबल्स खराब मतलब है कि वैरिएबल / ग्लोबल स्टेट कॉन्स्टेंट नहीं हैं।
ब्लैकजैक

2
ग्लोबल्स का उपयोग करना एक भयानक विचार है, एक कारण ठीक से परीक्षण कार्यों में असमर्थता हो सकती है जो कुछ मनमाना शब्दकोश को अपडेट करते हैं जो "कहीं" मौजूद है। ग्लोबल्स वाला एक कोडबेस वास्तव में कार्यात्मक साबित नहीं हो सकता है।
टॉमाज़ सोसिस्की

10

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

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

(संभवतः) विशुद्ध कार्य की परिभाषा

मेरा मानना ​​है कि एक साफ और (लगभग) बग-मुक्त कोड में ऐसे कार्य होने चाहिए जो यथासंभव शुद्ध हों ( शुद्ध कार्य देखें )। एक शुद्ध कार्य वह है जिसमें निम्नलिखित स्थितियाँ हैं:

  1. फ़ंक्शन हमेशा समान परिणाम मान का मूल्यांकन करता है जिसे समान तर्क मान दिया गया है । फ़ंक्शन परिणाम मान किसी भी छुपी हुई जानकारी या स्थिति पर निर्भर नहीं हो सकता है जो प्रोग्राम निष्पादन की कार्यवाही के दौरान या प्रोग्राम के विभिन्न निष्पादन के बीच बदल सकता है, और न ही यह I / O उपकरणों से किसी भी बाहरी इनपुट पर निर्भर हो सकता है (आमतौर पर नीचे देखें)।
  2. परिणाम का मूल्यांकन किसी भी शब्दानुभवनीय दुष्प्रभाव या आउटपुट का कारण नहीं बनता है , जैसे कि उत्परिवर्तनीय वस्तुओं का उत्परिवर्तन या I / O उपकरणों के आउटपुट।

वैश्विक चर होने से उपरोक्त में से कम से कम एक का उल्लंघन हो रहा है यदि बाहरी कोड के रूप में दोनों संभवत: अप्रत्याशित परिणाम नहीं दे सकते हैं।

शुद्ध कार्यों की एक और स्पष्ट परिभाषा: "शुद्ध कार्य एक ऐसा कार्य है जो अपने सभी इनपुटों को स्पष्ट तर्कों के रूप में लेता है और अपने सभी परिणामों को स्पष्ट परिणाम के रूप में उत्पन्न करता है ।" [१] । वैश्विक चर होने से इनपुट के बाद से शुद्ध कार्यों के विचार का उल्लंघन होता है और शायद आउटपुट में से एक (वैश्विक चर) स्पष्ट रूप से दिया या वापस नहीं किया जा रहा है।

(संभवतः) उल्लंघन करने वाली इकाई एफआईएसटी सिद्धांत का परीक्षण कर रही है

इसके अलावा, यदि आप यूनिट-परीक्षण और एफआईआरएसटी सिद्धांत पर विचार करते हैं ( एफ ast परीक्षण, मैं ndependent परीक्षण, R epeatable, S elf-Validating और T imely) संभवतः स्वतंत्र परीक्षण सिद्धांत (जिसका अर्थ है कि परीक्षण निर्भर नहीं करते हैं) का उल्लंघन करेंगे एक दूसरे पर)।

वैश्विक परिवर्तनशील होना (हमेशा नहीं) लेकिन अधिकांश मामलों में (जो मैंने अभी तक देखा है उनमें से कम से कम) अन्य कार्यों के लिए परिणाम तैयार करना और पारित करना है। यह इस सिद्धांत का भी उल्लंघन करता है। यदि वैश्विक चर का उपयोग उस तरह से किया गया है (अर्थात फ़ंक्शन X में उपयोग किया जाने वाला वैश्विक चर पहले किसी फ़ंक्शन Y में सेट किया जाना है) तो इसका मतलब है कि इकाई परीक्षण फ़ंक्शन X के लिए आपको परीक्षण / फ़ंक्शन फ़ंक्शन को पहले चलाना होगा।

स्थिरांक के रूप में ग्लोबल्स

दूसरी ओर और जैसा कि अन्य लोगों ने पहले ही उल्लेख किया है, अगर वैश्विक चर का उपयोग "स्थिर" चर के रूप में किया जा सकता है क्योंकि भाषा स्थिरांक का समर्थन नहीं करती है। हालांकि, मैं हमेशा कक्षाओं के साथ काम करना पसंद करता हूं और एक वर्ग के सदस्य के रूप में "स्थिरांक" रखता हूं और वैश्विक चर का उपयोग बिल्कुल नहीं करता हूं। यदि आपके पास एक कोड है जो दो अलग-अलग वर्गों को एक वैश्विक चर साझा करने की आवश्यकता है, तो आपको संभवतः अपने समाधान को फिर से भरने और अपनी कक्षाओं को स्वतंत्र बनाने की आवश्यकता है।

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


1
मुझे पसंद है "कॉन्स्टेंट के रूप में ग्लोबल्स एक समस्या है" ... क्योंकि अगर आप ओओ डिजाइन कर रहे हैं ... यह वास्तव में है। किसी को भी लेकिन IdCreator वर्ग को ID_LEN को जानने की आवश्यकता क्यों है?
एरिक एरोनिटी

3

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

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