পাইথন - 'যদি fo ইন ডিক' বনাম চেষ্টা করুন: ডিক্ট [foo] '


24

আমি মনে করি হাঁসের টাইপিংয়ের প্রকৃতি এবং পাইথোনিক থাকার বিষয়ে আরও কম প্রশ্ন, আমার ধারণা।

প্রথমত - ডিক্টের সাথে কাজ করার সময়, বিশেষত যখন ডিকের কাঠামোটি মোটামুটি অনুমানযোগ্য হয় এবং প্রদত্ত কীটি সাধারণত উপস্থিত হয় না তবে কখনও কখনও হয়, আমি প্রথমে দুটি পদ্ধতির কথা ভাবি:

if myKey in dict:
    do_some_work(dict[myKey])
else:
    pass

এবং অবশ্যই ইয়ে ওলেডে 'ক্ষমা বনাম অনুমতি' পদ্ধতির কাছে।

try:
    do_some_work(dict[myKey])
except KeyError:
    pass

একজন ট্র্যাভেলম্যান পাইথন লোক হিসাবে আমার মনে হয় যে আমি দ্বিতীয়টিকে অনেক বেশি পছন্দ করেছি, যা কেবলমাত্র আমার কাছে অদ্ভুত লাগে বলে মনে হয় কারণ পাইথন ডকসগুলিতে try/exceptsযখন সত্যিকারের কোনও ভুল আছে তখন তার পছন্দ নেই বলে মনে হচ্ছে , সাফল্যের অভাবে?

যদি মাঝে মাঝে ডিকের মাইডিক্টে কী না থাকে এবং এটি পরিচিত যে এটি সর্বদা that চাবিটি রাখে না, তবে প্রসঙ্গগতভাবে বিভ্রান্তি বাদ দিয়ে কি চেষ্টা করা যায়? এটি কোনও প্রোগ্রামিং ত্রুটি নয়, এটি কেবলমাত্র তথ্যের একটি সত্য - এই ডিকটির ঠিক সেই নির্দিষ্ট কীটি ছিল না।

এটি বিশেষত গুরুত্বপূর্ণ মনে হয় যখন আপনি চেষ্টাটি / বাদে / অন্য বাক্য বিন্যাসের দিকে লক্ষ্য করেন, যা চেষ্টা করা হয় যে খুব বেশি ত্রুটি ধরা পড়ছে না তা নিশ্চিত করার ক্ষেত্রে এটি সত্যিই দরকারী বলে মনে হচ্ছে। আপনি এর মতো কিছু করতে সক্ষম:

try:
    foo += bar
except TypeError:
    pass
else:
    return some_more_work(foo)

এর ফলে কি এমন সব ধরণের অদ্ভুত ত্রুটি গিলতে পরিচালিত করে না যা সম্ভবত কিছু খারাপ কোডের ফলাফল? উপরের কোডটি কেবল আপনাকে যুক্ত করার চেষ্টা করছে 2 + {}এবং আপনি কখনই বুঝতে পারবেন না যে আপনার কোডের কিছু অংশ মারাত্মকভাবে ভুল হয়েছে। আমি প্রস্তাব দিচ্ছি না যে আমাদের সমস্ত প্রকারের পরীক্ষা করা উচিত, এজন্যই এটি পাইথন এবং জাভাস্ক্রিপ্ট নয় - তবে আবার চেষ্টা / প্রসঙ্গে চেষ্টা করে মনে হচ্ছে যে প্রোগ্রামটি এমন কিছু করা উচিত যা করা উচিত নয়, পরিবর্তে এটি করা উচিত চালিয়ে যেতে সক্ষম করার।

আমি বুঝতে পারলাম উপরের উদাহরণটি খড়ের সাথে যুক্তিযুক্ত কিছু, এবং বাস্তবে ইচ্ছাকৃতভাবে খারাপ। তবে পাইথোনিক ধর্মের ভিত্তিতে better to ask forgiveness than permissionআমি সাহায্য করতে পারছি না তবে মনে হচ্ছে এটি বালিতে রেখাটি সঠিকভাবে প্রয়োগের / অন্য বনাম চেষ্টা করা / বাদে সঠিক প্রয়োগের মধ্যে যেখানে প্রশ্ন রয়েছে, বিশেষত যখন আপনি জানেন কী কী আশা করবেন আপনি যে ডেটা নিয়ে কাজ করছেন তা

