Analyze the situations in Python that require assertions and python

Source: Internet
Author: User

Analyze the situations in Python that require assertions and python

This problem is how to use an assertion expression in some scenarios. Someone may misuse it, so I decided to write an article to explain when to use assertion and when not to use it.

For those who are not clear about it, Python's assert is used to check a condition. If it is true, nothing will be done. If it is false, AssertError is thrown and contains the error message. For example:
 

py> x = 23py> assert x > 0, "x is not zero or negative"py> assert x%2 == 0, "x is not an even number"Traceback (most recent call last):File "", line 1, inAssertionError: x is not an even number

Many people use assert as a fast and easy method to throw an exception when a parameter error occurs. But this is wrong. It is very wrong for two reasons. First, AssertError is not an error that should be thrown during parameter testing. You should not write code like this:
 

if not isinstance(x, int):raise AssertionError("not an int")

You should throw a TypeError. assert will throw an error exception.

But what's more dangerous is that there is a problem with assert: It can be compiled and never executed. If you use the-O or-oo option to run Python, the assert expression does not run in the result. This is the future when assert is used properly, but when assert is used improperly, it will cause errors when the code is executed with-O.

When should I use assert? There are no specific rules. assertions should be used:

  • Defense Programming
  • Check Program Logic during runtime
  • Check conventions
  • Program constant
  • Check document

(It is acceptable to use assertions when testing Code. It is a very convenient unit test method. You accept these tests without doing anything when running with the-O sign. I sometimes use assert False in the code to mark the branches of the Code that have not been written. I want the code to fail to run. Although it may be better to throw NotImplementedError .)

There are many opinions on assertions, because they can ensure the correctness of the Code. If you are sure that the code is correct, there is no need to use assertions, because they never fail to run, you can directly remove these assertions. If you are sure that the check will fail, if you do not need to assert, the code will pass the compilation and ignore your check.

In the above two cases, it will be very interesting. When you are more sure of the code, but not absolutely sure. You may miss out on some weird situations. In this case, additional runtime checks can help you ensure that any errors are captured as early as possible.

Another good way to use assertions is to check the program's invariant. A constant is a situation where you need to rely on it to be true, unless a bug causes it to be false. If there is a bug, it is best to discover it as early as possible, so we will test it, but do not want to slow down the code running speed. So we use assertions because they can be opened during development and closed during the product stage.

A non-variable example may be: If your function wants to have a database connection at the beginning and promises to keep the connection when it returns, this is the function's invariant:
 

def some_function(arg):  assert not DB.closed()  ... # code goes here  assert not DB.closed()  return result

Assertions are good comments, better than writing comments directly:

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

You can add assertions to ensure it:

Assert n> 2

Assertion is also a defensive programming. Instead of making your code defend against current errors, you can prevent errors caused by code modifications. In ideal cases, unit tests can do this, but the reality is that they are generally not completed. People may forget to run the test code before submitting the code. One internal check is another line of defense against errors, especially those that are not obvious, but cause code problems and return incorrect results.

Add some if... The statement block of elif. Before that, you must have some values:
 

# target is expected to be 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 correct now. But will it always be correct? Dependency modification and code modification. If the dependency is changed to target = w, what will happen? Will it be related to the run_w_code function? If we change the code but do not modify the code, the run_z_code function may be called incorrectly and an error will be thrown. Using a defensive method to write code can make the code run correctly or execute an error immediately, even if you modify it in the future.

Comments at the beginning of the Code are a good step, but people are often reluctant to read or update comments. Once this happens, annotations become useless. But with assertions, I can write a document on the assumptions of code blocks at the same time, and trigger a clean error when they violate
 

assert target in (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, assertion is both a defensive programming and 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 case it does...  raise RuntimeError("an unexpected error occurred")

Designing according to conventions is another good use of assertions. We imagine a convention between a function and the caller, for example:

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

If the conventions are damaged by functions or calls, the Code may fail. We can say that a function has some pre-and post-conditions, so the function will write as follows:
 

def first_upper(astring):  assert isinstance(astring, str) and len(astring) > 0  result = astring[0].upper()  assert isinstance(result, str) and len(result) == 1  assert result == result.upper()  return result

The purpose of the design is to ensure correct programming. The preconditions and the post-conditions need to be maintained. This is a typical application scenario of assertion, because once we release the code that is no problem to the product, the program will be correct and we can safely remove the check.

The following is my suggestion not to use assertions:

  • Do not use it to test user data
  • Do not use assertions to check what you think will go wrong during normal use of your program. Assertions are used to check for very rare issues. Your users should not see any assertion errors. If they see this, it is a bug, fix it.
  • In some cases, you do not need to assert that it is shorter than the exact check. It should not be the lazy method of the coowner.
  • Do not use it to check the input parameters of the public database. Because it cannot control the caller, it cannot guarantee that the caller will not break the conventions of both parties.
  • Do not use assertions for errors that you think can be recovered. In other words, you do not need to capture asserted errors in the product code.
  • Do not use too many assertions to obscure the code.

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.