Python uses the functools module wrap method to describe the function

Source: Internet
Author: User
Tags wrapper in python

Today, I accidentally saw the Functools module in Python, found that the use of this module wraps () can implement some functions like interceptors, such as: packaging exceptions, hidden exceptions, print logs, statistical function use time. Here is a few pieces of code to see how to use the specific:

Wrapper exception
#!/usr/bin/env python
#-*-Coding:utf-8-*-
Import Functools


def wrap_exception (func):
@functools. Wraps (func)
def wrapper (self, *args, **kwargs):
Try
return func (Self, *args, **kwargs)
Except Baseexception as ex:
Raise MyException (Ex.message)

Return wrapper


Class MyException (Exception):
def __init__ (self, msg):
self.msg = Msg

def __str__ (self):
Return self.msg

def __repr__ (self):
Return self.msg


Class Test:
def __init__ (self):
Pass

@wrap_exception
def test (self):
Raise Exception ("Hello")


t = Test ()
T.test ()
Code Description:

The Wrap_exception function is used to decorate our final function, and the main function is to catch the exception and then convert it to another exception and throw it.
Defines a custom exception myexception, and we will convert the caught exception to this exception.
A test class, the test method uses the @wrap_exception description to use the adornment function, this method will raise an exception. This exception is eventually converted to a myexception exception.

Application Scenario:

This code can be used when we expect a certain class of functions to throw any exception to our expected exception type, and the most typical case is that we expect any exception to be converted to DataAccessException when dealing with database operations.

Hide Exceptions
#!/usr/bin/env python
#-*-Coding:utf-8-*-
Import Functools
def wrap_exception (func):
@functools. Wraps (func)
def wrapper (self, *args, **kwargs):
Try
return func (Self, *args, **kwargs)
Except
Pass

Return wrapper


Class Test:
def __init__ (self):
Pass

@wrap_exception
def test (self):
Raise Exception ("Hello")


t = Test ()
T.test ()
Code Description:

Similar to the previous, but we do not do anything after catching the exception, a bit want to let the function silently execution meaning.

Application Scenario:

Can be used when closing a file stream or a database connection.

#!/usr/bin/env python
#-*-Coding:utf-8-*-
def Wrap_logger (func):
@functools. Wraps (func)
def wrapper (self, *args, **kwargs):
Print ('%s (%s,%s) '% (func, args, Kwargs))
Print "Before Execute"
result = Func (self, *args, **kwargs)
Print "After Execute"
return result

Return wrapper


Class Test:
def __init__ (self):
Pass

@wrap_logger
def test (self, A, B, c):
Print A, B, c


t = Test ()
T.test (1, 2, 3)
Code Description:

The code is relatively simple, mainly in the wrapper method inside the call function before and after the function added some log.

Application Scenario:

Sometimes we expect to print some log information when we enter functions and exit functions for debugging purposes, and this code can be used at this time.

Statistical function Usage Time
#!/usr/bin/env python
#-*-Coding:utf-8-*-
Import Functools
Import time


def wrap_performance (func):
@functools. Wraps (func)
def wrapper (self, *args, **kwargs):
T_begin = Time.time ()
result = Func (self, *args, **kwargs)
T_end = Time.time ()
Print ("Time:%f"% (T_end-t_begin))
return result

Return wrapper


Class Test:
def __init__ (self):
Pass

@wrap_performance
def test (self):
Time.sleep (1)


t = Test ()
T.test ()
Code Description:

With the last example, we naturally think that we can count the execution time of the function, this case is born. Implementation is still relatively simple, in the real world we may need a data structure to save the statistics of each method minimum/maximum/average execution time.

Application Scenario:

Used when statistical function execution time is required.

Add:

When we introduce the function parameters, we can reduce the difficulty of the function call by setting the default value of the parameter. And the partial function can also do this. Examples are as follows:

the int () function converts a string to an integer, and the int () function is converted to decimal by default when only the string is passed in:

>>> int (' 12345 ')
12345
However, the Int () function also provides an additional base parameter with a default value of 10. If you pass in the base parameter, you can do an n-ary conversion:

>>> int (' 12345 ', base=8)
5349
>>> int (' 12345 ', 16)
74565
Suppose that to convert a large number of binary strings, passing in int (x, base=2) is very troublesome, so we think that we can define a int2 () function, by default, base=2 is passed in:

def int2 (x, base=2):
return int (x, Base)
This makes it very convenient for us to convert the binaries:

>>> int2 (' 1000000 ')
64
>>> int2 (' 1010101 ')
85
Functools.partial is to help us create a partial function, we do not need to define INT2 (), you can create a new function directly using the following code Int2:

>>> Import Functools
>>> Int2 = functools.partial (int, base=2)
>>> int2 (' 1000000 ')
64
>>> int2 (' 1010101 ')
85
So, a simple summary of Functools.partial's role is to put some of the parameters of a function to the fixed (that is, set the default value), return a new function, call this new function is simpler.

Notice the new Int2 function above, simply to reset the base parameter to the default value of 2, but you can also pass in other values when the function is called:

>>> int2 (' 1000000 ', base=10)
1000000
Finally, when you create a partial function, you can actually receive the 3 parameters of the function object, *args, and **kw when you pass in:

Int2 = functools.partial (int, base=2)
Actually fixed the keyword parameter base for the int () function, which is:

Int2 (' 10010 ')
Equivalent:

KW = {Base:2}
Int (' 10010 ', **kw)
When incoming:

Max2 = Functools.partial (max, 10)
In fact, the 10 is automatically added to the left as part of the *args, which is:

MAX2 (5, 6, 7)
Equivalent:

args = (10, 5, 6, 7)
Max (*args)
The result is 10.

Summary

When the number of arguments for a function is too much to simplify, use functools.partial to create a new function that can hold some of the parameters of the original function, making it simpler to invoke.

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.