পাইথন দৃsert়তার জন্য সেরা অনুশীলন


482
  1. assertকেবলমাত্র ডিবাগিংয়ের উদ্দেশ্যে স্ট্যান্ডার্ড কোড ব্যবহার করার পরিবর্তে কোনও কার্য সম্পাদন বা কোড রক্ষণাবেক্ষণের সমস্যা আছে কি ?

    কি

    assert x >= 0, 'x is less than zero'

    চেয়ে ভাল বা খারাপ

    if x < 0:
        raise Exception, 'x is less than zero'
  2. এছাড়াও, কোনও ব্যবসায়ের নিয়ম নির্ধারণের কোনও উপায় if x < 0 raise errorকি সর্বদা তা ছাড়া পরীক্ষা করা হয় try/except/finally, যদি কোনও কোডের xমধ্যে যে কোনও সময় 0 টিরও কম হয় তবে যেমন assert x < 0কোনও ফাংশন শুরু করার পরে আপনি কোনও ফাংশনটির ভিতরেই সেট করে রেখেছিলেন যেখানে xকম হয়ে যায় 0 তারপর একটি ব্যতিক্রম উত্থাপিত হয়?



29
-O এবং -OO পাইথন প্যারামিটারগুলি আপনার দাবিগুলি সরিয়ে ফেলবে। এটি আপনার চিন্তাভাবনাটি কী জন্য ভাল তা নিয়ে চালিত হওয়া উচিত।
পিটার লাডা

4
থমাসজ জিলিনস্কির লিঙ্কটি নষ্ট হয়ে গেছে, এটি এখন: mail.python.org/pipermail/python-list/2013- নভেম্বার / 660568.html । আমি নিশ্চিত যে পাইপারমেলের একটি অস্থির আইডি ফাংশন রয়েছে, একই পাইপারমেলের ভিতরে থেকে একই লিঙ্কের সাথে একই লিঙ্কের দিকে ইঙ্গিত করে আমি অন্যান্য লিঙ্কগুলি পেয়েছি।
Quodlibetor

3
মামলা mail.python.org/pipermail/python-list/2013-November/660568.html আবার চলে আসে, এটা এ সংরক্ষন করা হয় archive.is/5GfiG । পোস্টটির শিরোনাম হল "কখন আসক্তি ব্যবহার করা হবে" এবং পাইথনের সেরা অনুশীলনের উপর একটি দুর্দান্ত পোস্ট (সত্যই একটি নিবন্ধ) assert
ক্লেক

উত্তর:


144

এক্স সম্পূর্ণরূপে শূন্যের চেয়ে কম হয়ে গেলে স্বয়ংক্রিয়ভাবে একটি ত্রুটি ছুঁড়ে ফেলতে সক্ষম হতে। আপনি ক্লাস বর্ণনাকারী ব্যবহার করতে পারেন । এখানে একটি উদাহরণ:

class LessThanZeroException(Exception):
    pass

class variable(object):
    def __init__(self, value=0):
        self.__x = value

    def __set__(self, obj, value):
        if value < 0:
            raise LessThanZeroException('x is less than zero')

        self.__x  = value

    def __get__(self, obj, objType):
        return self.__x

class MyClass(object):
    x = variable()

>>> m = MyClass()
>>> m.x = 10
>>> m.x -= 20
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "my.py", line 7, in __set__
    raise LessThanZeroException('x is less than zero')
LessThanZeroException: x is less than zero

10
বৈশিষ্ট্যগুলি বর্ণনাকারী হিসাবে প্রয়োগ করা হলেও, আমি এগুলি ব্যবহারের উদাহরণ বলব না। এই আরো এবং নিজেদের বৈশিষ্ট্য একটি উদাহরণ docs.python.org/library/functions.html#property
জেসন বেকার

3
এক্স সেট করার সময় বৈশিষ্ট্যগুলি মাই ক্লাসের মধ্যে ব্যবহার করা উচিত। এই সমাধানটি খুব সাধারণ।

112
খুব সুন্দর উত্তর, এটির মতো, তবে এই প্রশ্নটি ছাড়া কিছুই করতে হবে ... আমরা কি ডিস্টান বা জন মি'র উত্তরটিকে বৈধ প্রতিক্রিয়া হিসাবে চিহ্নিত করতে পারি না?
ভজ্ক হার্মেকজ

4
এটি প্রশ্নের শিরোনামের উত্তর দিতে উপস্থিত হবে না। এছাড়াও, এটি পাইথনের শ্রেণিবদ্ধ সম্পত্তি বৈশিষ্ট্যের একটি দুর্বল বিকল্প।
ডুমস 101

