পাইথনের খারাপ / অবৈধ যুক্তির সংমিশ্রণে আমার কোন ব্যতিক্রম উত্থাপন করা উচিত?


542

আমি পাইথনে অবৈধ যুক্তি সংমিশ্রনের ইঙ্গিত করার জন্য সেরা অনুশীলনগুলি সম্পর্কে ভাবছিলাম। আমি কয়েকটি পরিস্থিতিতে এসেছি যেখানে আপনার মত একটি ফাংশন রয়েছে:

def import_to_orm(name, save=False, recurse=False):
    """
    :param name: Name of some external entity to import.
    :param save: Save the ORM object before returning.
    :param recurse: Attempt to import associated objects as well. Because you
        need the original object to have a key to relate to, save must be
        `True` for recurse to be `True`.
    :raise BadValueError: If `recurse and not save`.
    :return: The ORM object.
    """
    pass

এটির সাথে একমাত্র বিরক্তি হ'ল প্রতিটি প্যাকেজের নিজস্ব থাকে, সাধারণত কিছুটা পৃথক হয় BadValueError। আমি জানি যে জাভাতে রয়েছে java.lang.IllegalArgumentException- এটি কি ভালভাবে বোঝা গেছে যে প্রত্যেকে BadValueErrorপাইথনে নিজের নিজস্ব তৈরি করবে বা অন্য কোনও পছন্দসই পদ্ধতি রয়েছে?

উত্তর:


608

আপনার যদি আরও নির্দিষ্ট ব্যতিক্রম না হয় তবে আমি কেবল মান বাড়িয়ে তুলব ..

def import_to_orm(name, save=False, recurse=False):
    if recurse and not save:
        raise ValueError("save must be True if recurse is True")

সত্যিই করার কোনও অর্থ নেই class BadValueError(ValueError):pass- আপনার কাস্টম ক্লাসটি ভ্যালুআরারের ব্যবহারে অভিন্ন , সুতরাং কেন এটি ব্যবহার করবেন না?


65
> "তাহলে কেন তা ব্যবহার করবেন না?" - নির্দিষ্টতা। সম্ভবত আমি কিছু বাইরের স্তর "মাইভ্যালু এরির" ধরতে চাই, তবে কোনও / সমস্ত "ভ্যালুয়েরর" নয়।
কেভিন লিটল

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

3
আমি নিশ্চিত নই যে এই যুক্তিটি ধারণ করেছে: যদি কেউ কল করে math.sqrt(-1), এটি একটি প্রোগ্রামিং ত্রুটি যা যে কোনও উপায়ে ঠিক করা দরকার। ValueErrorসাধারণ প্রোগ্রাম কার্যকর করার সময় ধরা পড়ার উদ্দেশ্যে নয় বা এটি থেকে নেওয়া হবে RuntimeError

2
যদি ত্রুটিটি যদি আর্গুমেন্টের সংখ্যাটিতে হয় তবে একটি চলক সংখ্যক তর্ক যুক্তিযুক্ত ফাংশনের জন্য ... উদাহরণস্বরূপ এমন একটি ফাংশন যেখানে আর্গুমেন্টগুলি একটি যুক্তিগুলির সমান সংখ্যক হতে হবে, তারপরে আপনার সামঞ্জস্য বজায় রাখার জন্য একটি টাইপরর বাড়াতে হবে। ক) আপনার ব্যবহারের কেস না থাকলে বা খ) আপনি নিজের লাইব্রেরি অন্যের ব্যবহারের জন্য রফতানি না করে নিজের শ্রেণি তৈরি করবেন না। অকাল কার্যকারিতা কোডের মৃত্যু।
এরিক অ্যারোনস্টি

104

আমি থেকে উত্তরাধিকারী হবে ValueError

class IllegalArgumentError(ValueError):
    pass

