पायथन: कृपया इन स्थानों पर सावधान रहें
python एक बहुत ही रोचक भाषा है. यह कई बहुत ही सुविधाजनक मानक पुस्तकालय प्रदान करता है और कई अंतर्निहित आदेश हैं जो हमें आसानी से कार्य पूरा करने के लिए हैं. लेकिन बहुत सारी अच्छी चीजें हैं जो चयनात्मकता से डरती हैं कि हम इस मानक पुस्तकालय और इसकी बुनियादी संस्थाओं का बहुत अच्छा उपयोग नहीं कर सकते हैं. नीचे कुछ सरल और प्रभावी पाइथन नौसिखियों के लिए जाल दिए गए हैं.
यह StackOverflow पर लगातार उठाया जाने वाला एक सवाल है। जब आपका सही कोड किसी और के कंप्यूटर पर चलता है तो यह कैसा अनुभव होता है, इसलिए आपको यह जांचने की आवश्यकता है कि क्या आपके पायथन संस्करण संगत हैं। सुनिश्चित करें कि कोड आपके द्वारा ज्ञात पायथन संस्करण पर चल रहा है। आप निम्न कोड के माध्यम से पायथन संस्करण देख सकते हैंः
$ python --version
Python 2.7.9
python संस्करण प्रबंधन
pyenv एक अच्छा python संस्करण प्रबंधक है. दुर्भाग्य से यह केवल*nix पर. Mac OS पर, आप बस पीएनवी को ब्रीव इंस्टॉल करके इंस्टॉल कर सकते हैं, और लिनक्स पर, एक स्वचालित इंस्टॉलर है।
बहुत से लोगों का दावा है कि मैं एक पंक्ति कोड के साथ सभी समस्याओं को हल कर सकता हूं, भले ही उनके कोड सामान्य रूप से लिखे गए कोड की तुलना में अधिक अक्षम हों, और वे पढ़ने में अधिक कठिन हो सकते हैं, और यहां तक कि असंगत भी हो सकते हैं।
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))]
ईमानदारी से, मैंने यह कोड खुद के लिए लिखा है ताकि यह स्पष्ट हो सके कि यह कैसे करना है। लेकिन मैंने वास्तव में कई लोगों को ऐसा करते हुए देखा है। यदि आप केवल एक सूची या एक सेट में कुछ जोड़कर जटिल समस्याओं को हल करने के लिए अपने स्वयं के साधनों को प्रदर्शित करते हैं, तो आप बहुत कुछ खो सकते हैं।
कोड की एक पंक्ति को नियंत्रित करना कोई बड़ी उपलब्धि नहीं है, हालांकि यह कभी-कभी विशेष रूप से बुद्धिमान दिखता है। अच्छा कोड संक्षिप्त है लेकिन दक्षता और पढ़ने में आसानी पर अधिक ध्यान केंद्रित करता है।
यह एक और अधिक सूक्ष्म प्रश्न है, और कभी-कभी यह आपको आश्चर्यचकित कर सकता है। सेट अनुमान एक सूची अनुमान की तरह है।
>>> { 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 })
उपरोक्त उदाहरण इस बात को दर्शाता है. set थोड़ा सा कंटेनर में list की तरह है इनका अंतर यह है कि सेट में कोई दोहराने वाला मान नहीं है और यह क्रमहीन है. लोग आमतौर पर {} को एक खाली सेट मानते हैं, लेकिन यह नहीं है, यह एक खाली डिक्ट है.
>>> {}
{}
>>> type({})
तो अगर हम एक खाली सेट को इनिशियलाइज़ करना चाहते हैं, तो हम सीधे set () का उपयोग करते हैं.
>>> set()
set()
>>> type(set())
ध्यान दें कि एक रिक्त सेट को set () के रूप में दर्शाया जा सकता है, लेकिन तत्वों के एक सेट को set () के रूप में परिभाषित किया जाना चाहिए।[1, 2]) जैसा दिखता है।
GIL (ग्लोबल इंटरप्रिटर लॉक) का अर्थ है कि एक पायथन प्रोग्राम में केवल एक ही थ्रेड किसी भी समय चल सकता है। इसका मतलब है कि जब हम एक थ्रेड नहीं बना सकते हैं और इसे समानांतर रूप से चलाने की उम्मीद कर सकते हैं। पायथन इंटरप्रिटर वास्तव में क्या करता है, विभिन्न चल रहे थ्रेड को जल्दी से स्विच करना है। लेकिन यह एक बहुत ही सरल संस्करण है। कई उदाहरणों में प्रोग्राम समानांतर रूप से चलते हैं, जैसे कि सी एक्सटेंशन लाइब्रेरी का उपयोग करते समय। लेकिन जब पायथन कोड चलता है, तो अधिकांश समय यह निष्पादित नहीं होता है। दूसरे शब्दों में, पायथन में थ्रेड नहीं होते हैं जैसे कि जावा या सी ++ में होते हैं।
3 यह सच है, लेकिन यह इस तथ्य को नहीं बदलता है कि पायथन आपके द्वारा अपेक्षित होने के विपरीत एक धागे को संभालता है। रूबी में भी एक समान स्थिति है (और एक व्याख्याकार लॉक है) ।
निर्धारित समाधान एक बहुप्रसंस्करण मॉड्यूल का उपयोग करना है. बहुप्रसंस्करण मॉड्यूल द्वारा प्रदान की जाने वाली प्रक्रिया वर्गों को मूल रूप से बहुत अच्छी तरह से अंतर को कवर किया जा सकता है. हालांकि, अंतर की लागत थ्रेड की तुलना में बहुत अधिक है. इसलिए समानांतर रूप से चलना हमेशा अच्छा नहीं होता है.
हालांकि, यह समस्या हर पायथन प्रोग्राम के साथ नहीं होती है। पायथन-एसटीएम एक उदाहरण है जहां पायथन का कार्यान्वयन जीआईएल से अप्रभावित है। अन्य प्लेटफार्मों पर आधारित कार्यान्वयन जैसे जेवीएम (Jython) या सीएलआर (IronPython) में जीआईएल की समस्या नहीं है।
अंत में, उपयोग करते समय सावधानी बरतें, क्योंकि आपको जो मिलता है वह वह नहीं हो सकता है जो आप चाहते हैं।
पायथन 2 में दो प्रकार की कक्षाएं हैं, पुरानी शैली की कक्षाएं और नई शैली की कक्षाएं। यदि आप पायथन 3 का उपयोग कर रहे हैं, तो आप डिफ़ॉल्ट नई शैली की कक्षाओं का उपयोग कर रहे हैं। यह सुनिश्चित करने के लिए कि आप पायथन 2 में नई शैली की कक्षाओं का उपयोग कर रहे हैं, आपको ऑब्जेक्ट को विरासत में लेना होगा या आप जो भी नई कक्षाएं बनाते हैं, वे हमेशा अंतर्निहित निर्देशों को विरासत में नहीं लेते हैं।
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 के दुरुपयोग ने 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 को हर बार और हर बार संदर्भित किया जाता है जब फ़ंक्शन को बुलाया जाता है। इससे कुछ बहुत अनावश्यक परिणाम हो सकते हैं।