10
@ বাজক হার্মেকজ: আসলে, আপনি যদি প্রশ্নটি পুনরায় পাঠ করেন তবে এটি একটিতে দুটি প্রশ্ন। কেবল শিরোনামের দিকে তাকানো লোকেরা কেবল প্রথম প্রশ্নের সাথেই পরিচিত, যার উত্তর এই উত্তর দেয় না। এই উত্তরটিতে দ্বিতীয় প্রশ্নের উত্তর রয়েছে।
আর্টঅফ ওয়ারফেয়ার

742

এমন পরিস্থিতি যা কখনও না ঘটে সেগুলি পরীক্ষা করতে দৃ As়রূপে ব্যবহার করা উচিত । উদ্দেশ্যটি হ'ল কোনও দুর্নীতিগ্রস্থ প্রোগ্রামের ক্ষেত্রে তাড়াতাড়ি ক্রাশ করা।

ব্যতিক্রমগুলি ত্রুটিগুলির জন্য ব্যবহার করা উচিত যা ধারণাগুলি ঘটতে পারে এবং আপনার প্রায়শই নিজের ব্যতিক্রম ক্লাস তৈরি করা উচিত


উদাহরণস্বরূপ, আপনি যদি একটি কনফিগারেশন ফাইল থেকে একটিতে পড়ার জন্য একটি ফাংশন লিখছেন dictতবে ফাইলটিতে অনুপযুক্ত বিন্যাসটি একটি উত্থাপন করা উচিত ConfigurationSyntaxError, যখন আপনি করতে পারবেন assertযে আপনি ফিরে আসবেন না None


আপনার উদাহরণে, যদি xকোনও ব্যবহারকারী ইন্টারফেসের মাধ্যমে বা বাহ্যিক উত্স থেকে কোনও মান সেট করা হয় তবে একটি ব্যতিক্রম সেরা is

যদি xএকই প্রোগ্রামে কেবল আপনার নিজের কোড দ্বারা সেট করা থাকে তবে একটি দৃser়তা দিয়ে যান।


126
এই asserts ব্যবহার করার সঠিক উপায়। এগুলি প্রোগ্রামের প্রবাহ নিয়ন্ত্রণ করতে ব্যবহার করা উচিত নয়।
থান ব্রিমহল

41
শেষ অনুচ্ছেদের জন্য +1 - যদিও আপনার স্পষ্টভাবে উল্লেখ করা উচিত যা assertএতে অন্তর্নিহিত রয়েছে if __debug__এবং এটি অপ্টিমাইজড হতে পারে - জন
মি'র

3
আপনার উত্তরটি পুনরায় পড়া আমার মনে হয় আপনার সম্ভবত এমন পরিস্থিতি বোঝানো হয়নি যা কখনই কোনও নিয়ম হিসাবে বোঝানো উচিত নয় , বরং উদ্দেশ্য হ'ল একটি দুর্নীতিগ্রস্থ প্রোগ্রামের ক্ষেত্রে তাড়াতাড়ি ক্রাশ করা যা সাধারণত এমন শর্তের সাথে মিল থাকে যা আপনি প্রত্যাশা করেন না usually কখনও ঘটতে
বেন্টলে

10
অজানা কেবল অজানা পুনরুদ্ধার ছাড়া সমস্যাগুলি ধরতে ব্যবহার করা উচিত; প্রায়শই কোড বাগ (খারাপ ইনপুট নয়)। যখন একটি দৃsert়তা ট্রিগার করা হয়, তার অর্থ হওয়া উচিত যে প্রোগ্রামটি এমন অবস্থায় রয়েছে যা চালিয়ে যাওয়া বিপজ্জনক হতে পারে, কারণ এটি নেটওয়ার্কের সাথে কথা বলা বা ডিস্কে লেখা শুরু করতে পারে। শক্তিশালী কোড খারাপ (বা দূষিত) ইনপুটটির মুখে বৈধ রাষ্ট্র থেকে বৈধ অবস্থায় 'পরমাণু' থেকে চলে। প্রতিটি থ্রেডের শীর্ষ স্তরের একটি ত্রুটি বাধা থাকা উচিত। বাইরের বিশ্ব থেকে ইনপুট গ্রহণকারী ফল্ট বাধাগুলি সাধারণত বাধাটির কেবলমাত্র একটি পুনরাবৃত্তির জন্য ব্যর্থ হয় (যখন / চেষ্টা করুন), রোলব্যাক / লগ অন ত্রুটি।
রব