কখনও কখনও নিজের ব্যতিক্রমগুলি তৈরি করা আরও ভাল তবে কোনও বিল্ট-ইন থেকে উত্তরাধিকারী হন, যা আপনি যতটা সম্ভব চান তার কাছাকাছি।

আপনার যদি সেই নির্দিষ্ট ত্রুটিটি ধরা দরকার তবে একটি নাম রাখা সহায়ক have


26
ক্লাস এবং কাস্টম ব্যতিক্রমগুলি লিখতে বন্ধ করুন - pyvideo.org/video/880/stop-writing-class
হামিশ গ্রুবিজন

40
@ হামিশগ্রবিজন এই ভিডিওটি ভয়ানক। যখনই কেউ ক্লাসের ভাল ব্যবহারের পরামর্শ দিয়েছিল, তখন তিনি "ব্লগ ব্যবহার করবেন না" সবেমাত্র রক্তাক্ত করেছেন। উজ্জ্বল। ক্লাস ভাল হয়। তবে এর জন্য আমার কথাটি নেবেন না
রব গ্রান্ট

12
@ রবার্টগ্রান্ট না, আপনি এটি পাবেন না। সেই ভিডিওটি আসলে আক্ষরিক "ক্লাস ব্যবহার করবেন না" সম্পর্কে নয়। এটি জিনিসগুলিকে অত্যধিক জটিল না করার বিষয়ে।
রায়লুও

15
@ রায়লুও আপনার কাছে ভিডিওটি কী বলেছে তা নির্দোষভাবে পরীক্ষা করে দেখতে পারা যায় এবং এটিকে একটি মনোজ্ঞ, বোধগম্য বিকল্প বার্তায় রূপান্তরিত করতে পারে তবে ভিডিওটি এটি বলে, এবং যার অভিজ্ঞতা নেই এবং সাধারণ জ্ঞান নেই সে চলে আসবে সঙ্গে.
রব গ্রান্ট

3
@ সামুয়েলসন্তান যেমন আমি বলেছিলাম, যে কোনও সময় কেউ তাদের হাত তুলে "এক্স এর কী হবে?" যেখানে এক্স ভাল ধারণা ছিল, তিনি কেবল বলেছিলেন, "অন্য কোনও ক্লাস তৈরি করবেন না।" বেশ স্পষ্ট. আমি সম্মতি জানাই কী ব্যালেন্স; সমস্যাটি আসলে :-) দ্বারা লাইভ করা খুব অস্পষ্ট
রব গ্রান্ট

18

আমি মনে করি এটি হ্যান্ডেল করার সর্বোত্তম উপায় হ'ল পাইথন নিজেই এটি পরিচালনা করে। পাইথন একটি টাইপরর উত্থাপন করে। উদাহরণ স্বরূপ:

$ python -c 'print(sum())'
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: sum expected at least 1 arguments, got 0

আমাদের জুনিয়র দেব সদ্য এই পৃষ্ঠাটি "অজগর ব্যতিক্রম ভুল যুক্তি" সন্ধানের জন্য একটি গুগল অনুসন্ধানে খুঁজে পেয়েছিলেন এবং আমি অবাক হয়েছি যে এই প্রশ্নটি জিজ্ঞাসা করার পর থেকে দশকের দশকের মধ্যে আমার কাছে স্পষ্ট (আমার কাছে) উত্তর কখনও প্রস্তাব করা হয়নি।


8
কিছুই আমাকে অবাক করে দেয় না তবে আমি 100% এর সাথে সম্মত হই যে ফাংশনে পাস হওয়া কিছু আর্গুমেন্টের মধ্যে টাইপটি ভুল হলে টাইপররার সঠিক ব্যতিক্রম। ভ্যারিয়েবলগুলি সঠিক ধরণের হয় তবে তাদের বিষয়বস্তু এবং মানগুলি বোঝায় না যদি একটি ভ্যালুআরর উপযুক্ত।
ব্যবহারকারী3504575

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

