संसाधन लोड हो रहा है... लोड करना...

python: कृपया इन स्थानों से सावधान रहें

लेखक:इलिदान, बनाया गयाः 2016-12-29 13:46:12, अद्यतन किया गयाः

python: कृपया इन स्थानों से सावधान रहें

python是一门非常有趣的语言。它提供了许多非常方便的标准库和许多内置命令是我们轻松完成任务.但是好东西太多了就有选择恐惧症了,以至于我们不能很好第利用这个标准库和它的基本机构。下面列出了一些对python新手来说很简单有效的陷阱。

  • पायथन के संस्करण को अनदेखा करें

    यह एक सवाल है जो StackOverflow पर बार-बार उठाया जाता है. जब आप किसी और के कंप्यूटर पर अपना सही कोड चला रहे होते हैं तो यह एक त्रुटिपूर्ण अनुभव होता है, इसलिए यह समय है कि आप अपने पायथन संस्करणों को एक साथ जांचें। सुनिश्चित करें कि कोड आपके द्वारा जाने जाने वाले पायथन संस्करणों पर चल रहा है। आप निम्न कोड के माध्यम से पायथन संस्करण देख सकते हैंः

    $ python --version
    Python 2.7.9
    

    python संस्करण प्रबंधक

    pyenv एक अच्छा पायथन संस्करण प्रबंधक उपकरण है. दुर्भाग्य से यह केवल *nix सिस्टम पर चलता है. मैक ओएस पर, आप आसानी से पीएनवी को स्थापित कर सकते हैं।

  • कोड की एक पंक्ति के साथ सभी समस्याओं को हल करने के लिए उलझन

    बहुत से लोग कहते हैं कि मैं एक पंक्ति कोड के साथ सभी समस्याओं को हल करता हूं, भले ही उनका कोड सामान्य रूप से लिखे गए कोड की तुलना में कम कुशल हो, और यह कोड पढ़ने में अधिक कठिन हो, या यहां तक कि अस्पष्ट हो; उदाहरण के लिएः

    l = [m for a, b in zip(this, that) if b.method(a) != b for m in b if not m.method(a, b) and reduce(lambda x, y: a + y.method(), (m, a, b))]
    

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

    कोड की एक पंक्ति का नियंत्रण कोई बड़ी उपलब्धि नहीं है, हालांकि यह कभी-कभी विशेष रूप से बुद्धिमान लग सकता है। अच्छा कोड संक्षिप्त है लेकिन दक्षता और आसानी से पढ़ने पर अधिक ध्यान केंद्रित करता है।

  • सेट को गलत तरीके से आरंभ किया गया

    这是一个更加微妙的问题,有时候会让你措手不及。set推导式起来有点像list推导式.

    >>> { n for n in range(10) if n % 2 == 0 }
    {0, 8, 2, 4, 6}
    >>> type({ n for n in range(10) if n % 2 == 0 })
    

    उपरोक्त उदाहरण इस बात को दर्शाता है । सेट कंटेनर में सूची की तरह है । इनका अंतर यह है कि सेट दोहराने योग्य नहीं है और अनियमित है. लोग आमतौर पर {} को एक खाली सेट के रूप में देखते हैं, लेकिन यह नहीं है, यह एक खाली डिक्ट है।

    >>> {}
    {}
    >>> type({})
    

    तो अगर हम एक खाली सेट को आरंभ करना चाहते हैं, तो हम सीधे सेट का उपयोग करते हैं।

    >>> set()
    set()
    >>> type(set())
    

    ध्यान दें कि एक खाली सेट को सेट के रूप में दर्शाया जा सकता है, लेकिन यह एक ऐसा सेट है जिसमें तत्व हैं जिसे सेट के रूप में परिभाषित किया जाना है (([1, 2]) ।

  • गलतफहमी जीआईएल

    GIL (global interpreter lock) का अर्थ है कि किसी भी समय केवल एक ही थ्रेड एक पायथन प्रोग्राम में चलाया जा सकता है। इसका मतलब है कि जब हम एक थ्रेड नहीं बना सकते और इसे समानांतर में चलाने की उम्मीद नहीं कर सकते। पायथन व्याख्याकार वास्तव में जो करता है वह है विभिन्न चल रहे थ्रेडों को जल्दी से स्विच करना। लेकिन यह एक बहुत ही सरल संस्करण है। कई उदाहरणों में प्रोग्राम समानांतर में चलता है, जैसे कि सी एक्सटेंडेड लाइब्रेरी का उपयोग करते समय। लेकिन पायथन कोड के अधिकांश भाग में समानांतर में निष्पादित नहीं होता है जब यह चलाया जाता है। दूसरे शब्दों में, पायथन में थ्रेड जावा या सी ++ में नहीं होते हैं।

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

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

    हालाँकि, यह समस्या हर पायथन प्रोग्राम के साथ नहीं होती है. PyPy-stm एक ऐसा पायथन कार्यान्वयन है जो जीआईएल से प्रभावित नहीं है. अन्य प्लेटफार्मों पर निर्मित कार्यान्वयन जैसे कि JVM (Jython) या CLR (IronPython) में जीआईएल की समस्या नहीं है.

    संक्षेप में, थ्रेड क्लास का उपयोग करते समय सावधान रहें, आपको वह नहीं मिल सकता है जो आप चाहते हैं।

  • अप्रचलित शैली वर्गों का उपयोग करना

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

    class MyNewObject(object): # stuff here
    

    ये नए वर्ग तालिकाएं कुछ बहुत ही बुनियादी समस्याओं को ठीक करती हैं जो पुराने वर्गों में दिखाई देती हैं, यदि आप रुचि रखते हैं तो आप दस्तावेज़ को देख सकते हैं।

  • गलत पुनरावृत्ति

    ये गलतियाँ नए लोगों के लिए बहुत आम हैं:

    for name_index in range(len(names)):
      print(names[name_index])
    

    यह स्पष्ट है कि len का उपयोग करना आवश्यक नहीं है, और वास्तव में सूची में बहुत सरल वाक्यांशों के साथ किया जा सकता हैः

    for name in names:
       print(name)  
    

    इसके अलावा, कई अन्य उपकरण हैं जो आपको सरल पुनरावृत्ति के साथ काम करने में मदद करते हैं। उदाहरण के लिए, ज़िप का उपयोग दो सूचियों को पार करने के लिए किया जा सकता हैः

    for cat, dog in zip(cats, dogs):
       print(cat, dog)
    

    यदि हम सूची के लिए एक सूचकांक और एक वैल्यू वेरिएबल के बारे में सोच रहे हैं, तो हम enumerate का उपयोग कर सकते हैं।

    for index, cat in enumerate(cats):
       print(cat, index)
    

    itertools में भी बहुत सारे फ़ंक्शन हैं जिनसे आप चुन सकते हैं. अगर itertools में कोई फ़ंक्शन है जो आप चाहते हैं तो इसे लेना आसान है. लेकिन इसे इस्तेमाल करने के लिए भी इसका उपयोग न करें.

    itertools दुरुपयोग ने StackOverflow पर एक बड़े भगवान को इसे ठीक करने में बहुत समय लगा दिया।

    एक वैरिएबल डिफ़ॉल्ट पैरामीटर का उपयोग करना

    मैंने बहुत कुछ देखा हैः

    def foo(a, b, c=[]):
       # append to c
       # do some more stuff
    

    एक वैरिएबल डिफ़ॉल्ट पैरामीटर का उपयोग न करें, बल्कि निम्न का उपयोग करेंः

    def foo(a, b, c=None):
     if c is None:
       c = []
       # append to c
       # do some more stuff 
    

    इस सवाल को समझने के लिए नीचे दिए गए उदाहरण का उपयोग करना बहुत सहज है:

    In[2]: def foo(a, b, c=[]):
    ...     c.append(a)
    ...     c.append(b)
    ...     print(c)
    ...
    In[3]: foo(1, 1)
    [1, 1]
    In[4]: foo(1, 1)
    [1, 1, 1, 1]
    In[5]: foo(1, 1)
    [1, 1, 1, 1, 1, 1]
    

    एक ही c को इस फ़ंक्शन को बार-बार कॉल करने के लिए बार-बार संदर्भित किया जाता है. इससे कुछ बहुत अनावश्यक परिणाम हो सकते हैं.


अधिक