আমি এখানে গতির উদ্বেগ বা সর্বোত্তম অনুশীলনের কথাও বলছি না, আমি কেবল ধরণের ক্ষেত্রে অনুভূত ভেন ডায়াগ্রামের সাথে চুপচাপ বিভ্রান্ত হয়েছি যেখানে মনে হয় এটি কোনওভাবে যেতে পারে তবে লোকেরা চেষ্টা করে / বাদ দিয়ে ভুল করে কারণ 'কেউ কোথাও বলেছিল এটি পাইথোনিক'। আমি কি এই সিনট্যাক্সের প্রয়োগ সম্পর্কে ভুল সিদ্ধান্ত নিয়েছি?

python 

আমি সম্মত হই যে চেষ্টা ব্যতীত প্রবণতা ত্রুটিগুলি আড়াল করার ঝুঁকি চালায়। আমার মতামতটি হ'ল আপনি যে শর্তগুলি দেখেছেন সেগুলি বাদ দিয়ে সাধারণত চেষ্টা করা এড়ানো উচিত (অবশ্যই কিছু নিয়মনীতি এই নিয়মের ক্ষেত্রে প্রযোজ্য)।
গর্ডন বিন

উত্তর:


26

ব্যবহার করুন GET পদ্ধতি পরিবর্তে:

some_dict.get(the_key, default_value)

... default_valueমান the_keyনা থাকলে কোথায় ফিরে আসে some_dict? আপনি বাদ তাহলে default_value, Noneফিরিয়ে দেওয়া হয় কী অনুপস্থিত পারেন।

সাধারণভাবে, পাইথনে, লোকেরা প্রথমে কিছু পরীক্ষা করা বাদ দিয়ে চেষ্টা করতে পছন্দ করেন - গ্লোসারিটিতে ইএএফপি প্রবেশ দেখুন । নোট করুন যে অনেকগুলি "সদস্যতার জন্য পরীক্ষা" ফাংশনগুলি পর্দার আড়ালে ব্যতিক্রমগুলি ব্যবহার করে।


যদিও এই ধরণের সমস্যাটি একই রকম নয়? যদি আমরা কোনটির সাথে কাজ করার চেষ্টা করি dictএবং যা পাওয়া যায় তার উপর ভিত্তি করে কাজ করি, তবে মনে if myDict.get(a_key) is not None: do_work(myDict[a_key])হয় এটি শব্দভাবাপন্ন এবং লাফিয়ে উঠার আগে অন্তর্নিহিত দেখার আরও একটি উদাহরণ - প্লাস এটি সামান্য কম পঠনযোগ্য IMHO। সম্ভবত আমি dict.get(a_key, a_default)সঠিক প্রসঙ্গে বুঝতে পারছি না , তবে মনে হচ্ছে এটি 'নো-এ-স্যুইচ-স্টেটমেন্ট যদি / এলেস' বা যাদুবিদ্যার মান লেখার পূর্বসূরী। আমি এই পদ্ধতিটি যা করি তা পছন্দ করি তবে আমি এটি আরও গভীরভাবে দেখব।