10
"এমন পরিস্থিতি যা কখনও না ঘটে সেগুলি পরীক্ষা করতে দৃ to়রূপে ব্যবহার করা উচিত" " হ্যাঁ. এবং দ্বিতীয়টির "উচিত" এর অর্থ হ'ল: যদি এটি হয় তবে প্রোগ্রাম কোডটি ভুল।
লুৎজ প্রেশেল্ট

362

সংকলনটি অনুকূলিত হয়ে গেলে "দৃsert়বিশ্বাসের" বিবৃতিগুলি সরানো হবে । সুতরাং, হ্যাঁ, কর্মক্ষমতা এবং কার্যকরী উভয় পার্থক্য রয়েছে।

সংকলনের সময় অপ্টিমাইজেশনের জন্য অনুরোধ করা হলে বর্তমান কোড জেনারেটর দৃsert় বিবৃতিতে কোনও কোড বহন করে না। - পাইথন 2 ডক্স পাইথন 3 ডক্স

আপনি যদি assertঅ্যাপ্লিকেশন কার্যকারিতা বাস্তবায়নের জন্য ব্যবহার করেন , তবে উত্পাদনকে স্থাপনার অনুকূলিতকরণ করুন, আপনি "কিন্তু-এটি-ওয়ার্ক-ইন-ডেভ" ত্রুটি দ্বারা জর্জরিত হবেন।

দেখুন PYTHONOPTIMIZE এবং -O -OO


26
কি দারুন! যে সুপার গুরুত্বপূর্ণ নোট! আমি কয়েকটি জিনিস যা কখনই ব্যর্থ হয় না তা যাচাই করার জন্য দৃ using় ব্যবহারের পরিকল্পনা করছিলাম, যার ব্যর্থতা ইঙ্গিত দেয় যে কেউ আমার ডেটা যেগুলি অ্যাক্সেস না করা উচিত সেগুলি অ্যাক্সেস করার চেষ্টা করে তারা যে ডেটা প্রেরণ করছিলেন তা খুব যত্ন সহকারে চালাচ্ছিল। এটি কার্যকর হবে না, তবে আমি দৃ attempt়তার সাথে তাদের প্রয়াস দ্রুততার সাথে বন্ধ করতে চাই, যাতে উত্পাদনের ক্ষেত্রে অপ্টিমাইজড হওয়া উদ্দেশ্যকে পরাভূত করতে পারে। আমি ঠিক কি করবো হবে raiseএকটি Exceptionপরিবর্তে। ওহ - আমি সবেমাত্র SuspiciousOperation Exceptionসাবক্লাস সহ একটি উপযুক্তভাবে নামটি আবিষ্কার করেছি Django! পারফেক্ট!
আর্টঅফ ওয়ারফেয়ার

যাইহোক @ আর্টঅফ ওয়ারফেয়ার যদি আপনি banditআপনার কোডটিতে চালান তবে এটি আপনাকে এ সম্পর্কে সতর্ক করবে।
নাগেভ

132

চারটি উদ্দেশ্য assert

ধরুন আপনি চার সহকর্মী অ্যালিস, বার্ড, কার্ল এবং ড্যাফনে সহ 200,000 লাইনের কোডে কাজ করছেন। তারা আপনার কোড কল করে, আপনি তাদের কোড কল করুন।