2
@ ব্যবহারকারী3504575 এবং @ নোবডি যেমন বলেছে, টাইপআরআর ব্যবহার করা হয় যদি আর্গুমেন্টগুলি ফাংশনের স্বাক্ষরের সাথে মিল না দেয় (অবস্থানগত আর্গুমেন্টের ভুল সংখ্যা, ভুল নামের সাথে কীওয়ার্ড আর্গুমেন্ট, ভুল প্রকারের যুক্তি), তবে ফাংশন কল করার সময় একটি ভ্যালুআরর ব্যবহৃত হয় স্বাক্ষরের সাথে মেলে তবে যুক্তির মানগুলি অবৈধ (যেমন, কল করা int('a')) calling উত্স
গুডমামি

ওপির প্রশ্নটি "অবৈধ যুক্তি সংমিশ্রণগুলি" হিসাবে উল্লেখ করা হয়েছে বলে মনে হয় যে এটি টাইপরর যথাযথ হবে কারণ এটি এমন একটি মামলা যেখানে ফাংশনের স্বাক্ষরটি মূলত পাস হওয়া যুক্তির জন্য ভুল।
জে

আপনার উদাহরণটি sum()কোনও যুক্তি ছাড়াই কল করে, যা একটি TypeError, কিন্তু ওপি যুক্তির মানগুলি সঠিক হলে "অবৈধ" সংশ্লেষের সাথে সম্পর্কিত ছিল। এই ক্ষেত্রে, উভয় saveএবং recursebools, কিন্তু যদি recurseহয় Trueতবে তা saveহওয়া উচিত নয় False। এটি একটি ValueError। আমি সম্মত হই যে প্রশ্নের শিরোনামের কিছু ব্যাখ্যা উত্তর দেওয়া হবে TypeErrorতবে উপস্থাপিত উদাহরণের জন্য নয়।
গুডমামি


8

এটি আর্গুমেন্টগুলির সাথে কী সমস্যা তা নির্ভর করে।

যদি যুক্তিটি ভুল টাইপ করে থাকে তবে একটি টাইপআররের উত্থাপন করুন। উদাহরণস্বরূপ, আপনি যখন সেই বুলিয়ানগুলির মধ্যে একটির পরিবর্তে একটি স্ট্রিং পান।

if not isinstance(save, bool):
    raise TypeError(f"Argument save must be of type bool, not {type(save)}")

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

যদি যুক্তিগুলির অবৈধ মান থাকে, তবে ভ্যালুআরারের উত্থাপন করুন। এটি আপনার ক্ষেত্রে আরও উপযুক্ত বলে মনে হচ্ছে:

if recurse and not save:
    raise ValueError("If recurse is True, save should be True too")

বা এই নির্দিষ্ট ক্ষেত্রে, পুনরাবৃত্তির একটি সত্য মানটি সংরক্ষণের সত্যিকারের মান বোঝায়। যেহেতু আমি এটিকে একটি ত্রুটি থেকে পুনরুদ্ধার হিসাবে বিবেচনা করব তাই আপনি লগেও অভিযোগ করতে চাইতে পারেন।

if recurse and not save:
    logging.warning("Bad arguments in import_to_orm() - if recurse is True, so should save be")
    save = True

আমি মনে করি এটিই সবচেয়ে সঠিক উত্তর। এটি স্পষ্টতই আন্ডাররেটেড (খনি সহ এখনও পর্যন্ত 7 টি ভোট)।
সিউ চিং পং-আসুকা কেনজি-

-1

আমি নিশ্চিত আমি কাছ থেকে উত্তরাধিকার সূত্রে সাথে একমত ValueError- নথিপত্রের আমার ব্যাখ্যা যে ValueErrorহয় শুধুমাত্র builtins দ্বারা উত্থাপিত হওয়ার কথা ... এটা থেকে উত্তরাধিকার সূত্রে প্রাপ্ত অথবা এটি উত্থাপন নিজেকে ভুল বলে মনে হয়।