1
@ স্টিক - আপনি করেন: data = myDict.get(a_key, default)এবং do_workপ্রদত্ত default(উদা। None) দেওয়ার সময় আপনি সঠিক কাজ করবেন বা আপনি করেন if data: do_work(data)। উভয় ক্ষেত্রে শুধুমাত্র একটি অনুসন্ধান প্রয়োজন। (এটি if data is not None: ...উভয় ক্ষেত্রেই হতে পারে , এটি এখনও কেবলমাত্র একটি
তদন্ত

1
সুতরাং আমি স্থির করেছি যে ডিক্টেজেট () আমার বর্তমান প্রকল্পে আমাকে অনেক চেষ্টা করেছে saved এটি আমার লাইন গণনা হ্রাস করেছে, প্রচুর ভয়ঙ্কর চেহারা try/except/elseজঙ্ক পরিষ্কার করেছে এবং আমার কোডটির পঠনযোগ্যতা কেবলমাত্র আইএমএইচওকে উন্নত করেছে। আমি একটি মূল্যবান পাঠ শিখেছি যা আমি এর আগে শুনেছি তবে তা মনে মনে অবহেলা করতে সক্ষম হয়েছি: "আপনার যদি মনে হয় আপনি খুব বেশি কোড লিখছেন তবে থামুন এবং ভাষার বৈশিষ্ট্যগুলি দেখুন"। ধন্যবাদ !!

@ স্টিক - এটি শুনে আনন্দিত :) আমি এই পরামর্শটি পছন্দ করি, এটি আগে কখনও শুনিনি।
অবধি

1
প্রযুক্তিগতভাবে, কোনটি দ্রুততম?
অলিভিয়ার পন্স

4

কী হারিয়ে যাওয়া কোনও নিয়ম বা ব্যতিক্রম ?

ব্যবহারিক দৃষ্টিকোণ থেকে, ছোঁড়া / ধরা অনেক ধীর গতিতে থাকে কি টেবিলে আছে কিনা তা পরীক্ষা করে। যদি হারিয়ে যাওয়া কীটি একটি সাধারণ ঘটনা - আপনার শর্তটি ব্যবহার করা উচিত।

শর্তের পক্ষে অন্য জিনিসটি অন্য একটি ধারা - এটি বোঝা অনেক সহজ যখন উভয়কে মৃত্যুদণ্ড কার্যকর করা হলে অবরুদ্ধ করা হয়, বিবেচনা করুন যে একই ব্যতিক্রম শ্রেণিটি চেষ্টা ব্লকের বেশ কয়েকটি বিবৃতি থেকে ফেলে দেওয়া যেতে পারে।

ধারা বাদে কোডটি স্বাভাবিক ত্রুটির একটি অংশ হওয়া উচিত নয় (উদাহরণস্বরূপ যদি কী সেখানে না থাকে তবে এটি যুক্ত করুন) - এটি ত্রুটিটি পরিচালনা করা উচিত।


4
"ব্যবহারিক দৃষ্টিকোণ থেকে, ছোঁড়া / ধরা অনেক ধীর গতিতে থাকে কি টেবিলে কী আছে কিনা তা পরীক্ষা করে" - না এটি নয় isn't অগত্যা, যাই হোক না কেন। সর্বশেষে আমি চেক করেছি, সর্বাধিক সাধারণ পাইথন প্রয়োগগুলি দ্রুত try/ catchসংস্করণে করে।
অবশেষে 23'13

2
পাইথন নিক্ষেপ / ক্যাচ করা কোনও ডিল পারফরম্যান্সের ভিত্তিতে এতটা বড় নয় যে এটি প্রায়শই পাইথনের প্রবাহ নিয়ন্ত্রণের জন্য ব্যবহৃত হয়। অতিরিক্তভাবে, কিছু পরিস্থিতিতে সম্ভাবনা রয়েছে যেখানে পরীক্ষা এবং অ্যাক্সেসের মধ্যে সেই ডিকটি সংশোধন করা যেতে পারে।
whatsisname

@ ওয়াটসিসনাম - আমি আমার উত্তরে এটি যোগ করার কথা ভেবেছিলাম, তবে টিবিএইচ যদি আপনার মতো রেসের ঝুঁকি থাকে তবে আপনার অনেক বড় সমস্যা রয়েছে যে ইএএফপি বনাম এলবিওয়িল: পি
যথাক্রমে

1

"পাইথোনিক" হওয়ার আত্মায় এবং বিশেষত হাঁসের টাইপিং - চেষ্টা / বাদে আমার কাছে প্রায় ভঙ্গুর মনে হয় looks

আপনি যা চান তা হ'ল ডিকের মতো অ্যাক্সেস সহ এমন কিছু যা __getitem__আপনার প্রত্যাশার মতো নয় এমন কিছু করতে ওভাররাইড করা যেতে পারে। উদাহরণস্বরূপ, defaultdictস্ট্যান্ডার্ড লাইব্রেরি থেকে ব্যবহার করে :