তারপর assertরয়েছে চার ভূমিকা :

  1. আপনার কোডটি কী প্রত্যাশা করে এলিস, বার্ড, কার্ল এবং ড্যাফনে জানান।
    ধরুন আপনার কাছে এমন একটি পদ্ধতি রয়েছে যা টিপলগুলির একটি তালিকা প্রক্রিয়াকরণ করে এবং যদি এই টিউপসগুলি স্থায়ী না হয় তবে প্রোগ্রামের যুক্তিটি ভাঙ্গতে পারে:

    def mymethod(listOfTuples):
        assert(all(type(tp)==tuple for tp in listOfTuples))

    এটি ডকুমেন্টেশনের সমতুল্য তথ্যের চেয়ে বিশ্বাসযোগ্য এবং বজায় রাখা আরও সহজ।

  2. আপনার কোডটি যা প্রত্যাশা করে তা কম্পিউটারকে জানিয়ে দিন।
    assertআপনার কোডের কলকারীদের থেকে যথাযথ আচরণ প্রয়োগ করে। যদি আপনার কোড অ্যালিসের কাছে কল করে এবং বারেন্ডের কোডটি আপনাকে কল করে assert, তবে যদি না, প্রোগ্রামটি অ্যালিস কোডে ক্র্যাশ হয়ে যায়, বার্ড এটি অ্যালিসের ভুল বলে ধরে নিতে পারে, অ্যালিস তদন্ত করে এবং ধরে নিতে পারে যে এটি আপনার ত্রুটি ছিল, আপনি তদন্ত করেছিলেন এবং বারেন্ডকে বলবেন যে এটি আসলে ছিল তার। প্রচুর কাজ হারিয়ে গেছে।
    দৃser়তার সাথে, যে কেউ কলটি ভুল পেয়েছে, তারা তাড়াতাড়ি দেখতে পাবে যে এটি তাদের নয়, আপনার নয়। অ্যালিস, বার্ড এবং আপনারা সকলেই উপকৃত হন। সময় প্রচুর পরিমাণে বাঁচায়।

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

    assert(all(entry.isClean() for entry in mylist))

    এই বিবৃতিটি হ'ল বিস্ময়কর লুপটি অর্জন করছে ঠিক কী তা বোঝার চেষ্টা করছে এমন প্রত্যেকের জন্য মাথা ব্যথা রক্ষা করে । এবং এই লোকদের মধ্যে সবচেয়ে ঘন ঘন সম্ভবত নিজেকে হতে হবে।

  4. আপনার কোডটি এক পর্যায়ে কী অর্জন করেছে তা কম্পিউটারকে জানান।
    ট্রট করার পরে যদি আপনি কোনও প্রবেশের প্রয়োজনটি চালিয়ে যেতে ভুলে যান তবে এটি assertআপনার দিনটি বাঁচায় এবং আপনার কোড প্রিয় ডাফ্নের পরে খুব বেশি বিরতি এড়ায়।

আমার মনে, assertডকুমেন্টেশনের দুটি উদ্দেশ্য (1 এবং 3) এবং সেফগার্ড (2 এবং 4) সমান মূল্যবান।
মানুষ পরিচায়ক এমনকি হতে পারে আরো কম্পিউটার পরিচায়ক চেয়ে মূল্যবান, কারণ এটি খুব ভুল প্রতিরোধ করতে পারি assertধরতে লক্ষ্য ও কোনো ক্ষেত্রে পরবর্তী ভুল প্রচুর (কেস 1)।


34
৫. দৃsert়তার সাথে আইসনস্ট্যান্স () পাইচার্ম (পাইথন আইডিই) কে ভেরিয়েবলের ধরণ জানতে সহায়তা করে, এটি স্বতঃপূরণের জন্য ব্যবহৃত হয়।
Cjkjvfnby

1
বর্তমান মৃত্যুদন্ড কার্যকর হওয়ার সময় সত্য যা আছে তার জন্য স্ব-নথির কোড অনুমানকে যুক্ত করে। এটি একটি অনুমানের মন্তব্য, যা পরীক্ষা করা হয়।
pyj

9
2 এবং 4 সম্পর্কিত: আপনার প্রতিবেদনগুলি খুব কঠোর না হওয়ার বিষয়ে আপনার খুব যত্নশীল হওয়া উচিত। অন্যথায় জোর দেওয়া নিজেরাই আপনার প্রোগ্রামকে আরও সাধারণ সেটিংসে ব্যবহারের জন্য রাখার একমাত্র জিনিস হতে পারে। বিশেষত জোর দেওয়া টাইপগুলি পাইথনের হাঁস-টাইপিংয়ের বিরুদ্ধে যায়।
zwirbeltier

9
@ Cjkjvfnby এই ব্লগের এন্ট্রিতে বর্ণিত আইসনস্ট্যান্স () এর অতিরিক্ত ব্যবহার সম্পর্কে সতর্ক থাকুন: " আইসিনস্ট্যান্স () ক্ষতিকারক হিসাবে বিবেচিত "। আপনি এখন পাইচার্মে প্রকার নির্দিষ্ট করতে ডকাস্ট্রিং ব্যবহার করতে পারেন
বাইনারিসউস্ট্রেট

2
চুক্তি নিশ্চিত করার এক উপায়ে দৃser়পদ ব্যবহার করা Using চুক্তি দ্বারা নকশা সম্পর্কে আরও তথ্য en.wikedia.org/wiki/Design_by_contract
লেজেক জারনা

22

অন্যান্য উত্তরগুলির পাশাপাশি, নিজেরাই ব্যতিক্রম ছুঁড়ে ফেলেছে বলে দাবি করে তবে কেবল অ্যাসেরেশনআররেস। একটি উপযোগবাদী দৃষ্টিকোণ থেকে, আপনি যখন ব্যতিক্রমগুলি ধরেন তার উপর সূক্ষ্ম শস্য নিয়ন্ত্রণের প্রয়োজন হয় তখন দৃser় প্রতিজ্ঞাগুলি উপযুক্ত নয়।


