2010-02-06 14 views
10

आमतौर पर असाइनमेंट पर चर घोषित करने को वीबीस्क्रिप्ट या जावास्क्रिप्ट में सबसे अच्छा अभ्यास माना जाता है, उदाहरण के लिए, हालांकि इसकी अनुमति है।चर घोषित करने का पाइथोनिक तरीका क्या है?

पाइथन आपको केवल तब उपयोग करने के लिए मजबूर करता है जब आप इसका उपयोग करते हैं? चूंकि पाइथन केस संवेदनशील है, इसलिए यह बग का कारण नहीं बन सकता है क्योंकि आपने एक चर के नाम की गलत वर्तनी की है?

आप ऐसी स्थिति से कैसे बचेंगे?

+3

"पाइथन आपको क्यों मजबूर करता है" ... "यह बग का कारण नहीं बन सकता" यह "व्यक्तिपरक और तर्कवादी" की परिभाषा है। मैंने करीब मतदान किया। – balpha

+6

@balpha सीखने पर विचार करें कि "व्यक्तिपरक" और "तर्कवादी" शब्द क्या हैं, जैसा कि आप उद्धृत उदाहरण दोनों के सटीक विपरीत * हैं। – hobbs

+0

@ हॉब्स मैं * करीबी कारण * "व्यक्तिपरक और तर्कवादी" की परिभाषा के बारे में बात कर रहा हूं (दोनों शब्दों के चारों ओर उद्धरण के * एकल * जोड़ी को नोट करें)। इस सवाल का जवाब देना असंभव है [उदाहरण 2], और सवाल एक टकराव, तर्कसंगत तरीके से पूछा गया था [उदाहरण 1]। – balpha

उत्तर

9

पायथन में यह नामों को बाध्यकारी मूल्यों के रूप में घोषित करने के बारे में सोचने में मदद करता है।

उन्हें गलत वर्तनी न करने का प्रयास करें, या आपके पास नए होंगे (मान लें कि आप असाइनमेंट कथन के बारे में बात कर रहे हैं - उन्हें संदर्भित करने से अपवाद होगा)।

यदि आप आवृत्ति चर के बारे में बात कर रहे हैं, तो आप बाद में उनका उपयोग नहीं कर पाएंगे।

उदाहरण के लिए, यदि आप एक वर्ग myclass था और इसके __init__ विधि में self.myvar = 0 लिखा था, तो संदर्भ के लिए self.myvare एक त्रुटि का कारण होगा, बजाय आप एक डिफ़ॉल्ट मान देने की कोशिश कर रहा।

+4

+1 जो आपने गलत वर्तनी के बारे में कहा था, मुझे हंसते हुए – lamas

+0

क्या आप समझा सकते हैं कि self.myvar को संदर्भित करने से त्रुटि क्यों होगी? –

+1

'self.myvar' का संदर्भ देने से कोई त्रुटि नहीं आएगी, क्योंकि इसे 'init' में असाइन किया गया है। 'Init' के बाहर 'self.myvare' का संदर्भ देना (मुझे इसके बारे में अधिक स्पष्ट होना चाहिए था) एक त्रुटि का कारण बन जाएगा, क्योंकि इसे' init' में असाइन नहीं किया गया था। – danben

5

पायथन आपको इसका उपयोग करते समय केवल एक चर बनाने के लिए मजबूर नहीं करता है। आप हमेशा नाम पर None बांध सकते हैं और फिर बाद में नाम का उपयोग कर सकते हैं।

+3

-1 मुझसे मुझे लगता है कि आप वास्तव में सवाल का जवाब नहीं दे रहे हैं। यदि आप यह दिखाने के लिए संपादित करते हैं कि यह ओपी के बारे में चिंतित समस्याओं को कैसे रोक सकता है, तो मैं +2 करूंगा। –

3

यदि आप कोई गंभीर विकास करते हैं तो आप एक (एकीकृत) विकास पर्यावरण का उपयोग करेंगे। Pylint इसका हिस्सा होगा और आपको अपनी सभी गलत वर्तनी बताएगा। लैंगेज के इस तरह के एक विशेषता हिस्सा बनाने की जरूरत नहीं है।

+3

पिलिंट मदद करता है। हालांकि गंभीर विकास के लिए पिलिंट या आईडीई का उपयोग नहीं दिया जाता है। – batbrat

