When to use assertions in Python

Source: Internet
Author: User

Original: http://blog.jobbole.com/76285/

This document is translated by Bó Lè Online-the base Saint OMG. without permission, no reprint!
English Source: Python maillist. Welcome to join the translation team.

The question is how to use assertion expressions in some scenarios, and usually someone will misuse it, so I decided to write an article explaining when to use assertions and when not.

For those who do not know it, Python's assert is used to check a condition, and if it is true, it does nothing. If it is false, it throws a Asserterror and contains an error message. For example:

py> x =negative"pyassert"  "xis a even number""in is   not an even number

Many people use assert as a quick and easy way to throw an exception when a parameter is wrong. But this is wrong, very wrong, there are two reasons. The first asserterror is not the error that should be thrown when testing parameters. You should not write code like this:

if  not isinstance (x, int): Raise Assertionerror ("not aint")

You should throw a typeerror error, and the assert will throw the wrong exception.

But, more dangerously, there is a disturbance about assert: it can be compiled well and never executed, if you run Python with the –O or –oo option, the result is not guaranteed that the assert expression will run to. This is the future when the appropriate assert is used, but when the assert is improperly used, it causes the code to execute with-o error.

When should I use assert? Without a specific rule, assertions should be used for:

    • Defense-based programming
    • Run-time Check program logic
    • Check Convention
    • Program Constants
    • Check the document

(It is also acceptable to use assertions when testing the code, which is a handy unit test method, and you can accept that these tests will not do anything when you run with the-o flag.) I sometimes use assert false in my code to mark a branch of code that has not been written, and I want the code to run unsuccessfully. Although it might be better to throw notimplementederror. )

There are many opinions about assertions, because it ensures that the code is correct. If you are sure that the code is correct, then there is no need to assert it because they will never run a failure and you can remove these assertions directly. If you are sure that the check will fail, then if you do not have to assert, the code will compile and ignore your check.

In both cases it will be interesting when you are more certain of the code but not absolutely sure. Maybe you'll miss out on some very odd situations. In this case, an additional run-time check will help you ensure that any errors will be captured as early as possible.

Another good way to use assertions is to check the program's invariants. A non-variable is something you need to rely on for a real situation unless a bug causes it to be false. If there are bugs, it's best to find them early, so we do a test for it, but don't want to slow down the code. So use assertions because it can be opened at development time and closed in the product phase.

An example of a non-variable might be if your function wants to have a database connection at the beginning of it and commits to remain connected when it returns, which is the invariant of the function:

def some_function (ARG):     assert  not db.closed ()     # code goes    here assert  not db.closed ()     return Result

The assertion itself is a good comment, rather than writing a comment directly:

# when we reach here, we know that n > 2

You can ensure it by adding an assertion:

Assert n > 2

Assertions are also a defensive type of programming. Instead of getting your code to defend against the current error, you are preventing errors that are raised after the code is modified. Ideally, unit tests can do the job, but the reality is that they are usually not done. People may forget to run the test code before committing the code. One internal check is another line of defense that blocks the error, especially those that are not obvious, which leads to a problem with the code and returns the wrong result.

Adding you have some if...elif block of statements, you know some of the values before this need:

# target is expected to being one of X, Y, or Z, and nothing else. if target = = x:    run_x_code ()elif target = = y:    run_y_code ()Else :    run_z_code ()

Suppose the code is now completely correct. But will it always be right? Dependent modification, code modification. What happens if the dependency changes to target = W, is it related to the Run_w_code function? If we change the code, but do not modify the code here, it may result in an incorrect call to the Run_z_code function and throw an error. It's good to write code in a defensive way, which allows the code to run correctly or execute errors immediately, even if you modify it in the future.

Comments at the beginning of the code are a good step, but people often don't bother reading or updating comments. Once this happens, comments become useless. But with assertions, I can write documents on the assumptions of blocks of code at the same time, and trigger a clean error when they violate.

assert inch (x, Y, z) if target = = x:    run_x_code ()elif target = = y:    run_y_code ()Else  :    assert target = = Z    run_z_code ()

In this way, assertions are a defensive type of programming and also a document. I think of a better solution:

if target = = x:    run_x_code ()elif target = = y:    run_y_code ()elif target = = Z    : Run_z_code ()else:    # This can never happen. But just in the case it does    ... Raise RuntimeError ("anunexpected error occurred")

Designing by convention is another good use of assertions. We imagine a convention between a function and a caller, such as the following:

"If you pass me a non-empty string, I promise to pass the first letter of the string and capitalize it." ”

If the contract is broken by a function or call, the code will go wrong. We say that the function has some preconditions and a post condition, so the function will write:

def First_upper (astring):     assert  and Len (astring) > 0    = astring[0].upper ()    assert and Len ( result) = = 1    assert result = = result.upper    ()return result

The goals are designed to be properly programmed, with preconditions and post conditions that need to be maintained. This is a typical scenario for assertions, because once we release the code without the problem into the product, the program will be correct and we can safely remove the check.

Here's what I suggest not to use the assertion scenario:

    • Do not use it to test user-supplied data
    • Don't use assertions to check what you think will go wrong in your routine use of your program. Assertions are used to check for very rare problems. Your users should not see any assertion errors, and if they see it, this is a bug that fixes it.
    • In some cases, it is not necessary to assert that it is shorter than a precise check, and it should not be lazy.
    • Do not use it to check the input parameters of the public library, because it does not control the caller, so there is no guarantee that the caller will break the contract between them.
    • Do not use assertions for errors that you feel can be restored. In other words, you don't have to catch an assertion error in your product code.
    • Don't use too many assertions to obscure your code.
About the base of the holy OMG

When to use assertions in Python (go)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.