3
ঠিক। কলারের মধ্যে দৃ error়তা ত্রুটিযুক্ত ব্যতিক্রম ধরা এটি নির্বোধ বলে মনে হবে।
রাফি খ্যাচাডৌড়িয়ান

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

আপনার উত্তরটি এমনভাবে পড়তে পারে যেন আপনি ধরতে চান AssertionErrors, যখন আপনি এটি ঠিকঠাক করে ছাঁটাই করছেন। বাস্তবে, আপনার এগুলি ধরা উচিত নয়।
টমাসজ গ্যান্ডোর

19

এই পদ্ধতির সাথে সত্যই যে সমস্যাটি রয়েছে তা হ'ল দৃsert় বিবৃতি ব্যবহার করে খুব বর্ণনামূলক ব্যতিক্রম করা শক্ত। আপনি যদি সরল বাক্য গঠনটি সন্ধান করেন তবে মনে রাখবেন আপনি এই জাতীয় কিছু করতেও পারেন :

class XLessThanZeroException(Exception):
    pass

def CheckX(x):
    if x < 0:
        raise XLessThanZeroException()

def foo(x):
    CheckX(x)
    #do stuff here

আর একটি সমস্যা হ'ল স্বাভাবিক অবস্থা-পরীক্ষার জন্য দৃsert়তা ব্যবহার করা এটি -O পতাকা ব্যবহার করে ডিবাগিং সংস্থাগুলি অক্ষম করা কঠিন করে তোলে।


24
আপনি একটি তদন্তে একটি ত্রুটি বার্তা যুক্ত করতে পারেন। এটি দ্বিতীয় প্যারামিটার। এটি বর্ণনামূলক করে তুলবে।
রাফি খ্যাচাডৌড়িয়ান

10

ইংরেজি ভাষা শব্দ জাহির এখানে অর্থে ব্যবহার করা হয় শপথ , সত্যাপন , সত্য বলিয়া ঘোষণা করা । এর অর্থ "চেক" বা "হওয়া উচিত" নয় । এর অর্থ হ'ল কোডার হিসাবে আপনি এখানে শপথের বিবৃতি দিচ্ছেন :

# I solemnly swear that here I will tell the truth, the whole truth, 
# and nothing but the truth, under pains and penalties of perjury, so help me FSM
assert answer == 42

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


8

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

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

def SumToN(n):
    if n <= 0:
        raise ValueError, "N must be greater than or equal to 0"
    else:
        return RecursiveSum(n)

def RecursiveSum(n):
    #precondition: n >= 0
    assert(n >= 0)
    if n == 0:
        return 0
    return RecursiveSum(n - 1) + n
    #postcondition: returned sum of 1 to n

এই লুপ আক্রমণকারীদের প্রায়শই একটি দৃser়তার সাথে প্রতিনিধিত্ব করা যায়।


2
এটি সজ্জাকারীদের (@ পূর্বশর্ত এবং @ পোস্টকন্ডিশন) দিয়ে সর্বোত্তমভাবে করা হয়
ক্যারিডর্ক

@ ক্যারিডরক এটির কংক্রিট সুবিধা কী?
চিয়েল দশ ব্রিংকে

@ চিল্টেনব্রিংক নিজের ডকুমেন্টিং কোড এর পরিবর্তে #precondition: n >= 0 এবং একটি @precondition(lambda n: n >= 0)
দৃsert়তার সাথে

পছন্দ করুন এবং কীভাবে একজন তা থেকে ডকুমেন্টেশন জেনারেট করে?
চিয়েল দশ ব্রিনকে

@ChieltenBrinke বিল্ট-ইন না কিন্তু সহজ বাস্তবায়ন stackoverflow.com/questions/12151182/... । ডকুমেন্টেশনের জন্য কেবল __doc__অতিরিক্ত স্ট্রিং দিয়ে গুনটি প্যাচ করুন
ক্যারিডর্ক

4