+0

पिलिंट के लिए +1, +0 "भाषा के इस तरह का एक विशेषता हिस्सा बनाने की आवश्यकता नहीं है"। –

+0

कई अच्छे पायथन प्रोग्रामर आईडीआई का उपयोग नहीं करते हैं, इसके बजाय विम या इमाक्स का चयन करते हैं। –

4

गलत वर्तनी चर नाम के साथ एक स्थिति से बचने के लिए, मैं एक स्वतः पूर्णता समारोह के साथ एक पाठ संपादक का उपयोग करें और एक समारोह जब मैं एक फ़ाइल को सहेजने के नाम से जाना जाने के लिए

python -c "import py_compile; py_compile.compile('{filename}')" 

आबद्ध।

3

टेस्ट।

उदाहरण के लिए, फ़ाइल variable.py साथ:

#! /usr/bin/python 

somevar = 5 

फिर, फ़ाइल variable.txt (परीक्षण धारण करने के लिए) बनाने:

>>> import variables 
>>> variables.somevar == 4 
True 

तब कार्य करें:

python -m doctest variable.txt 

और मिलती है:

********************************************************************** 
File "variables.txt", line 2, in variables.test 
Failed example: 
    variables.somevar == 4 
Expected: 
    True 
Got: 
    False 
********************************************************************** 
1 items had failures: 
    1 of 2 in variables.test 
***Test Failed*** 1 failures. 

यह एक चर को घोषित गलत तरीके से दिखाता है।

प्रयास करें:

>>> import variables 
>>> variables.someothervar == 5 
True 

ध्यान दें कि चर एक ही नाम नहीं है।

********************************************************************** 
File "variables.test", line 2, in variables.test 
Failed example: 
    variables.someothervar == 5 
Exception raised: 
    Traceback (most recent call last): 
     File "/usr/local/lib/python2.6/doctest.py", line 1241, in __run 
     compileflags, 1) in test.globs 
     File "<doctest variables.test[1]>", line 1, in <module> 
     variables.someothervar == 5 
    AttributeError: 'module' object has no attribute 'someothervar' 
********************************************************************** 
1 items had failures: 
    1 of 2 in variables.test 
***Test Failed*** 1 failures. 

यह एक गलत वर्तनी चर दिखाता है।

>>> import variables 
>>> variables.somevar == 5 
True 

और यह कोई त्रुटि नहीं देता है।

मैंने यह जानने के लिए पर्याप्त वीबीस्क्रिप्ट विकास किया है कि टाइपो परिवर्तनीय नाम में एक समस्या है, और पर्याप्त वीबीस्क्रिप्ट विकास यह जानने के लिए कि Option Explicit सबसे अच्छा है। (< - एएसपी वीबीस्क्रिप्ट अनुभव के 12 साल ने मुझे कठिन तरीका सिखाया।)

15

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

+3

मुझे आशा है कि यह उत्तर जीत जाएगा। स्पष्ट रूप से जवाब यह है कि "आप पाइथन में ऐसा नहीं कर सकते हैं, लेकिन संभवतया आपके विचार से कम एक बड़ा सौदा है।" –

12

आप के साथ एक वर्ग चाहते हैं "बंद-नीचे" उदाहरण के गुण, यह एक बनाने के लिए मुश्किल नहीं है, जैसे:

class LockedDown(object): 
    __locked = False 
    def __setattr__(self, name, value): 
    if self.__locked: 
     if name[:2] != '__' and name not in self.__dict__: 
     raise ValueError("Can't set attribute %r" % name) 
    object.__setattr__(self, name, value) 
    def _dolock(self): 
    self.__locked = True 

class Example(LockedDown): 
    def __init__(self): 
    self.mistakes = 0 
    self._dolock() 
    def onemore(self): 
    self.mistakes += 1 
    print self.mistakes 
    def reset(self): 
    self.mitsakes = 0 

x = Example() 
for i in range(3): x.onemore() 
x.reset() 