In [1]: from collections import defaultdict

In [2]: foo = defaultdict(int)

In [3]: foo['a'] = 1

In [4]: foo['b']  # Someone did access checking with a try/except exactly as you have in the question
Out[4]: 0

In [5]: 'a' in foo
Out[5]: True

In [6]: 'b' in foo  # We never set it, but now it exists!
Out[6]: True

In [7]: 'c' in foo
Out[7]: False

কারণ ডিফল্ট রিটার্ন মানটি ফালসি, এর মতো অ্যাক্সেস চেকিং বেশিরভাগ সময় ঠিক সূক্ষ্মভাবে কাজ করবে .. এটি কোডটি সহজ রাখে বলে মনে হয়, এ কারণেই আমার সহকর্মীরা এবং আমি কয়েক মাস ধরে এটি করেছিলাম।

দুর্ভাগ্যক্রমে, কয়েক মাস পরে, এই অতিরিক্ত কীগুলি আসলে সমস্যা এবং হার্ড-টু-ট্র্যাক-ডাউন বাগগুলি সৃষ্টি করেছিল, কারণ 0এটি একটি বৈধ মান হয়ে গেছে। এবং কখনও কখনও আমরা চাই ব্যবহার inকোড ভিন্ন কিছু করার যখন এটি অভিন্ন হওয়া উচিত ছিল উপার্জন, যদি একটি কী অস্তিত্ব বার করো।

কারণ হাঁস-টাইপ করার পাইথন এর আত্মা, সমস্ত আপনি চান উচিত কিছু অভি মত কারণ আমি আপনাকে পরামর্শ দিচ্ছি এটা ভেঙে দেখায়, এবং একটি defaultdictফিট করে প্রয়োজন পুরোপুরি, যেমন হবে কোন বস্তুর আপনি যে উত্তরাধিকারী থেকে তৈরি করতে পারেন dict। আপনি গ্যারান্টি দিতে পারবেন না যে কলার পরে তার প্রয়োগটি পরিবর্তন করে না রেখায়, সুতরাং আপনার কাজটি কমপক্ষে পার্শ্ব-প্রতিক্রিয়া সহ করা উচিত।

প্রথম সংস্করণ ব্যবহার করুন if myKey in mydict,।


এছাড়াও, নোট করুন যে এটি বিশেষত প্রশ্নের মধ্যে উদাহরণ সম্পর্কে। "অনুমতি চেয়ে ক্ষমা চাইতে আরও ভাল" এর অজগর ধর্মটি মূলত বোঝানো হয় যে আপনি যখন যা চান তা না পেলে আপনি আসলে সঠিকভাবে কাজ করেন। উদাহরণস্বরূপ, কোনও ফাইল উপস্থিত রয়েছে কিনা তা পরীক্ষা করে এবং সেখান থেকে পড়ার চেষ্টা করা - কমপক্ষে 3 টি জিনিস যা আমি আমার মাথার উপরের দিক থেকে ভাবতে পারি তা ভুল হতে পারে:

  • একটি রেসের শর্তটি হ'ল ফাইলটি মুছে ফেলা / সরানো / ইত্যাদি করা হতে পারে
  • আপনার কাছে ফাইলটিতে পড়ার অনুমতি নেই
  • ফাইলটি দূষিত হয়েছে

আপনি প্রথমে "অনুমতি চাইতে" চেষ্টা করতে পারেন, তবে একটি বর্ণের অবস্থার প্রকৃতির দ্বারা এটি সর্বদা কার্যকর হয় না; দ্বিতীয়টি পরীক্ষা করা ভুলে যাওয়া খুব সহজ; এবং তৃতীয়টি ফাইলটি পড়ার চেষ্টা না করে চেক করা যায় না। যাই হোক, আপনি ব্যর্থ প্রায় অবশ্যই, একই হবে যাতে পরে কি এই উদাহরণ, এটা হয় ভাল "মাগফেরাত কামনা" ব্যবহার করে দেখুন ব্যবহার করে / ছাড়া।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.