কি সেখানে একটি কার্যকারিতা সমস্যা?

  • দয়া করে মনে রাখবেন "আপনি এটিকে দ্রুত কাজ করার আগে প্রথমে এটি কাজ করুন"
    যে কোনও প্রোগ্রামের খুব কম শতাংশই এর গতির জন্য সাধারণত প্রাসঙ্গিক। আপনি যদি সর্বদা assertএটির কার্য সম্পাদন সমস্যা হিসাবে প্রমাণিত হন তবে আপনি সর্বদা কিক আউট বা সরল করতে পারেন - এবং তাদের বেশিরভাগ কখনই তা করবে না।

  • বাস্তববাদী হোন :
    ধরুন আপনার কাছে এমন একটি পদ্ধতি রয়েছে যা টিপলগুলির একটি খালি খালি তালিকার প্রক্রিয়া করে এবং যদি এই টিউপসগুলি স্থায়ী না হয় তবে প্রোগ্রামের যুক্তিটি ভেঙে যাবে। আপনার লেখা উচিত:

    def mymethod(listOfTuples):
        assert(all(type(tp)==tuple for tp in listOfTuples))

    আপনার তালিকাগুলি দশটি এন্ট্রি দীর্ঘ হতে পারে তবে এটি সম্ভবত ঠিক আছে, তবে তাদের যদি মিলিয়ন এন্ট্রি থাকে তবে এটি সমস্যা হয়ে উঠতে পারে। সম্পূর্ণরূপে এই মূল্যবান চেকটি বাতিল করার পরিবর্তে আপনি কেবল এটিকে ডাউনগ্রেড করতে পারেন

    def mymethod(listOfTuples):
        assert(type(listOfTuples[0])==tuple)  # in fact _all_ must be tuples!

    যা সস্তা তবে সম্ভবত যেহেতু বেশিরভাগ প্রকৃত প্রোগ্রাম ত্রুটিগুলি ধরা দেবে ।


2
হওয়া উচিত assert(len(listOfTuples)==0 or type(listOfTyples[0])==tuple)
osa

না, এটা করা উচিত নয়। এটি অনেক দুর্বল পরীক্ষা হবে, কারণ এটি আর 'খালি নয়' সম্পত্তিটি যাচাই করে না, এটি দ্বিতীয়টি যাচাই করে। (প্রথমটি যদিও এটি হওয়া উচিত নয় does)
লুটজ প্রিচেল্ট

1
দ্বিতীয় দাবী খালি খালি সম্পত্তি স্পষ্টভাবে চেক করে না; এটি আরও একটি পার্শ্ব প্রতিক্রিয়া। যদি তালিকাটি খালি থাকার কারণে যদি এটি ব্যতিক্রম করে তোলে, কোডটি নিয়ে কাজ করা ব্যক্তি (অন্য কেউ বা লেখক, এটি লেখার এক বছর পরে) এটি তাকিয়ে থাকবে, এই দাবীটি সত্যিকার অর্থে ধরা হয়েছিল কিনা তা নির্ধারণ করার চেষ্টা করছিল খালি তালিকার পরিস্থিতি, বা যদি এটি নিজেই দাবিতে কোনও ত্রুটি হয়। তদুপরি, আমি দেখতে পাচ্ছি না যে খালি ক্ষেত্রে "কীভাবে দুর্বল" তা খতিয়ে দেখা হচ্ছে না, তবে কেবলমাত্র প্রথম উপাদানটি পরীক্ষা করা "97% সঠিক"।
oca

3

ঠিক আছে, এটি একটি উন্মুক্ত প্রশ্ন এবং আমার দুটি দিক রয়েছে যা আমি স্পর্শ করতে চাই: কখন যুক্তি যুক্ত করতে হবে এবং কীভাবে ত্রুটি বার্তা লিখতে হয় to

উদ্দেশ্য

কোনও শিক্ষানবিশকে এটি ব্যাখ্যা করার জন্য - জোর দেওয়া বিবৃতিগুলি যা ত্রুটি বাড়াতে পারে তবে আপনি সেগুলি ধরবেন না won't এবং এগুলি সাধারণত উত্থাপিত করা উচিত নয়, তবে বাস্তবে তারা কখনও কখনও উত্থাপিত হয়। এবং এটি একটি গুরুতর পরিস্থিতি, যা কোডটি পুনরুদ্ধার করতে পারে না, যাকে আমরা 'মারাত্মক ত্রুটি' বলে থাকি।

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

শৈলী