जैसा कि आप देखेंगे, x.onemore काम करने के लिए कॉल ठीक है, लेकिन resetmitsakes के रूप में विशेषता की गलत वर्तनी के कारण अपवाद उठाता है। यहां सगाई के नियम हैं कि __init__ को सभी विशेषताओं को प्रारंभिक मानों पर सेट करना होगा, फिर self._dolock() पर कॉल करने के लिए विशेषताओं को और भी शामिल करना होगा। मैं "सुपर-प्राइवेट" विशेषताओं (__ से शुरू होने वाले) को छूट दे रहा हूं, जो पूरी तरह से विशिष्ट भूमिकाओं के लिए स्टाइलिस्टिक रूप से बहुत ही कम इस्तेमाल किया जाना चाहिए, और बेहद सीमित दायरे के साथ (इसे सुपर-सावधानीपूर्वक निरीक्षण में स्पॉट टाइपो को छोटा करना वैसे भी सुपर-गोपनीयता की आवश्यकता की पुष्टि करने के लिए), लेकिन यह एक स्टाइलिस्ट पसंद है, जो रिवर्स करना आसान है; इसी प्रकार लॉक डाउन स्टेट "अपरिवर्तनीय" ("सामान्य" माध्यम से - यानी बाईपास के लिए बहुत स्पष्ट कामकाज की आवश्यकता होती है) के विकल्प के लिए।

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

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

रॉबर्ट मार्टिन और ब्रूस एकेल दोनों अलग और स्वतंत्र लेख में इस बिंदु व्यक्त 7 साल पहले - Eckel के ब्लॉग अभी अस्थायी रूप से बंद है, लेकिन मार्टिन सही here, और जब Eckel की साइट जान लेख here होना चाहिए। थीसिस विवादास्पद है (जेफ अटवुड और उनकी टिप्पणीकार इसे उदाहरण के लिए here पर बहस करते हैं), लेकिन यह ध्यान रखना दिलचस्प है कि मार्टिन और एकल दोनों सी ++ और जावा जैसी स्थिर भाषाओं के प्रसिद्ध विशेषज्ञ हैं (हालांकि प्रेम मामलों के साथ क्रमशः, रुबी और पायथन), और वे केवल एकमात्र लोगों से यूनिट-टेस्ट के महत्व की खोज कर चुके हैं ... और साइड इफेक्ट के रूप में एक अच्छा यूनिट-टेस्ट सूट कैसे स्थिर भाषा की कठोरता को अनावश्यक बनाता है।

वैसे, आपके परीक्षण सूट को जांचने का एक तरीका "त्रुटि इंजेक्शन" है: व्यवस्थित रूप से अपने कोडबेस पर एक गलत वर्तनी पेश करना - यह सुनिश्चित करने के लिए परीक्षण चलाएं कि वे विफल हो जाएं, अगर वे एक नहीं जोड़ते हैं विफल रहता है, वर्तनी गलती को सही करता है, दोहराना। काफी अच्छी तरह से स्वचालित हो सकता है ("एक परीक्षण जोड़ें" भाग नहीं, लेकिन सूट द्वारा कवर नहीं होने वाली संभावित त्रुटियों की खोज), जैसा कि त्रुटि इंजेक्शन के कुछ अन्य रूप हो सकते हैं (प्रत्येक पूर्णांक स्थिर, एक-एक करके बदलें, एक और, एक से कम; प्रत्येक < से <= आदि बदलें; प्रत्येक if और while स्थिति को इसके विपरीत करने के लिए स्वैप करें; ...), जबकि त्रुटि-इंजेक्शन के अन्य रूपों के लिए अभी भी बहुत अधिक मानवीय समझदार की आवश्यकता है। दुर्भाग्यवश मुझे त्रुटि इंजेक्शन ढांचे (किसी भी भाषा के लिए) के सार्वजनिक रूप से उपलब्ध सूटों के बारे में पता नहीं है - एक अच्छा ओपन सोर्स प्रोजेक्ट बना सकता है ;-)।

+0

एक उत्तर का एक और मणि। – telliott99

+0

@telliott, धन्यवाद! -) –

+0

त्रुटि इंजेक्शन एक अच्छा विचार है। लेकिन मैं असहमत हूं कि यूनिट परीक्षणों की स्पष्ट उपयोगिता मजबूत टाइपिंग बेकार बनाती है। क्यों कंपेलर से आपके लिए कुछ बुनियादी जांच करने के लिए नहीं कहें, तो आप पहले और कम प्रयास के साथ बग की एक कक्षा (निश्चित रूप से, * सभी * बग) नहीं पा सकते हैं? लोकप्रिय दृढ़ता से टाइप की गई भाषाएं वर्बोज़ हैं क्योंकि वे स्वचालित रूप से उल्लंघन करने वाले प्रकारों में बहुत अच्छी नहीं हैं - लेकिन ओकैमल और हास्केल जैसी भाषाएं दिखाती हैं कि ऐसा नहीं होना चाहिए। –