উত্থাপিত যখন কোনও অন্তর্নির্মিত ক্রিয়াকলাপ বা ফাংশনটি একটি যুক্তি পায় যা সঠিক টাইপ করে তবে একটি অনুপযুক্ত মান, এবং পরিস্থিতি সূচিপত্র হিসাবে আরও সুনির্দিষ্ট ব্যতিক্রম দ্বারা বর্ণিত হয় না।

- ভ্যালুএররের ডকুমেন্টেশন


Google.com/codesearch?q=lang:python+class \ + \ w ত্রুটি (([[^ E] \ w * | E [^ x] \ w ))) এর সাথে তুলনা করুন : google.com/codesearch?q=lang সাথে: পাইথন + ক্লাস \ + \
ডাব্লু

13
এই ব্লার্বের সহজ অর্থ হ'ল বিল্ট-ইনগুলি এটি উত্থাপন করে এবং কেবল বিল্ট-ইনগুলিই এটি উত্থাপন করতে পারে না। বাইরের লাইব্রেরিগুলি কী উত্থাপন করে সে সম্পর্কে কথা বলা পাইথন ডকুমেন্টেশনের পক্ষে এই উদাহরণে সম্পূর্ণভাবে উপযুক্ত হবে না।
Ignacio Vazquez-Abram

5
পাইথন সফটওয়্যারটির প্রতিটি টুকর আমি ValueErrorএই ধরণের জিনিসটির জন্য ব্যবহার করেছি , সুতরাং আমি মনে করি আপনি ডকুমেন্টেশনে খুব বেশি পড়ার চেষ্টা করছেন।
জেমস বেনেট

6
ত্রুটি, আমরা যদি এই যুক্তিটি গুগল কোড অনুসন্ধানগুলি ব্যবহার করতে যাচ্ছি: google.com/codesearch?q=lang%3Aththon+raise%5C+ ভ্যালু এরির # 66,300 কেপ, জেন, জ্যাঙ্গো, মজিলা সহ ভ্যালুয়েরর উত্থাপনের কেসগুলি (এবং এটি ফলাফলের প্রথম পৃষ্ঠা থেকে)। যদি কোনও অন্তর্নির্মিত ব্যতিক্রম ফিট হয় তবে এটি ব্যবহার করুন ..
dbr

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

-1

আপনার নিজের ব্যতিক্রম রোল করার জন্য মার্কাসের পরামর্শের সাথে একমত হন, তবে ব্যতিক্রমটির পাঠ্যটি স্পষ্ট করে জানিয়ে দিতে হবে যে সমস্যাটি যুক্তি তালিকায় রয়েছে, স্বতন্ত্র যুক্তির মানগুলিতে নয়। আমি প্রস্তাব দেব:

class BadCallError(ValueError):
    pass

যখন কীওয়ার্ড আর্গুমেন্টগুলি নিখোঁজ থাকে যা নির্দিষ্ট কলের জন্য প্রয়োজনীয় ছিল বা আর্গুমেন্ট মান পৃথকভাবে বৈধ তবে একে অপরের সাথে অসামঞ্জস্যপূর্ণ Used ValueErrorএখনও নির্দিষ্ট হতে পারে যখন নির্দিষ্ট যুক্তিটি সঠিক টাইপ হয় তবে সীমার বাইরে থাকে।

পাইথনে এটি কি স্ট্যান্ডার্ড ব্যতিক্রম হওয়া উচিত নয়?

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


আমি KeyErrorকীওয়ার্ডটি খুঁজে পাইনি তার জন্য উত্থাপন করতাম (যেহেতু একটি অনুপস্থিত স্পষ্ট কীওয়ার্ড **kwargsশব্দটির সাথে শব্দাবলীর সাথে একই কী অনুপস্থিত) ident
কাউয়ার্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.