python: এই জায়গাগুলোতে সাবধান হোন।
python是一门非常有趣的语言。它提供了许多非常方便的标准库和许多内置命令是我们轻松完成任务.但是好东西太多了就有选择恐惧症了,以至于我们不能很好第利用这个标准库和它的基本机构。下面列出了一些对python新手来说很简单有效的陷阱。
পাইথন সংস্করণ উপেক্ষা করুন
এটা এমন একটি প্রশ্ন যা StackOverflow-এ প্রতিনিয়ত উত্থাপিত হচ্ছে। আপনি যখন আপনার নিখুঁত কোড অন্য কারও কম্পিউটারে চালাচ্ছেন তখন ভুল করার অভিজ্ঞতা কেমন, তাই আপনার পাইথনের সংস্করণগুলি কি একই তা পরীক্ষা করার সময় এটি দরকার। আপনি যে পাইথন সংস্করণটি জানেন তা নিশ্চিত করুন। আপনি নিম্নলিখিত কোডটি ব্যবহার করে পাইথন সংস্করণগুলি দেখতে পারেনঃ
$ python --version
Python 2.7.9
পাইথন সংস্করণ ব্যবস্থাপনা
pyenv একটি ভাল পাইথন সংস্করণ পরিচালন সরঞ্জাম. দুর্ভাগ্যবশত এটি শুধুমাত্র *nix সিস্টেমে চলে। ম্যাক OS এ, আপনি সহজেই brew install pyenv ইনস্টল করতে পারেন। লিনাক্স সিস্টেমে একটি স্বয়ংক্রিয় ইনস্টলার রয়েছে।
এক লাইন কোড দিয়ে সব সমস্যার সমাধান করার ঝামেলা
অনেকে গর্ব করে যে আমি এক লাইন কোড দিয়ে সমস্ত সমস্যা সমাধান করেছি, এমনকি যদি তাদের কোডটি স্বাভাবিকের চেয়ে কম কার্যকর হয়, এবং কোডগুলি পড়তে আরও কঠিন এবং এমনকি বিভ্রান্তিকর হয়; উদাহরণস্বরূপঃ
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 })
উপরের উদাহরণটি এটি দেখায়। set একটি পাত্রে list রাখার মত। তাদের মধ্যে পার্থক্য হল সেটটি পুনরাবৃত্তিহীন এবং অনিয়মিত। {} সাধারণত একটি খালি সেট হিসাবে বিবেচিত হয়, কিন্তু এটি নয়, এটি একটি খালি ডিক্ট।
>>> {}
{}
>>> type({})
সুতরাং যদি আমরা একটি ফাঁকা সেট ইনসিওল করতে চাই, তাহলে আমরা সরাসরি সেট ((() ব্যবহার করব।
>>> set()
set()
>>> type(set())
মনে রাখবেন যে একটি ফাঁকা সেটকে সেট হিসাবে উল্লেখ করা যেতে পারে, কিন্তু এটি এমন একটি সেট যা উপাদানগুলি অন্তর্ভুক্ত করে যা সেট হিসাবে সংজ্ঞায়িত করা হবে (([1, 2]) ।
ভুল বোঝাবুঝি জিআইএল
জিআইএল (গ্লোবাল ইন্টারপ্রেটার লক) মানে হল যে শুধুমাত্র একটি থ্রেড একটি পাইথন প্রোগ্রামের মধ্যে যে কোন সময় চালানো যেতে পারে। এর মানে হল যে আমরা যখন একটি থ্রেড তৈরি করতে পারি না এবং এটি সমান্তরালভাবে চালানোর আশা করি। পাইথন ইন্টারপ্রেটার আসলে যা করে তা হল দ্রুত বিভিন্ন রান স্ট্রিংগুলির মধ্যে স্যুইচ করা। কিন্তু এটি একটি খুব সহজ সংস্করণ। অনেক ক্ষেত্রে প্রোগ্রামগুলি সমান্তরালভাবে চালিত হয়, যেমন সি এক্সটেনশন ল্যাবরেটরি ব্যবহার করা হয়। কিন্তু পাইথন কোডটি বেশিরভাগ সময় সমান্তরালভাবে চালিত হয় না। অন্য কথায়, পাইথনে থ্রেডগুলি জাভা বা সি++ এর মতো নয়।
অনেক লোক পাইথনকে যুক্তি দেওয়ার চেষ্টা করবে যে এগুলি সবই সত্যিকারের থ্রেড। 3 এটি সত্য, তবে এটি এই সত্যটিকে পরিবর্তন করে নাঃ পাইথন থ্রেডগুলিকে আপনি প্রত্যাশা করেন না এমনভাবে পরিচালনা করে। রুবিতেও অনুরূপ পরিস্থিতি ((এবং একটি ব্যাখ্যাকারী লক রয়েছে) ।) ।
প্রস্তাবিত সমাধান হল মাল্টিপ্রসেসিং মডিউল ব্যবহার করা; মাল্টিপ্রসেসিং মডিউল দ্বারা প্রদত্ত প্রক্রিয়াগুলি মূলত পার্থক্যগুলিকে ভালভাবে আবরণ করে। তবে, পার্থক্যগুলি থ্রেডের ব্যয়ের চেয়ে অনেক বেশি; তাই সমান্তরালভাবে চালানো সর্বদা ভাল নয়।
যাইহোক, এই সমস্যাটি প্রতিটি পাইথন প্রোগ্রামের সাথে দেখা হয় না। PyPy-stm হল পাইথনের একটি বাস্তবায়ন যা জিআইএল দ্বারা প্রভাবিত হয় না। অন্যান্য প্ল্যাটফর্মের উপর নির্মিত বাস্তবায়নগুলি যেমন JVM (Jython) বা CLR (IronPython) জিআইএল ছাড়াই সমস্যা করে।
যাইহোক, থ্রেড ক্লাস ব্যবহার করার সময় সাবধান হোন, আপনি যা চান তা নাও পেতে পারেন।
অপ্রচলিত স্টাইল ক্লাস ব্যবহার করুন
পাইথন ২-তে দুই ধরনের ক্লাস আছে, পুরাতন প্রকারের ক্লাস এবং নতুন প্রকারের ক্লাস। আপনি যদি পাইথন ৩-তে থাকেন, তাহলে আপনি ডিফল্টভাবে নতুন প্রকারের ক্লাস ব্যবহার করছেন। পাইথন ২-তে নতুন প্রকারের ক্লাস ব্যবহার করার জন্য, আপনাকে অবজেক্ট বা আপনার তৈরি করা যে কোনো নতুন ক্লাসকে উত্তরাধিকার করতে হবে যা সর্বদা অন্তর্নির্মিত নির্দেশ int বা list-এর উত্তরাধিকারী হয় না। অন্য কথায়, আপনার বেস ক্লাসটি সর্বদা অবজেক্ট-এর উত্তরাধিকারী হওয়া উচিত।
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-কে বারবার এই ফাংশনটি কল করার সময় পুনরায় উল্লেখ করা হয়। এটি কিছু খুব অপ্রয়োজনীয় পরিণতি হতে পারে।