-1

परिवर्तनीय घोषणा बग को रोकती नहीं है। परिवर्तनीय घोषणा की कमी से कहीं भी बग का कारण बनता है।

परिवर्तनीय घोषणाएं एक विशिष्ट प्रकार की बग को रोकती हैं, लेकिन यह अन्य प्रकार की बग बनाती है।

को रोकें। कोड लिखना जहां गलत प्रकार के डेटा के साथ चर को सेट (या परिवर्तित) करने का कोई प्रयास है।

कारण। कई असंबद्ध प्रकारों को एक साथ जोड़ने के लिए बेवकूफ कामकाज ताकि असाइनमेंट "बस काम करें"। उदाहरण: सी भाषा union। इसके अलावा, परिवर्तनीय घोषणाएं हमें कास्ट का उपयोग करने के लिए मजबूर करती हैं। जो हमें संकलन समय पर चेतावनियों पर चेतावनियों को दबाने के लिए भी मजबूर करता है क्योंकि हम "जानते हैं" यह "बस काम करेगा"। और यह नहीं करता है।

परिवर्तनीय घोषणाओं की कमी से बग का कारण नहीं बनता है। सबसे आम "खतरा परिदृश्य" किसी चर के लिए "गलत-असाइनमेंट" का एक प्रकार है।

  1. क्या चर "पुन: उपयोग किया जा रहा था"? यह गूंगा है लेकिन कानूनी और काम करता है।

  2. प्रोग्राम का कुछ हिस्सा गलत तरीके से गलत तरीके से असाइन कर रहा था?

    इससे गलत का क्या मतलब है इसका एक सूक्ष्म प्रश्न होता है? " एक बतख वाली टाइप भाषा में, गलत अर्थ है "सही तरीकों या विशेषताओं की पेशकश नहीं करता है।" जो अभी भी घबराहट है। विशेष रूप से, इसका मतलब है "प्रकार को एक विधि या विशेषता प्रदान करने के लिए कहा जाएगा जो उसके पास नहीं है।" जो अपवाद उठाएगा और कार्यक्रम बंद हो जाएगा।

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

"यह कीड़े नहीं पैदा कर सकता है, क्योंकि आप एक वेरिएबल का नाम गलत वर्तनी"

हां। यह।

लेकिन इस जावा कोड पर विचार करें।

public static void maine(String[] argv) { 
    int main; 
    int mian; 
} 

यहां एक गलत वर्तनी समान रूप से घातक है। सांख्यिकीय रूप से टाइप किए गए जावा ने कुछ भी किया है ताकि किसी गलत वर्तनी वाले नाम को बग के कारण से रोका जा सके।

+2

(1) कोई भी यह नहीं कह रहा है कि घोषणाएं गलत वर्तनी के कारण * सभी * गलतियों को रोकती हैं। (2) सी/सी ++ की आधा assed प्रकार प्रणाली एक (दक्षता-प्रेरित) हैक है, यकीन है, लेकिन उस ब्रश के साथ सभी दृढ़ता से टाइप की गई भाषाओं को पेंट नहीं करते हैं। जैसे जावा आपके "कारण" तर्क को तोड़ देता है। (3) क्या आपको नहीं लगता कि बाद में (रनटाइम पर) के बजाय जल्द ही एक प्रकार की त्रुटि (संकलन समय पर) खोजना बेहतर होगा? (4) मुझे बतख-टाइप की गई भाषाओं को भी पसंद है, लेकिन इसका मतलब यह नहीं है कि मजबूत टाइपिंग का कोई मूल्य नहीं है। –

+0

"क्या यह बग का कारण नहीं बन सकता है क्योंकि आपने एक चर का नाम गलत लिखा है" दोषपूर्ण है। मैं नहीं कह रहा हूं कि विकल्प सही हैं। मैं कह रहा हूं कि इस प्रश्न के शीर्ष पर धारणा गलत है। –

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