পাইথনে, assertএকটি বিবৃতি, কোনও ফাংশন নয়! (মনে রাখবেন assert(False, 'is true')না উত্থাপিত।

কখন এবং কীভাবে errorচ্ছিক 'ত্রুটি বার্তা' লিখবেন?

এই acually ইউনিট টেস্টিং পরিকাঠামোর দ্বারা যাতে প্রায়ই অনেক ডেডিকেটেড পদ্ধতি আছে (গবেষকেরা করতে প্রযোজ্য assertTrue(condition), assertFalse(condition), assertEqual(actual, expected)ইত্যাদি)। তারা প্রায়শই দৃ as়ভাবে মন্তব্য করার একটি উপায়ও সরবরাহ করে।

নিক্ষেপ কোডে আপনি ত্রুটি বার্তা ছাড়াই করতে পারেন do

কিছু ক্ষেত্রে, এই দাবিতে যুক্ত করার মতো কিছুই নেই:

ডিফ ডাম্প (কিছু): দৃsert়তা বিহীন (কিছু, ডাম্পেবল) # ...

তবে এগুলি বাদে, একটি বার্তা অন্যান্য প্রোগ্রামারদের সাথে যোগাযোগের জন্য দরকারী (যা কখনও কখনও আপনার কোডের ইন্টারেক্টিভ ব্যবহারকারী হয়, যেমন আইপিথন / জুপিটার ইত্যাদি)।

তাদের তথ্য দিন, কেবল অভ্যন্তরীণ বাস্তবায়নের বিশদটি ফাঁস করবেন না।

পরিবর্তে:

assert meaningless_identifier <= MAGIC_NUMBER_XXX, 'meaningless_identifier is greater than MAGIC_NUMBER_XXX!!!'

লিখুন:

assert meaningless_identifier > MAGIC_NUMBER_XXX, 'reactor temperature above critical threshold'

বা এমনকি এমনকি:

assert meaningless_identifier > MAGIC_NUMBER_XXX, f'reactor temperature({meaningless_identifier }) above critical threshold ({MAGIC_NUMBER_XXX})'

আমি জানি, আমি জানি - এটি কোনও স্থির দৃ as়তার জন্য কেস নয়, তবে আমি বার্তার তথ্যগত মানটির দিকে ইঙ্গিত করতে চাই।

নেতিবাচক বা ইতিবাচক বার্তা?

এটি বিতর্কিত হতে পারে তবে এ জাতীয় জিনিসগুলি পড়তে আমার কষ্ট দেয়:

assert a == b, 'a is not equal to b'
  • এগুলি প্রত্যেকের পাশেই লেখা দুটি পরস্পরবিরোধী জিনিস। সুতরাং যখনই আমার কোডবেজে প্রভাব রয়েছে, আমি 'আবশ্যক' এবং 'উচিত' এর মতো অতিরিক্ত ক্রিয়া ব্যবহার করে এবং আমরা কী চাই না তা না বলে আমরা কী চাই তা নির্দিষ্ট করার জন্য চাপ দিই।

    একটি == খ, 'একটি অবশ্যই বি এর সমান হতে হবে'

তারপরে, AssertionError: a must be equal to bপাওয়াটাও পঠনযোগ্য এবং বিবৃতিটি কোডটিকে যৌক্তিক মনে হচ্ছে। এছাড়াও, আপনি ট্রেসব্যাক না পড়ে এটি থেকে কিছু পেতে পারেন (যা কখনও কখনও উপলভ্যও হতে পারে না)।


1

assertব্যতিক্রমগুলির ব্যবহার এবং উত্থাপন উভয়ই যোগাযোগ সম্পর্কিত।

  • সংস্থাগুলি হ'ল বিকাশকারীদের উদ্দেশ্যে সম্বোধন করা কোডের সঠিকতা সম্পর্কে বিবৃতি: কোডটিতে একটি যুক্তি কোডের পাঠকদেরকে এমন শর্তাদি সম্পর্কে অবহিত করে যে কোডটি সঠিক হওয়ার জন্য পূরণ করতে হবে। রান-টাইমে ব্যর্থ হওয়া একটি প্রতিবেদনটি বিকাশকারীদের জানিয়ে দেয় যে কোডের মধ্যে একটি ত্রুটি রয়েছে যা ফিক্সিংয়ের প্রয়োজন।

  • ব্যতিক্রমগুলি হ'ল অ-সাধারণ পরিস্থিতি সম্পর্কে ইঙ্গিত যা রান-টাইমে ঘটতে পারে তবে হাতের কোড দ্বারা সমাধান করা যায় না, কলিং কোডটিতে সম্বোধন করা হয় there একটি ব্যতিক্রমের ঘটনাটি বোঝায় না যে কোডটিতে কোনও ত্রুটি রয়েছে।

ভাল অভ্যাস

সুতরাং, আপনি যদি রান-টাইমে কোনও নির্দিষ্ট পরিস্থিতির উপস্থিতিটিকে বাগ হিসাবে বিবেচনা করেন যা আপনি বিকাশকারীদের সম্পর্কে অবহিত করতে চান ("হাই বিকাশকারী, এই শর্তটি নির্দেশ করে যে কোথাও একটি বাগ রয়েছে, দয়া করে কোডটি ঠিক করুন" ") একটি দৃ for়তা জন্য যান যদি জোর দেওয়া আপনার কোডের ইনপুট আর্গুমেন্টগুলি পরীক্ষা করে, আপনার ইনপুট আর্গুমেন্টগুলি শর্ত লঙ্ঘন করে তবে আপনার কোডটি "অপরিজ্ঞাত আচরণ" রয়েছে এমন ডকুমেন্টেশনে সাধারণত যুক্ত করা উচিত।

পরিবর্তে যদি সেই খুব প্রকৃতির ঘটনাটি আপনার চোখে কোনও বাগের ইঙ্গিত না দেয় তবে পরিবর্তে একটি (সম্ভবত বিরল তবে) সম্ভাব্য পরিস্থিতি যা আপনি মনে করেন ক্লায়েন্ট কোড দ্বারা পরিচালিত হওয়া উচিত, একটি ব্যতিক্রম বাড়াবেন। পরিস্থিতি যখন কোন ব্যতিক্রম উত্থাপিত হয় তা সংশ্লিষ্ট কোডের ডকুমেন্টেশনের অংশ হওয়া উচিত।

ব্যবহারের সাথে একটি পারফরম্যান্স [...] সমস্যা আছে কি? assert

দাবিগুলির মূল্যায়নের জন্য কিছু সময় লাগে। সংকলন সময়ে এগুলি নির্মূল করা যেতে পারে। এর কিছু পরিণতি রয়েছে তবে নীচে দেখুন।

ব্যবহারের সাথে কোড রক্ষণাবেক্ষণের কোনও সমস্যা আছে কি? assert

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


1

একটি দৃsert়তা পরীক্ষা করতে হবে -
1. বৈধ শর্ত,
2. বৈধ বিবৃতি,
3. সত্য যুক্তি;
উত্স কোড। পুরো প্রকল্পটি ব্যর্থ হওয়ার পরিবর্তে এটি একটি এলার্ম দেয় যে আপনার উত্স ফাইলে কিছু উপযুক্ত নয়।

উদাহরণস্বরূপ 1, যেহেতু ভেরিয়েবল 'str' নাল নয়। সুতরাং কোন জোর বা ব্যতিক্রম উত্থাপিত হয় না।

উদাহরণ 1:

#!/usr/bin/python

str = 'hello Python!'
strNull = 'string is Null'

if __debug__:
    if not str: raise AssertionError(strNull)
print str

if __debug__:
    print 'FileName '.ljust(30,'.'),(__name__)
    print 'FilePath '.ljust(30,'.'),(__file__)


------------------------------------------------------

Output:
hello Python!
FileName ..................... hello
FilePath ..................... C:/Python\hello.py

উদাহরণস্বরূপ 2, var 'str' নাল। সুতরাং আমরা দৃ sert় বিবৃতি দিয়ে ত্রুটিযুক্ত প্রোগ্রামের আগে ব্যবহারকারীকে বাঁচিয়ে দিচ্ছি

উদাহরণ 2:

#!/usr/bin/python

str = ''
strNull = 'NULL String'

if __debug__:
    if not str: raise AssertionError(strNull)
print str

if __debug__:
    print 'FileName '.ljust(30,'.'),(__name__)
    print 'FilePath '.ljust(30,'.'),(__file__)


------------------------------------------------------

Output:
AssertionError: NULL String

যে মুহুর্তে আমরা ডিবাগ করতে চাই না এবং উত্স কোডটিতে আসক্তি ইস্যুটি উপলব্ধি করেছি। অপ্টিমাইজেশন পতাকাটি অক্ষম করুন

পাইথন -O assertStatement.py
কিছুই প্রিন্ট পাবেন না


0

আইটিই এর যেমন পিটিভিএস, পাইচার্মে উইং assert isinstance()স্টেটমেন্টগুলি কিছু অস্পষ্ট বস্তুর কোড সম্পাদন সক্ষম করতে ব্যবহার করা যেতে পারে।


এটি প্রকারের টীকা বা ব্যবহারের পূর্বাভাস দেয় বলে মনে হয় typing.cast
একিউম্যানাস

-1

এর মূল্য কী, আপনি যদি সেই কোডটি নিয়ে কাজ করছেন যা assertসঠিকভাবে কাজ করতে নির্ভর করে তবে নীচের কোডটি যুক্ত করা নিশ্চিত করবে যে জোরগুলি সক্ষম হয়েছে:

try:
    assert False
    raise Exception('Python assertions are not working. This tool relies on Python assertions to do its job. Possible causes are running with the "-O" flag or running a precompiled (".pyo" or ".pyc") module.')
except AssertionError:
    pass

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